📄 umc_h264_slice_decoding.cpp
字号:
m_DistScaleFactorAFF = 0;
m_DistScaleFactorMVAFF = 0;
} // void H264Slice::Release(void)
bool H264Slice::Init(Ipp32s iConsumerNumber)
{
// release object before initialization
Release();
// initialize threading tools
m_DebTools.Init(iConsumerNumber);
return true;
} // bool H264Slice::Init(Ipp32s iConsumerNumber)
Ipp32s H264Slice::RetrievePicParamSetNumber(void *pSource, size_t nSourceSize)
{
if (!nSourceSize)
return -1;
// reset bit stream
if (false == m_BitStream.Init())
return -1;
m_BitStream.Reset((Ipp8u *) pSource, (Ipp32u) nSourceSize);
Status umcRes = UMC_OK;
try
{
// find slice start code
while ((UMC_OK == umcRes) &&
(0 == m_BitStream.GetSCP()))
{
umcRes = m_BitStream.AdvanceToNextSCP();
}
if (UMC_OK != umcRes)
return -1;
NAL_Unit_Type NALUType;
Ipp8u nal_ref_idc;
umcRes = m_BitStream.GetNALUnitType(NALUType, nal_ref_idc);
if (UMC_OK != umcRes)
return false;
// decode first part of slice header
umcRes = m_BitStream.GetSliceHeaderPart1(&m_SliceHeader);
if (UMC_OK != umcRes)
return -1;
} catch (...)
{
return -1;
}
return m_SliceHeader.pic_parameter_set_id;
}
bool H264Slice::Reset(void *pSource, size_t nSourceSize, Ipp32s iConsumerNumber)
{
Ipp32s iMBInFrame;
Ipp32s iFieldIndex;
// reset bit stream
if (false == m_BitStream.Init())
return false;
m_BitStream.Reset((Ipp8u *) pSource, (Ipp32u) nSourceSize);
// decode slice header
if (nSourceSize && false == DecodeSliceHeader())
return false;
m_iMBWidth = GetSeqParam()->frame_width_in_mbs;
m_iMBHeight = GetSeqParam()->frame_height_in_mbs;
iMBInFrame = (m_iMBWidth * m_iMBHeight) / ((m_SliceHeader.field_pic_flag) ? (2) : (1));
iFieldIndex = (m_SliceHeader.field_pic_flag && m_SliceHeader.bottom_field_flag) ? (1) : (0);
// set slice variables
m_iFirstMB = m_SliceHeader.first_mb_in_slice;
m_iMaxMB = iMBInFrame;
m_iFirstMBFld = m_SliceHeader.first_mb_in_slice + iMBInFrame * iFieldIndex;
m_bUnknownSize = IsSliceGroups();
m_iAvailableMB = iMBInFrame;
if (m_iFirstMB >= m_iAvailableMB)
return false;
// reset all internal variables
m_iCurMBToDec = m_iFirstMB;
m_iCurMBToRec = m_iFirstMB;
m_iCurMBToDeb = m_iFirstMB;
m_bInProcess = false;
m_bDecVacant = 1;
m_bRecVacant = 1;
m_bDebVacant = 1;
m_bFirstDebThreadedCall = true;
m_bError = false;
m_MVsDistortion = 0;
// reallocate internal buffer
if (false == m_bUnknownSize && iConsumerNumber > 1)
{
Ipp32s iMBRowSize = GetMBRowWidth();
Ipp32s iMBRowBuffers;
Ipp32s bit_depth_luma, bit_depth_chroma;
if (m_SliceHeader.is_auxiliary)
{
bit_depth_luma = GetSeqParamEx()->bit_depth_aux;
bit_depth_chroma = 8;
} else {
bit_depth_luma = GetSeqParam()->bit_depth_luma;
bit_depth_chroma = GetSeqParam()->bit_depth_chroma;
}
Ipp32s isU16Mode = (bit_depth_luma > 8 || bit_depth_chroma > 8) ? 2 : 1;
// decide number of buffers
iMBRowBuffers = IPP_MAX(MINIMUM_NUMBER_OF_ROWS, MB_BUFFER_SIZE / iMBRowSize);
iMBRowBuffers = IPP_MIN(MAXIMUM_NUMBER_OF_ROWS, iMBRowBuffers);
m_CoeffsBuffers.Init(iMBRowBuffers, sizeof(Ipp16s) * isU16Mode * (iMBRowSize * COEFFICIENTS_BUFFER_SIZE + DEFAULT_ALIGN_VALUE));
}
m_CoeffsBuffers.Reset();
// reset through-decoding variables
m_nMBSkipCount = 0;
m_nQuantPrev = m_pPicParamSet->pic_init_qp +
m_SliceHeader.slice_qp_delta;
m_prev_dquant = 0;
m_field_index = iFieldIndex;
if (IsSliceGroups())
m_bNeedToCheckMBSliceEdges = true;
else
m_bNeedToCheckMBSliceEdges = (0 == m_SliceHeader.first_mb_in_slice) ? (false) : (true);
// set conditional flags
m_bDecoded = false;
m_bPrevDeblocked = false;
m_bDeblocked = (m_SliceHeader.disable_deblocking_filter_idc == DEBLOCK_FILTER_OFF);
if (m_bDeblocked)
{
m_bDebVacant = 0;
m_iCurMBToDeb = m_iMaxMB;
}
// frame is not associated yet
m_pCurrentFrame = NULL;
return true;
} // bool H264Slice::Reset(void *pSource, size_t nSourceSize, Ipp32s iNumber)
bool H264Slice::ResetLimited(void *pSource, size_t nSourceSize)
{
// reset bit stream
m_BitStream.Reset((Ipp8u *) pSource, (Ipp32u) nSourceSize);
// decode slice header
if (false == DecodeSliceHeader(false))
return false;
return true;
} // bool H264Slice::ResetLimited(void *pSource, size_t nSourceSize)
void H264Slice::SetSliceNumber(Ipp32s iSliceNumber)
{
m_iNumber = iSliceNumber;
} // void H264Slice::SetSliceNumber(Ipp32s iSliceNumber)
AdaptiveMarkingInfo * H264Slice::GetAdaptiveMarkingInfo()
{
return &m_AdaptiveMarkingInfo;
}
bool H264Slice::DecodeSliceHeader(bool bFullInitialization)
{
Status umcRes = UMC_OK;
// Locals for additional slice data to be read into, the data
// was read and saved from the first slice header of the picture,
// is not supposed to change within the picture, so can be
// discarded when read again here.
bool bIsIDRPic = false;
NAL_Unit_Type NALUType;
Ipp8u nal_ref_idc;
Ipp32s iSQUANT;
try
{
memset(&m_SliceHeader, 0, sizeof(m_SliceHeader));
while (UMC_OK == umcRes)
{
// find slice start code
while ((UMC_OK == umcRes) &&
(0 == m_BitStream.GetSCP()))
{
umcRes = m_BitStream.AdvanceToNextSCP();
}
if (UMC_OK != umcRes)
return false;
umcRes = m_BitStream.GetNALUnitType(NALUType, nal_ref_idc);
if (UMC_OK != umcRes)
return false;
if ((NALUType != NAL_UT_SLICE) && (NALUType != NAL_UT_IDR_SLICE) &&
(NALUType != NAL_UT_AUXILIARY))
continue;
m_SliceHeader.nal_unit_type = NALUType;
bIsIDRPic = (NALUType == NAL_UT_IDR_SLICE);
if (NALUType == NAL_UT_AUXILIARY)
{
VM_ASSERT(m_pCurrentFrame);
bIsIDRPic = m_pCurrentFrame->m_bIDRFlag[0]; // DEBUG : temporal fix
NALUType = bIsIDRPic ? NAL_UT_IDR_SLICE : NAL_UT_SLICE;
m_SliceHeader.nal_unit_type = NALUType;
m_SliceHeader.is_auxiliary = true;
}
// decode first part of slice header
umcRes = m_BitStream.GetSliceHeaderPart1(&m_SliceHeader);
if (UMC_OK != umcRes)
return false;
m_CurrentPicParamSet = m_SliceHeader.pic_parameter_set_id;
m_CurrentSeqParamSet = m_pPicParamSet->seq_parameter_set_id;
// decode second part of slice header
umcRes = m_BitStream.GetSliceHeaderPart2(&m_SliceHeader,
m_pPicParamSet,
bIsIDRPic,
m_pSeqParamSet,
nal_ref_idc);
if (UMC_OK != umcRes)
return false;
// when we require only slice header
if (false == bFullInitialization)
return true;
// decode second part of slice header
umcRes = m_BitStream.GetSliceHeaderPart3(&m_SliceHeader,
m_PredWeight[0],
m_PredWeight[1],
&ReorderInfoL0,
&ReorderInfoL1,
&m_AdaptiveMarkingInfo,
m_pPicParamSet,
m_pSeqParamSet,
nal_ref_idc);
if (UMC_OK != umcRes)
return false;
m_iMBWidth = m_pSeqParamSet->frame_width_in_mbs;
m_iMBHeight = m_pSeqParamSet->frame_height_in_mbs;
if (m_bPermanentTurnOffDeblocking)
m_SliceHeader.disable_deblocking_filter_idc = DEBLOCK_FILTER_OFF;
// redundant slice, discard
if (m_SliceHeader.redundant_pic_cnt)
continue;
// Set next MB.
if (m_SliceHeader.first_mb_in_slice >= (Ipp32s) (m_iMBWidth * m_iMBHeight))
{
return false;
}
Ipp32s bit_depth_luma = m_SliceHeader.is_auxiliary ?
GetSeqParamEx()->bit_depth_aux : GetSeqParam()->bit_depth_luma;
iSQUANT = m_pPicParamSet->pic_init_qp +
m_SliceHeader.slice_qp_delta;
if (iSQUANT < QP_MIN - 6*(bit_depth_luma - 8)
|| iSQUANT > QP_MAX)
{
return false;
}
// we sucessfully decoded slice header
break;
}
if ((UMC_OK == umcRes) &&
(m_pPicParamSet->entropy_coding_mode))
{
// reset CABAC engine
m_BitStream.InitializeDecodingEngine_CABAC();
if (INTRASLICE == m_SliceHeader.slice_type)
{
m_BitStream.InitializeContextVariablesIntra_CABAC(m_pPicParamSet->pic_init_qp +
m_SliceHeader.slice_qp_delta);
}
else
{
m_BitStream.InitializeContextVariablesInter_CABAC(m_pPicParamSet->pic_init_qp +
m_SliceHeader.slice_qp_delta,
m_SliceHeader.cabac_init_idc);
}
}
}
catch(const h264_exception & )
{
return false;
}
catch(...)
{
return false;
}
return (UMC_OK == umcRes);
} // bool H264Slice::DecodeSliceHeader(bool bFullInitialization)
bool H264Slice::GetDeblockingCondition(void) const
{
// there is no deblocking
if (DEBLOCK_FILTER_OFF == m_SliceHeader.disable_deblocking_filter_idc)
return false;
// no filtering edges of this slice
if ((DEBLOCK_FILTER_ON_NO_SLICE_EDGES == m_SliceHeader.disable_deblocking_filter_idc) ||
(m_bPrevDeblocked))
{
if (false == IsSliceGroups())
return true;
}
return false;
} // bool H264Slice::GetDeblockingCondition(void)
} // namespace UMC
#endif // UMC_ENABLE_H264_VIDEO_DECODER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -