📄 umc_h264_segment_decoder_decode_mb_types.cpp
字号:
if (uCodeNum)
{
*PassFDFDecode = 0;
*MBSkipCount = uCodeNum;
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_SKIPPED;
return;
}
}
else
{
// first MB after run of skipped MBs, no new skip count
// in bitstream to read, clear MBSkipCount to detect next skip run
*MBSkipCount = 0;
}
if (m_pSliceHeader->MbaffFrameFlag)
{
if (*PassFDFDecode==0)
{
Ipp32u bit = m_pBitStream->Get1Bit();
pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,m_cur_mb.GlobalMacroblockPairInfo,bit);
*PassFDFDecode = 1;
}
else
{
*PassFDFDecode = 0;
}
}
else
{
pSetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,0);
*PassFDFDecode = 0;
}
uCodeNum = m_pBitStream->GetVLCElement(false);
if (m_pSliceHeader->slice_type == PREDSLICE)
{
switch (uCodeNum)
{
case 0:
// 16x16
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_FORWARD;
break;
case 1:
// 16x8
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_16x8;
break;
case 2:
// 8x16
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_8x16;
break;
case 3:
case 4:
// 8x8
m_cur_mb.GlobalMacroblockInfo->mbtype = (Ipp8u) ((uCodeNum == 4) ? MBTYPE_INTER_8x8_REF0 : MBTYPE_INTER_8x8);
{
// read subblock types
Ipp32u subblock;
Ipp8u sbtype;
for (subblock=0; subblock<4; subblock++)
{
uCodeNum = m_pBitStream->GetVLCElement(false);
switch (uCodeNum)
{
case 0:
sbtype = SBTYPE_8x8;
break;
case 1:
sbtype = SBTYPE_8x4;
break;
case 2:
sbtype = SBTYPE_4x8;
break;
case 3:
sbtype = SBTYPE_4x4;
break;
default:
sbtype = (Ipp8u) -1;
throw h264_exception(UMC_ERR_INVALID_STREAM);
break;
}
m_cur_mb.GlobalMacroblockInfo->sbtype[subblock] = sbtype;
} // for subblock
} // 8x8 subblocks
break;
case 5:
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
break;
default:
if (uCodeNum < 30)
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
uCodeNum -= 6;
}
else if (uCodeNum == 30)
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
}
else
{
throw h264_exception(UMC_ERR_INVALID_STREAM);
}
break;
}
} // P frame
else if (m_pSliceHeader->slice_type == BPREDSLICE)
{
if (uCodeNum < 23)
{
m_cur_mb.GlobalMacroblockInfo->mbtype = CodeToMBTypeB[uCodeNum];
if (m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_16x8 ||
m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x16)
{
// direction for the two subblocks
m_cur_mb.LocalMacroblockInfo->sbdir[0] = CodeToBDir[(uCodeNum-4)>>1][0];
m_cur_mb.LocalMacroblockInfo->sbdir[1] = CodeToBDir[(uCodeNum-4)>>1][1];
}
if (m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x8 || m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x8_REF0)
{
// read subblock types and prediction direction
Ipp32u subblock;
for (subblock=0; subblock<4; subblock++)
{
uCodeNum = m_pBitStream->GetVLCElement(false);
if (uCodeNum < 13)
{
m_cur_mb.GlobalMacroblockInfo->sbtype[subblock] = CodeToSBTypeAndDir[uCodeNum].type;
m_cur_mb.LocalMacroblockInfo->sbdir[subblock] = CodeToSBTypeAndDir[uCodeNum].dir;
}
else
{
throw h264_exception(UMC_ERR_INVALID_STREAM);
}
} // for subblock
} // 8x8 subblocks
}
else if (uCodeNum == 23)
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
else if (uCodeNum < 48)
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
uCodeNum -= 24;
}
else if (uCodeNum == 48)
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
}
else
{
throw h264_exception(UMC_ERR_INVALID_STREAM);
}
} // B frame
else
{
throw h264_exception(UMC_ERR_INVALID_STREAM);
}
} // not Intra
if (m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTRA_16x16)
{
// 16x16 INTRA, code includes prediction mode and cbp info
pMBIntraTypes[0] =
pMBIntraTypes[1] =
pMBIntraTypes[2] =
pMBIntraTypes[3] = (IntraType)((uCodeNum) & 0x03);
if (uCodeNum > 11)
{
m_cur_mb.LocalMacroblockInfo->cbp = 0x0f;
uCodeNum -= 12;
}
else
m_cur_mb.LocalMacroblockInfo->cbp = 0x00;
uCodeNum <<= 2;
m_cur_mb.LocalMacroblockInfo->cbp = (Ipp8u) (m_cur_mb.LocalMacroblockInfo->cbp | (uCodeNum & 0x30));
} // INTRA_16x16
} // void H264SegmentDecoder::DecodeMacroBlockType(Ipp32u *pMBIntraTypes,
void H264SegmentDecoder::DecodeIntraTypes4x4_CAVLC(IntraType *pMBIntraTypes,
bool bUseConstrainedIntra)
{
Ipp32u block;
// Temp arrays for modes from above and left, initially filled from
// outside the MB, then updated with modes within the MB
Ipp32u uModeAbove[4];
Ipp32u uModeLeft[4];
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[1].mb_num<0) || ((!IS_INTRA_MBTYPE(gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[1].mb_num].mbtype) && bUseConstrainedIntra)))
predictors &= (~4); //clear 3-rd 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 &= (~8); //clear 4-th bit
if ((m_cur_mb.CurrentBlockNeighbours.mbs_left[3].mb_num<0) || ((!IS_INTRA_MBTYPE(gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[3].mb_num].mbtype) && bUseConstrainedIntra)))
predictors &= (~16); //clear 5-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[11] + 1;
uModeAbove[2] = pRefIntraTypes[14] + 1;
uModeAbove[3] = pRefIntraTypes[15] + 1;
}
else
{ // MB above in slice but not INTRA, use mode 2 (+1)
uModeAbove[0] = uModeAbove[1] = uModeAbove[2] = uModeAbove[3] = 2 + 1;
}
}
else
{
uModeAbove[0] = uModeAbove[1] = uModeAbove[2] = uModeAbove[3] = 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[1].mb_num].mbtype == MBTYPE_INTRA)
{
pRefIntraTypes = m_pMBIntraTypes + m_cur_mb.CurrentBlockNeighbours.mbs_left[1].mb_num*NUM_INTRA_TYPE_ELEMENTS;
uModeLeft[1] = pRefIntraTypes[NIT2LIN[m_cur_mb.CurrentBlockNeighbours.mbs_left[1].block_num]] + 1;
}
else
{
// MB left in slice but not INTRA, use mode 2 (+1)
uModeLeft[1] = 2+1;
}
}
else
{
uModeLeft[1] = 0;
}
if (predictors&8)
{
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[2] = 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[2] = 2+1;
}
}
else
{
uModeLeft[2] = 0;
}
if (predictors&16)
{
if (gmbinfo[m_cur_mb.CurrentBlockNeighbours.mbs_left[3].mb_num].mbtype == MBTYPE_INTRA)
{
pRefIntraTypes = m_pMBIntraTypes + m_cur_mb.CurrentBlockNeighbours.mbs_left[3].mb_num*NUM_INTRA_TYPE_ELEMENTS;
uModeLeft[3] = pRefIntraTypes[NIT2LIN[m_cur_mb.CurrentBlockNeighbours.mbs_left[3].block_num]] + 1;
}
else
{
// MB left in slice but not INTRA, use mode 2 (+1)
uModeLeft[3] = 2+1;
}
}
else
{
uModeLeft[3] = 0;
}
for (block=0; block<4; block++)
{
uAboveIndex = (block & 1) * 2; // 0,2,0,2
uLeftIndex = (block & 2); // 0,0,2,2
// upper left 4x4
// 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] = (IntraType)uPredMode;
uModeAbove[uAboveIndex] = uPredMode + 1;
// upper right 4x4
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[1] = (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[2] = (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[3] = (IntraType)uPredMode;
uModeAbove [uAboveIndex+1] = uPredMode + 1;
uModeLeft [uLeftIndex+1] = uPredMode + 1;
pMBIntraTypes += 4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -