📄 umc_h264_segment_decoder_decode_mb_types.cpp
字号:
} // block
} // void H264SegmentDecoder::DecodeIntraTypes4x4_CAVLC(Ipp32u *pMBIntraTypes,
void H264SegmentDecoder::DecodeIntraTypes8x8_CAVLC(IntraType *pMBIntraTypes,
bool bUseConstrainedIntra)
{
Ipp32u uModeAbove[2];
Ipp32u uModeLeft[2];
Ipp32u uPredMode; // predicted mode for current 4x4 block
Ipp32u uBSMode; // mode bits from bitstream
IntraType *pRefIntraTypes;
Ipp32u uLeftIndex; // indexes into mode arrays, dependent on 8x8 block
Ipp32u uAboveIndex;
H264DecoderMacroblockGlobalInfo *gmbinfo=m_gmbinfo->mbs;
Ipp32u predictors=31;//5 lsb bits set
//new version
{
// above, left MB available only if they are INTRA
if ((m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num<0) || ((!IS_INTRA_MBTYPE(gmbinfo[m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num].mbtype) && bUseConstrainedIntra)))
predictors &= (~1);//clear 1-st bit
if ((m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num<0) || ((!IS_INTRA_MBTYPE(gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num].mbtype) && bUseConstrainedIntra)))
predictors &= (~2); //clear 2-nd bit
if ((m_cur_mb.CurrentBlockNeighbours.mbs_left[2].mb_num<0) || ((!IS_INTRA_MBTYPE(gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[2].mb_num].mbtype) && bUseConstrainedIntra)))
predictors &= (~4); //clear 4-th bit
}
// Get modes of blocks above and to the left, substituting 0
// when above or to left is outside this MB slice. Substitute mode 2
// when the adjacent macroblock is not 4x4 INTRA. Add 1 to actual
// modes, so mode range is 1..9.
if (predictors&1)
{
if (gmbinfo[m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num].mbtype == MBTYPE_INTRA)
{
pRefIntraTypes = m_pMBIntraTypes + m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num * NUM_INTRA_TYPE_ELEMENTS;
uModeAbove[0] = pRefIntraTypes[10] + 1;
uModeAbove[1] = pRefIntraTypes[14] + 1;
}
else
{ // MB above in slice but not INTRA, use mode 2 (+1)
uModeAbove[0] = uModeAbove[1] = 2 + 1;
}
}
else
{
uModeAbove[0] = uModeAbove[1] = 0;
}
if (predictors&2)
{
if (gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num].mbtype == MBTYPE_INTRA)
{
pRefIntraTypes = m_pMBIntraTypes + m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num*NUM_INTRA_TYPE_ELEMENTS;
uModeLeft[0] = pRefIntraTypes[NIT2LIN[m_cur_mb.CurrentBlockNeighbours.mbs_left[0].block_num]] + 1;
}
else
{ // MB left in slice but not INTRA, use mode 2 (+1)
uModeLeft[0] = 2+1;
}
}
else
{
uModeLeft[0] = 0;
}
if (predictors&4)
{
if (gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[2].mb_num].mbtype == MBTYPE_INTRA)
{
pRefIntraTypes = m_pMBIntraTypes + m_cur_mb.CurrentBlockNeighbours.mbs_left[2].mb_num*NUM_INTRA_TYPE_ELEMENTS;
uModeLeft[1] = pRefIntraTypes[NIT2LIN[m_cur_mb.CurrentBlockNeighbours.mbs_left[2].block_num]] + 1;
}
else
{ // MB left in slice but not INTRA, use mode 2 (+1)
uModeLeft[1] = 2+1;
}
}
else
{
uModeLeft[1] = 0;
}
uAboveIndex = 0;
uLeftIndex = 0;
// upper left 8x8
// Predicted mode is minimum of the above and left modes, or
// mode 2 if above or left is outside slice, indicated by 0 in
// mode array.
uPredMode = IPP_MIN(uModeLeft[uLeftIndex], uModeAbove[uAboveIndex]);
if (uPredMode)
uPredMode--;
else
uPredMode = 2;
// If next bitstream bit is 1, use predicted mode, else read new mode
if (m_pBitStream->Get1Bit() == 0)
{
// get 3 more bits to determine new mode
uBSMode = m_pBitStream->GetBits(3);
if (uBSMode < uPredMode)
uPredMode = uBSMode;
else
uPredMode = uBSMode + 1;
}
// Save mode
pMBIntraTypes[0] =
pMBIntraTypes[1] =
pMBIntraTypes[2] =
pMBIntraTypes[3] =
(IntraType)uPredMode;
uModeAbove[uAboveIndex] = uPredMode + 1;
// upper right 8x8
uPredMode = IPP_MIN(uPredMode+1, uModeAbove[uAboveIndex+1]);
if (uPredMode)
uPredMode--;
else
uPredMode = 2;
if (m_pBitStream->Get1Bit() == 0)
{
uBSMode = m_pBitStream->GetBits(3);
if (uBSMode < uPredMode)
uPredMode = uBSMode;
else
uPredMode = uBSMode + 1;
}
pMBIntraTypes[4] =
pMBIntraTypes[5] =
pMBIntraTypes[6] =
pMBIntraTypes[7] =
(IntraType)uPredMode;
uModeAbove[uAboveIndex+1] = uPredMode + 1;
uModeLeft[uLeftIndex] = uPredMode + 1;
// lower left 4x4
uPredMode = IPP_MIN(uModeLeft[uLeftIndex+1], uModeAbove[uAboveIndex]);
if (uPredMode)
uPredMode--;
else
uPredMode = 2;
if (m_pBitStream->Get1Bit() == 0)
{
uBSMode = m_pBitStream->GetBits(3);
if (uBSMode < uPredMode)
uPredMode = uBSMode;
else
uPredMode = uBSMode + 1;
}
pMBIntraTypes[8] =
pMBIntraTypes[9] =
pMBIntraTypes[10] =
pMBIntraTypes[11] =
(IntraType)uPredMode;
uModeAbove[uAboveIndex] = uPredMode + 1;
// lower right 4x4 (above and left must always both be in slice)
uPredMode = IPP_MIN(uPredMode+1, uModeAbove[uAboveIndex+1]) - 1;
if (m_pBitStream->Get1Bit() == 0)
{
uBSMode = m_pBitStream->GetBits(3);
if (uBSMode < uPredMode)
uPredMode = uBSMode;
else
uPredMode = uBSMode + 1;
}
pMBIntraTypes[12] =
pMBIntraTypes[13] =
pMBIntraTypes[14] =
pMBIntraTypes[15] =
(IntraType)uPredMode;
uModeAbove [uAboveIndex+1] = uPredMode + 1;
uModeLeft [uLeftIndex+1] = uPredMode + 1;
// copy last IntraTypes to first 4 for reconstruction since they're not used for further prediction
pMBIntraTypes[1] = pMBIntraTypes[4];
pMBIntraTypes[2] = pMBIntraTypes[8];
pMBIntraTypes[3] = pMBIntraTypes[12];
} // void H264SegmentDecoder::DecodeIntraTypes8x8_CAVLC(Ipp32u *pMBIntraTypes,
Ipp32u H264SegmentDecoder::DecodeCBP_CAVLC(Ipp32u color_format)
{
Ipp32u index;
Ipp32u cbp;
index = (Ipp32u) m_pBitStream->GetVLCElement(false);
if (index < 48)
{
if (MBTYPE_INTRA == m_cur_mb.GlobalMacroblockInfo->mbtype)
cbp = dec_cbp_intra[0 != color_format][index];
else
cbp = dec_cbp_inter[0 != color_format][index];
}
else
{
throw h264_exception(UMC_ERR_INVALID_STREAM);
}
return cbp;
} // Ipp32u H264SegmentDecoder::DecodeCBP_CAVLC(Ipp32u color_format)
void H264SegmentDecoder::DecodeEdgeType()
{
Ipp8u edge_type = 0;
Ipp8u edge_type_2t = 0;
Ipp8u edge_type_2b = 0;
Ipp8u special_MBAFF_case =0;
Ipp32s nLeft = m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num;
Ipp32s nTop = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num;
Ipp32s nTopLeft = m_cur_mb.CurrentBlockNeighbours.mb_above_left.mb_num;
Ipp32s nTopRight = m_cur_mb.CurrentBlockNeighbours.mb_above_right.mb_num;
if (m_isMBAFF)
{
Ipp32s currmb_fdf = pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo);
if (m_IsUseConstrainedIntra)
{
Ipp32s mbA_fdf=1;
Ipp32s mbA_is_intra=0;
Ipp32s mbpA_is_intra=0;
if (nLeft >= 0)
{
mbA_fdf = GetMBFieldDecodingFlag(m_gmbinfo->mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A]);
mbA_is_intra = IS_INTRA_MBTYPE(m_gmbinfo->mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A].mbtype);
mbpA_is_intra = IS_INTRA_MBTYPE(m_gmbinfo->mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A+1].mbtype);
}
if (currmb_fdf) //current mb coded as field MB
{
if (!mbA_fdf) //(special case is allowed only in this branch)
{
if (mbA_is_intra && !mbpA_is_intra) special_MBAFF_case = 1;//only 2 top blocks can use left samples
if (!mbA_is_intra && mbpA_is_intra) special_MBAFF_case = 2;//only 2 bottom blocks can use left samples
}
}
switch (special_MBAFF_case)
{
case 1:
if (0 > nTop)
edge_type_2t |= IPPVC_TOP_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTop].mbtype)) edge_type_2t |= IPPVC_TOP_EDGE;
if (0 > nTopLeft)
edge_type_2t |= IPPVC_TOP_LEFT_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopLeft].mbtype)) edge_type_2t |= IPPVC_TOP_LEFT_EDGE;
if (0 > nTopRight)
edge_type_2t |= IPPVC_TOP_RIGHT_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopRight].mbtype)) edge_type_2t |= IPPVC_TOP_RIGHT_EDGE;
edge_type_2b = IPPVC_LEFT_EDGE | IPPVC_TOP_RIGHT_EDGE;
break;
case 2:
edge_type_2t |= IPPVC_LEFT_EDGE;
if (0 > nTop)
edge_type_2t |= IPPVC_TOP_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTop].mbtype)) edge_type_2t |= IPPVC_TOP_EDGE;
if (0 > nTopLeft)
edge_type_2t |= IPPVC_TOP_LEFT_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopLeft].mbtype)) edge_type_2t |= IPPVC_TOP_LEFT_EDGE;
if (0 > nTopRight)
edge_type_2t |= IPPVC_TOP_RIGHT_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopRight].mbtype)) edge_type_2t |= IPPVC_TOP_RIGHT_EDGE;
edge_type_2b = IPPVC_TOP_LEFT_EDGE | IPPVC_TOP_RIGHT_EDGE;
break;
default:
if (0 > nLeft)
edge_type |= IPPVC_LEFT_EDGE;
else
{
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nLeft].mbtype)) edge_type |= IPPVC_LEFT_EDGE;
if (mbA_fdf && !currmb_fdf && (!mbpA_is_intra || !mbA_is_intra)) edge_type |= IPPVC_LEFT_EDGE;
}
if (0 > nTop)
edge_type |= IPPVC_TOP_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTop].mbtype)) edge_type |= IPPVC_TOP_EDGE;
if (0 > nTopLeft)
edge_type |= IPPVC_TOP_LEFT_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopLeft].mbtype)) edge_type |= IPPVC_TOP_LEFT_EDGE;
if (0 > nTopRight)
edge_type |= IPPVC_TOP_RIGHT_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopRight].mbtype)) edge_type |= IPPVC_TOP_RIGHT_EDGE;
break;
}
}
else
{
if (0 > nLeft)
edge_type |= IPPVC_LEFT_EDGE;
if (0 > nTop)
edge_type |= IPPVC_TOP_EDGE;
if (0 > nTopLeft)
edge_type |= IPPVC_TOP_LEFT_EDGE;
if (0 > nTopRight)
edge_type |= IPPVC_TOP_RIGHT_EDGE;
}
if (special_MBAFF_case)
{
m_mbinfo.mbs[m_CurMBAddr].IntraTypes.edge_type = (edge_type_2t << 8) | edge_type_2b;
m_mbinfo.mbs[m_CurMBAddr].IntraTypes.edge_type |= 0x8000;
}
else
{
m_mbinfo.mbs[m_CurMBAddr].IntraTypes.edge_type = edge_type;
}
}
else
{
if (m_IsUseConstrainedIntra)
{
if (0 > nLeft)
edge_type |= IPPVC_LEFT_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nLeft].mbtype)) edge_type |= IPPVC_LEFT_EDGE;
if (0 > nTop)
edge_type |= IPPVC_TOP_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTop].mbtype)) edge_type |= IPPVC_TOP_EDGE;
if (0 > nTopLeft)
edge_type |= IPPVC_TOP_LEFT_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopLeft].mbtype)) edge_type |= IPPVC_TOP_LEFT_EDGE;
if (0 > nTopRight)
edge_type |= IPPVC_TOP_RIGHT_EDGE;
else
if (!IS_INTRA_MBTYPE(m_gmbinfo->mbs[nTopRight].mbtype)) edge_type |= IPPVC_TOP_RIGHT_EDGE;
}
else
{
if (0 > nLeft)
edge_type |= IPPVC_LEFT_EDGE;
if (0 > nTop)
edge_type |= IPPVC_TOP_EDGE;
if (0 > nTopLeft)
edge_type |= IPPVC_TOP_LEFT_EDGE;
if (0 > nTopRight)
edge_type |= IPPVC_TOP_RIGHT_EDGE;
}
m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type = edge_type;
}
} // void H264SegmentDecoder::DecodeEdgeType()
void H264SegmentDecoder::ReconstructEdgeType(Ipp8u &edge_type_2t, Ipp8u &edge_type_2b, Ipp32s &special_MBAFF_case)
{
if (m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type > 0xff)
{
edge_type_2t = (Ipp8u)((m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type >> 8) & 0x7f);
edge_type_2b = (Ipp8u)(m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type & 0xff);
//m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type |= 0x8000;
special_MBAFF_case = (edge_type_2t & IPPVC_LEFT_EDGE) ? 2 : 1;
}
else
{
special_MBAFF_case = 0;
edge_type_2t = (Ipp8u)m_cur_mb.LocalMacroblockInfo->IntraTypes.edge_type;
}
}
} // namespace UMC
#endif // UMC_ENABLE_H264_VIDEO_DECODER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -