📄 umc_h264_dec_decode_mb_types_cabac.cpp
字号:
top_c = (cbp & (1 << j)) ? (0) : (1); if (!j) { // get number of left macroblock nLeft = m_cur_mb.CurrentBlockNeighbours.mbs_left[i * 2].mb_num; if (0 <= nLeft) { nBNum = m_cur_mb.CurrentBlockNeighbours.mbs_left[i * 2].block_num; left_c = (m_mbinfo.mbs[nLeft].cbp & (1 << (block4_block8[nBNum])) || m_mbinfo.mbs[nLeft].mbtypeBS==MBTYPE_PCM) ? (0) : (1); } else left_c = 0; } else left_c = (cbp & (1 << (2 * i))) ? (0) : (1); mask = (1 << (2 * i + j)); ctxIdxInc = left_c + 2 * top_c; cbp_bit = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[CODED_BLOCK_PATTERN_LUMA] + ctxIdxInc); if (cbp_bit) cbp += mask; } } if (color_format==1) { // CHROMA part // obtain number of above macroblock nTop = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num; if (0 <= nTop) { top_c = (m_mbinfo.mbs[nTop].cbp > 15 || m_mbinfo.mbs[nTop].mbtypeBS==MBTYPE_PCM) ? (1) : (0); } else top_c = 0; // obtain number of left macroblock nLeft = m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num; if (0 <= nLeft) { left_c = (m_mbinfo.mbs[nLeft].cbp > 15 || m_mbinfo.mbs[nLeft].mbtypeBS==MBTYPE_PCM) ? (1) : (0); } else left_c = 0; ctxIdxInc = left_c + 2 * top_c; cbp_bit = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[CODED_BLOCK_PATTERN_CHROMA] + ctxIdxInc); if (cbp_bit) // set the chroma bits { if (top_c) top_c = ((m_mbinfo.mbs[nTop].cbp >> 4) == 2 || m_mbinfo.mbs[nTop].mbtypeBS==MBTYPE_PCM) ? (1) : (0); if (left_c) left_c = ((m_mbinfo.mbs[nLeft].cbp >> 4) == 2 || m_mbinfo.mbs[nLeft].mbtypeBS==MBTYPE_PCM) ? (1) : (0); ctxIdxInc = left_c + 2 * top_c + 4; cbp_bit = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[CODED_BLOCK_PATTERN_CHROMA] + ctxIdxInc); cbp += (cbp_bit == 1) ? (32) : (16); } } return cbp;} // Ipp32u H264VideoDecoder::DecodeCBP_CABAC()Status H264VideoDecoder::DecodeIntraTypes4x4_CABAC( Ipp32u *pMBIntraTypes, bool bUseConstrainedIntra){ // this variable used only in debug purposes Ipp32u block; // Ipp32u mb_width = m_pCurrentFrame->macroBlockSize().width; //Ipp32s mb_left_offset = -(mb_width*pMB->bottom_mb)-1; //Ipp32s mb_above_offset = -(mb_width*pMB->bottom_mb)-mb_width; // Temp arrays for modes from above and left, initially filled from // outside the MB, then updated with modes within the MB Ipp32u dummyAbove; Ipp32u dummyLeft; Ipp8u *uModeAbove = (Ipp8u*)&dummyAbove; Ipp8u *uModeLeft = (Ipp8u*)&dummyLeft; Ipp8u uPredMode; // predicted mode for current 4x4 block Ipp32u *pRefIntraTypes; Ipp32u uLeftIndex; // indexes into mode arrays, dependent on 8x8 block Ipp32u uAboveIndex; Ipp32s val; H264DecoderMacroblockGlobalInfo *gmbinfo=m_pCurrentFrame->m_mbinfo.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] = (Ipp8u) (pRefIntraTypes[10] + 1); uModeAbove[1] = (Ipp8u) (pRefIntraTypes[11] + 1); uModeAbove[2] = (Ipp8u) (pRefIntraTypes[14] + 1); uModeAbove[3] = (Ipp8u) (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; dummyAbove = 0x03030303; } } else { //uModeAbove[0]=uModeAbove[1]=uModeAbove[2]=uModeAbove[3] = 0; dummyAbove = 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] = (Ipp8u) (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] = (Ipp8u) (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] = (Ipp8u) (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] = (Ipp8u) (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; } // Loop over the 4 8x8 blocks 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 = MIN(uModeLeft[uLeftIndex], uModeAbove[uAboveIndex]); if (uPredMode) uPredMode--; else uPredMode = 2; // use_most_probable_mode // remaining_mode_selector if (0 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[PREV_INTRA4X4_PRED_MODE_FLAG])) { val = 0; val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE])); val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE]) << 1); val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE]) << 2); uPredMode = (Ipp8u) (val + (val >= uPredMode)); } // Save mode pMBIntraTypes[0] = uPredMode; uModeAbove[uAboveIndex] = uPredMode + 1; // upper right 4x4 uPredMode = MIN(uPredMode+1, uModeAbove[uAboveIndex+1]); if (uPredMode) uPredMode--; else uPredMode = 2; if (0 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[PREV_INTRA4X4_PRED_MODE_FLAG])) { val = 0; val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE])); val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE]) << 1); val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE]) << 2); uPredMode = (Ipp8u) (val + (val >= uPredMode)); } pMBIntraTypes[1] = uPredMode; uModeAbove[uAboveIndex+1] = uPredMode + 1; uModeLeft[uLeftIndex] = uPredMode + 1; // lower left 4x4 uPredMode = MIN(uModeLeft[uLeftIndex+1], uModeAbove[uAboveIndex]); if (uPredMode) uPredMode--; else uPredMode = 2; if (0 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[PREV_INTRA4X4_PRED_MODE_FLAG])) { val = 0; val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE])); val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE]) << 1); val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE]) << 2); uPredMode = (Ipp8u) (val + (val >= uPredMode)); } pMBIntraTypes[2] = uPredMode; uModeAbove[uAboveIndex] = uPredMode + 1; // lower right 4x4 (above and left must always both be in slice) uPredMode = MIN(uPredMode+1, uModeAbove[uAboveIndex+1]) - 1; if (0 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[PREV_INTRA4X4_PRED_MODE_FLAG])) { val = 0; val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE])); val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE]) << 1); val |= (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[REM_INTRA4X4_PRED_MODE]) << 2); uPredMode = (Ipp8u) (val + (val >= uPredMode)); } pMBIntraTypes[3] = uPredMode; uModeAbove[uAboveIndex+1] = uPredMode + 1; uModeLeft[uLeftIndex+1] = uPredMode + 1; pMBIntraTypes += 4; } // block return UMC_OK;} // Status H264VideoDecoder::DecodeIntraTypes_CABAC(Ipp32u *pMBIntraTypes,void H264VideoDecoder::DecodeMBSkipAndFDF( Ipp32u *MBSkipFlag, bool bIsBSlice){ // this variable used only in debug purposes int left_c,top_c; left_c = top_c = 0; if ((!pGetMBBottomFlag(m_cur_mb.GlobalMacroblockInfo) || (pGetMBBottomFlag(m_cur_mb.GlobalMacroblockInfo) && m_cur_mb.LocalMacroblockPairInfo->mbtypeBS==MBTYPE_SKIPPED)) && m_CurSliceHeader.MbaffFrameFlag) { //inherit field decoding flag if (m_cur_mb.CurrentMacroblockNeighbours.mb_A>=0) { pSetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,GetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A])); } else if (m_cur_mb.CurrentMacroblockNeighbours.mb_B>=0) { pSetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,GetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_B])); } else { pSetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,0); //probably doesn't needed } pSetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockPairInfo,pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)); } UpdateNeighbouringBlocks(); if(m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num>=0 && m_mbinfo.mbs[m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num].mbtypeBS!=MBTYPE_SKIPPED) left_c = 1; if(m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num>=0 && m_mbinfo.mbs[m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num].mbtypeBS!=MBTYPE_SKIPPED) top_c = 1; long ctxIdxInc = left_c + top_c; long ctxIdx; if (bIsBSlice) ctxIdx=MB_SKIP_FLAG_B; else ctxIdx=MB_SKIP_FLAG_P_SP; if (1 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[ctxIdx] + ctxIdxInc)) { m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_SKIPPED; *MBSkipFlag = 1; m_prev_dquant = 0; m_cur_mb.LocalMacroblockInfo->cbp = 0; } else { m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_FORWARD;//safe value; *MBSkipFlag = 0; if ((!pGetMBBottomFlag(m_cur_mb.GlobalMacroblockInfo) || (pGetMBBottomFlag(m_cur_mb.GlobalMacroblockInfo) && m_cur_mb.LocalMacroblockPairInfo->mbtypeBS==MBTYPE_SKIPPED)) && m_CurSliceHeader.MbaffFrameFlag) { left_c = top_c = 0; if(m_cur_mb.CurrentMacroblockNeighbours.mb_A>=0 && GetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_A]) == 1) left_c = 1; if(m_cur_mb.CurrentMacroblockNeighbours.mb_B>=0 && GetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[m_cur_mb.CurrentMacroblockNeighbours.mb_B]) == 1) top_c = 1; long ctxIdxInc = left_c + top_c; Ipp32u bit = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_FIELD_DECODING_FLAG] + ctxIdxInc); pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,m_cur_mb.GlobalMacroblockPairInfo,bit); } UpdateNeighbouringBlocks(); } return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -