📄 umc_h264_dec_decode_mb_cabac.cpp
字号:
ctxBase = ctxIdxOffset4x4FrameCoded; if (m_pCurrentFrame->m_PictureStructureForDec<FRM_STRUCTURE) single_scan = mp_scan4x4[1]; else single_scan = mp_scan4x4[0]; } if (uMBType == MBTYPE_INTRA_16x16) { // new m_cur_mb.LocalMacroblockInfo->cbp4x4 = 0; uBlockBit = 1; start_scan = 1; // skip DC coeff coef_ctr = -1; level = 1; uNumCoeff = 0; top_bit = 1; left_bit = 1; cbp_bit = 1; iMBAbove = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num; iMBLeft = m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num; if (0 <= iMBAbove) { top_bit = m_mbinfo.mbs[iMBAbove].cbp_bits & 1; } if (0 <= iMBLeft) { left_bit = m_mbinfo.mbs[iMBLeft].cbp_bits & 1; } ctxIdxInc = 2 * top_bit + left_bit; cbp_bit = m_pBitStream->DecodeSingleBin_CABAC(ctxBase[CODED_BLOCK_FLAG] + ctxIdxBlockCatOffset[CODED_BLOCK_FLAG][BLOCK_LUMA_DC_LEVELS] + ctxIdxInc); //set bits for current block if (cbp_bit) { m_cur_mb.LocalMacroblockInfo->cbp_bits |= 1; memset(pPosCoefbuf, 0, sizeof(short) * 16); coeff_count = m_pBitStream->ResidualBlock4x4_CABAC(coeff, BLOCK_LUMA_DC_LEVELS, pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo) || m_pCurrentFrame->m_PictureStructureForDec<FRM_STRUCTURE); // just to get inside the loop for (k = 0; (k < 17) && (level != 0); k++) { if (coeff_count > 0) { for (run = 0; coeff[index] == 0; index++, run++); level = coeff[index++]; uNumCoeff++; coef_ctr += run + 1; pos = single_scan[coef_ctr]; // store coeff block position pPosCoefbuf[pos] = (Ipp16s) level; } else { run = level = 0; index=0; if(uNumCoeff) { m_cur_mb.LocalMacroblockInfo->cbp4x4 |= uBlockBit; } } coeff_count--; } pPosCoefbuf += 16; } uBlockBit <<= 1; context = LUMA_16AC_CTX; } else { m_cur_mb.LocalMacroblockInfo->cbp4x4 = 0; uBlockBit = 2; start_scan = 0; // take all coeffs context = LUMA_4x4_CTX; } // luma coefficients for (i = 0; i < 16; i++) { if (cbp & (1 << (i >> 2))) // are there any coeff in current block at all { coef_ctr = start_scan - 1; level = 1; uNumCoeff = 0; bit = 1 + sb_x[i] + 4 * sb_y[i]; top_bit = def_bit; left_bit = def_bit; cbp_bit = 1; if (!sb_y[i]) { iMBAbove = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num; if (0 <= iMBAbove) { top_bit = BIT_CHECK(m_mbinfo.mbs[iMBAbove].cbp_bits, m_cur_mb.CurrentBlockNeighbours.mb_above.block_num + sb_x[i] + 1); // +1 since 0=DC } } else { top_bit = BIT_CHECK(m_cur_mb.LocalMacroblockInfo->cbp_bits, bit - 4); } if (!sb_x[i]) { iMBLeft = m_cur_mb.CurrentBlockNeighbours.mbs_left[sb_y[i]].mb_num; if (0 <= iMBLeft) { left_bit = BIT_CHECK(m_mbinfo.mbs[iMBLeft].cbp_bits, m_cur_mb.CurrentBlockNeighbours.mbs_left[sb_y[i]].block_num + 1); // +1 since 0=DC } } else { left_bit = BIT_CHECK(m_cur_mb.LocalMacroblockInfo->cbp_bits, bit - 1); } ctxIdxInc = 2 * top_bit + left_bit; cbp_bit = (LUMA_16AC_CTX == context) ? (m_pBitStream->DecodeSingleBin_CABAC(ctxBase[CODED_BLOCK_FLAG] + ctxIdxBlockCatOffset[CODED_BLOCK_FLAG][BLOCK_LUMA_AC_LEVELS] + ctxIdxInc)) : (m_pBitStream->DecodeSingleBin_CABAC(ctxBase[CODED_BLOCK_FLAG] + ctxIdxBlockCatOffset[CODED_BLOCK_FLAG][BLOCK_LUMA_LEVELS] + ctxIdxInc)); //set bits for current block if (cbp_bit) { m_cur_mb.LocalMacroblockInfo->cbp_bits |= (1 << bit); memset(pPosCoefbuf, 0, sizeof(short) * 16); coeff_count = m_pBitStream->ResidualBlock4x4_CABAC(coeff, (LUMA_16AC_CTX == context) ? (BLOCK_LUMA_AC_LEVELS) : (BLOCK_LUMA_LEVELS), pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo) || m_pCurrentFrame->m_PictureStructureForDec<FRM_STRUCTURE); for (k = start_scan; (k < 17) && (level!=0); k++) { if (coeff_count > 0) { for (run = 0; coeff[index]==0; index++, run++); level = coeff[index++]; uNumCoeff++; coef_ctr += run+1; pos = single_scan[coef_ctr]; // store coeff block position pPosCoefbuf[pos] = (Ipp16s) level; } else { run = level = 0; index=0; if (uNumCoeff) { m_cur_mb.LocalMacroblockInfo->cbp4x4 |= uBlockBit; } } coeff_count--; } // for pPosCoefbuf += 16; } } uBlockBit <<= 1; } // chroma 2x2 DC coeff if (cbp > 15) { for (i = 0; i < 2; i++) { coef_ctr=-1; level=1; uNumCoeff = 0; bit = 17 + i; top_bit = def_bit; left_bit = def_bit; cbp_bit = 1; // always one for 8x8 mode iMBAbove = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num; if (0 <= iMBAbove) { top_bit = BIT_CHECK(m_mbinfo.mbs[iMBAbove].cbp_bits,bit); } iMBLeft = m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num; if (0 <= iMBLeft) { left_bit = BIT_CHECK(m_mbinfo.mbs[iMBLeft].cbp_bits,bit); } ctxIdxInc = 2 * top_bit + left_bit; cbp_bit = m_pBitStream->DecodeSingleBin_CABAC(ctxBase[CODED_BLOCK_FLAG] + ctxIdxBlockCatOffset[CODED_BLOCK_FLAG][BLOCK_CHROMA_DC_LEVELS] + ctxIdxInc); if (cbp_bit) { m_cur_mb.LocalMacroblockInfo->cbp_bits |= (1 << bit); memset(pPosCoefbuf, 0, sizeof(short) * 4); coeff_count = m_pBitStream->ResidualBlock4x4_CABAC(coeff, BLOCK_CHROMA_DC_LEVELS, pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo) || m_pCurrentFrame->m_PictureStructureForDec<FRM_STRUCTURE); for (k = 0; (k < 5) && (level != 0); k++) { if (coeff_count > 0) { for (run = 0; coeff[index]==0; index++, run++); level = coeff[index++]; coef_ctr += run+1; uNumCoeff++; // Bug: img->cofu has only 4 entries, hence coef_ctr MUST be <4 (which is // caught by the VM_ASSERT(). If it is bigger than 4, it starts patching the // img->predmode pointer, which leads to bugs later on. // // This VM_ASSERT() should be left in the code, because it captures a very likely // bug early when testing in error prone environments (or when testing NAL // functionality). VM_ASSERT(coef_ctr < 4); // store coeff block position pPosCoefbuf[coef_ctr] = (Ipp16s) level; } else { run = level = 0; index=0; if (uNumCoeff) { m_cur_mb.LocalMacroblockInfo->cbp4x4 |= uBlockBit; } } coeff_count--; }//for pPosCoefbuf += 4; } uBlockBit <<= 1; } } else { uBlockBit <<= 2; } // chroma AC coeff, all zero from start_scan if (cbp > 31) { for (j = 0; j < 2; j++)//plane { for (i = 0; i < 4; i++)//block { coef_ctr=0; level=1; uNumCoeff = 0; crsb_y = (i > 1); crsb_x = (i & 1); bit = (j) ? (23 + 2 * crsb_y + crsb_x) : (19 + 2 * crsb_y + crsb_x); top_bit = def_bit; left_bit = def_bit; cbp_bit = 1; //--- get bits from neighbouring blocks --- if (!crsb_y) { iMBAbove = m_cur_mb.CurrentBlockNeighbours.mb_above_chroma[0].mb_num; if (0 <= iMBAbove) { top_bit = BIT_CHECK(m_mbinfo.mbs[iMBAbove].cbp_bits, m_cur_mb.CurrentBlockNeighbours.mb_above_chroma[j].block_num + i + 3); } } else { top_bit = BIT_CHECK(m_cur_mb.LocalMacroblockInfo->cbp_bits, bit - 2); } if (!crsb_x) { iMBLeft = m_cur_mb.CurrentBlockNeighbours.mbs_left_chroma[j][i > 0].mb_num; if (0 <= iMBLeft) { left_bit = BIT_CHECK(m_mbinfo.mbs[iMBLeft].cbp_bits, m_cur_mb.CurrentBlockNeighbours.mbs_left_chroma[j][i > 0].block_num + 3); } } else { left_bit = BIT_CHECK(m_cur_mb.LocalMacroblockInfo->cbp_bits, bit - 1); } ctxIdxInc = 2 * top_bit + left_bit; cbp_bit = m_pBitStream->DecodeSingleBin_CABAC(ctxBase[CODED_BLOCK_FLAG] + ctxIdxBlockCatOffset[CODED_BLOCK_FLAG][BLOCK_CHROMA_AC_LEVELS] + ctxIdxInc); if (cbp_bit) { m_cur_mb.LocalMacroblockInfo->cbp_bits |= (1 << bit); memset(pPosCoefbuf, 0, sizeof(short) * 16); coeff_count = m_pBitStream->ResidualBlock4x4_CABAC(coeff, BLOCK_CHROMA_AC_LEVELS, pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo) || m_pCurrentFrame->m_PictureStructureForDec<FRM_STRUCTURE); for (k = 0; (k < 16) && (level != 0); k++) { if (coeff_count > 0) { for (run = 0; coeff[index]==0; index++, run++); level = coeff[index++]; uNumCoeff++; coef_ctr += run+1; pos = single_scan[coef_ctr]; // store coeff block position pPosCoefbuf[pos] = (Ipp16s) level; } else { run = level = 0; index = 0; if(uNumCoeff) { m_cur_mb.LocalMacroblockInfo->cbp4x4 |= uBlockBit; } } coeff_count--; }//for pPosCoefbuf += 16; } uBlockBit <<= 1; } } } // update buffer position pointer m_pCoeffBlocksWrite = pPosCoefbuf; return ps;} // H264VideoDecoder::DecodeCoefficients4x4_CABAC} // end namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -