📄 umc_h264_dec_bitstream.cpp
字号:
Ipp32u H264Bitstream::Get1Bit(){ Ipp32u w; ippiGetBits1(m_pbs, m_bitOffset, w); return(w);} // H264Bitstream::Get1Bit()// ---------------------------------------------------------------------------// NextBit()// Check next 1 bit. Bitstream state,// pointer and bit offset, will be updated if code equal to 1.// ---------------------------------------------------------------------------bool H264Bitstream::NextBit(){ Ipp32s bp; Ipp32u w; bp = m_bitOffset - 1; if(bp < 0) { w = m_pbs[0] & 1; if(w) { m_pbs++; m_bitOffset = 31; return true; } } else { w = m_pbs[0] >> m_bitOffset; w = w & 1; if(w) { m_bitOffset = bp; return true; } } return false;} // H264Bitstream::SearchBits()// ---------------------------------------------------------------------------// GetCAVLCInfoChroma()//// Calls CAVLC bitstream decoding functions to obtain nonzero coefficients// and related information, returning in passed buffers and passed-by-reference// parameters.// Bitstream pointer and offset are updated by called functions and are// updated on return.// ---------------------------------------------------------------------------Status H264Bitstream::GetCAVLCInfoChroma (Ipp16s &sNumCoeff, Ipp16s *&pPosCoefbuf){ if(ippStsNoErr < ippiDecodeCAVLCChromaDcCoeffs_H264_1u16s(&m_pbs, &m_bitOffset, &sNumCoeff, &pPosCoefbuf, m_tblCoeffToken[3], (const int **) m_tblTotalZerosCR, (const int **) m_tblRunBefore)) { return UMC_BAD_STREAM; } return UMC_OK;}// ---------------------------------------------------------------------------// C_GetCAVLCInfoLuma()//// Calls CAVLC bitstream decoding functions to obtain nonzero coefficients// and related information, returning in passed buffers and passed-by-reference// parameters.// Bitstream pointer and offset are updated by called functions and are// updated on return.// ---------------------------------------------------------------------------Status H264Bitstream::GetCAVLCInfoLuma(Ipp32u uVLCSelect, // N, obtained from num coeffs of above/left blocks Ipp16s uMaxNumCoeff, Ipp16s &sNumCoeff, Ipp16s *&pPosCoefbuf,// buffer to return up to 16 Ipp8u field_flag,Ipp8s hp_4x4_block_index){ Status umcRes = UMC_OK; int *scan_matr; if (hp_4x4_block_index<0) { scan_matr = (Ipp32s*)mp_scan4x4[field_flag]; } else { VM_ASSERT(0); return UMC_UNSUPPORTED; } if(ippStsNoErr < ippiDecodeCAVLCCoeffs_H264_1u16s(&m_pbs, &m_bitOffset, &sNumCoeff, &pPosCoefbuf, uVLCSelect, uMaxNumCoeff, (const int **) m_tblCoeffToken, (const int **) m_tblTotalZeros, (const int **) m_tblRunBefore, scan_matr)) { umcRes = UMC_BAD_STREAM; } return umcRes;}void H264Bitstream::DiscardZeroPadding(){ int rest_bytes = (int)(m_maxBsSize - BytesDecoded()); int zero_byte = 0xff; if(rest_bytes > 4) { if(!GetSCP()) { zero_byte = GetBits(8); while(rest_bytes > 0 && zero_byte == 0) { if(!GetSCP()) zero_byte = GetBits(8); else { ippiUngetNBits(m_pbs,m_bitOffset,24); break; } } if(zero_byte != 0) { ippiUngetNBits(m_pbs,m_bitOffset,8); } } else { ippiUngetNBits(m_pbs,m_bitOffset,24); } }}long H264Bitstream::DecodeCoeffAbsLevelMinus1_CABAC(long ctxIdxOffset, long &numDecodAbsLevelEq1, long &numDecodAbsLevelGt1){ // See subclause 9.3.2.3 of H.264 long uCoff = 14; long ctxIdxInc; long binVal, binIdx; long &syntaxElement = binIdx; // PREFIX BIN(S) STRING DECODING // decoding first bin of prefix bin string binIdx = 0; ctxIdxInc = (numDecodAbsLevelGt1 != 0) ? (0) : (min(4, 1 + numDecodAbsLevelEq1)); binVal = DecodeSingleBin_CABAC(ctxIdxOffset + ctxIdxInc); if (0 == binVal) { numDecodAbsLevelEq1 += 1; return syntaxElement; }; // decoding next bin(s) of prefix bin string // we use Truncated Unary binarization with cMax = uCoff; ctxIdxInc = 5 + min(4, numDecodAbsLevelGt1); do { binIdx += 1; if (syntaxElement >= uCoff) break; binVal = DecodeSingleBin_CABAC(ctxIdxOffset + ctxIdxInc); } while (binVal); // SUFFIX BIN(S) STRING DECODING // See subclause 9.1 of H.264 standard // we use Exp-Golomb code of 0-th order if (binVal) { long leadingZeroBits; long codeNum; leadingZeroBits = 0; // counting leading 1' before 0 while (DecodeBypass_CABAC()) leadingZeroBits += 1; // create codeNum codeNum = 1; while (leadingZeroBits--) codeNum = (codeNum << 1) | DecodeBypass_CABAC(); codeNum -= 1; // update syntax element syntaxElement += codeNum; }; numDecodAbsLevelGt1 += 1; return syntaxElement;} //long H264Bitstream::DecodeCoeffAbsLevelMinus1_CABAC(long ctxIdxOffset, long &numDecodAbsLevelEq1, long &numDecodAbsLevelGt1)long H264Bitstream::ResidualBlock4x4_CABAC(short int *coeffLevel, long ctxBlockCat,bool field_decoding_flag){ // See subclause 7.3.5.3.2 of H.264 standard long numCoeff, maxNumCoeff; long l, lSignificant, ctxIdxOffset, ctxIdxInc; long coeff_abs_level_minus1, coeff_sign_flag; long numDecodAbsLevelEq1, numDecodAbsLevelGt1; long lNonZeroCoeff = 1; // See table 9-32 of H.264 standard switch (ctxBlockCat) { case BLOCK_LUMA_DC_LEVELS: case BLOCK_LUMA_LEVELS: maxNumCoeff = 16; break; case BLOCK_LUMA_AC_LEVELS: case BLOCK_CHROMA_AC_LEVELS: maxNumCoeff = 15; break; case BLOCK_CHROMA_DC_LEVELS: maxNumCoeff = 4; break; default: return 0; }; numCoeff = maxNumCoeff; l = 0; const Ipp32u *ctxIdxBase; if (field_decoding_flag) ctxIdxBase = ctxIdxOffset4x4FieldCoded; else ctxIdxBase = ctxIdxOffset4x4FrameCoded; do { // See subclause 9.3.3.1(.3) of H.264 standard // ctxIdx = ctxIdxOffset + ctxIdxBlockCatOffset(ctxBlockCat) + ctxIndInc ctxIdxInc = l; ctxIdxOffset = ctxIdxBase[SIGNIFICANT_COEFF_FLAG] + ctxIdxBlockCatOffset[SIGNIFICANT_COEFF_FLAG][ctxBlockCat]; lSignificant = DecodeSingleBin_CABAC(ctxIdxOffset+ctxIdxInc); if (lSignificant) { lNonZeroCoeff += 1; coeffLevel[l] = 1; // See subclause 9.3.3.1(.3) of H.264 standard // ctxIdx = ctxIdxOffset + ctxIdxBlockCatOffset(ctxBlockCat) + ctxIndInc ctxIdxInc = l; ctxIdxOffset = ctxIdxBase[LAST_SIGNIFICANT_COEFF_FLAG] + ctxIdxBlockCatOffset[LAST_SIGNIFICANT_COEFF_FLAG][ctxBlockCat]; lSignificant = DecodeSingleBin_CABAC(ctxIdxOffset+ctxIdxInc); if (lSignificant) { // when last_significant_bit occurs we enumerate all coeff-ts // and eluminate one extra lNonZeroCoeff -= 1; numCoeff = l + 1; // set remain coefficients to zero (instead cicle) memset(coeffLevel + numCoeff, 0, (maxNumCoeff - numCoeff) * sizeof(coeffLevel[0])); } } else coeffLevel[l] = 0; l += 1; } while (numCoeff - 1 > l); numDecodAbsLevelEq1 = 0; numDecodAbsLevelGt1 = 0; // calculate last coefficient in block ctxIdxOffset = ctxIdxBase[COEFF_ABS_LEVEL_MINUS1] + ctxIdxBlockCatOffset[COEFF_ABS_LEVEL_MINUS1][ctxBlockCat]; coeff_abs_level_minus1 = DecodeCoeffAbsLevelMinus1_CABAC(ctxIdxOffset, numDecodAbsLevelEq1, numDecodAbsLevelGt1); coeff_sign_flag = DecodeBypass_CABAC(); coeffLevel[numCoeff - 1] = static_cast<short int> ((coeff_abs_level_minus1 + 1) * (1 - 2 * coeff_sign_flag)); for (l = numCoeff - 2; l >= 0; l -= 1) { if (coeffLevel[l]) { // calculate remain coefficient(s) in block ctxIdxOffset = ctxIdxBase[COEFF_ABS_LEVEL_MINUS1] + ctxIdxBlockCatOffset[COEFF_ABS_LEVEL_MINUS1][ctxBlockCat]; coeff_abs_level_minus1 = DecodeCoeffAbsLevelMinus1_CABAC(ctxIdxOffset, numDecodAbsLevelEq1, numDecodAbsLevelGt1); coeff_sign_flag = DecodeBypass_CABAC(); coeffLevel[l] = static_cast<short int> ((coeff_abs_level_minus1 + 1) * (1 - 2 * coeff_sign_flag)); } } return lNonZeroCoeff;//numCoeff;} //long H264Bitstream::ResidualBlock_CABAC(short int *coeffLevel, long ctxBlockCat)static int num1[] = {2, 2, -6, -6};static int num2[] = {1, 1, 1, -7};size_tH264Bitstream::BytesDecoded(){ return static_cast<size_t>((vm_byte*)m_pbs - (vm_byte*)m_pbsBase) + ((31 - m_bitOffset) >> 3);}size_tH264Bitstream::BytesDecodedRoundOff(){ return static_cast<size_t>((vm_byte*)m_pbs - (vm_byte*)m_pbsBase);}void removeSCEBP(Ipp32u* ¤t_data, Ipp32s &offset){ if((offset & 7) == 7) { int a = offset>>3; unsigned char* tmp = ((unsigned char*)current_data) + a; if(tmp[0] == 3) { if(!tmp[num1[a]] && !tmp[num2[a]]) { offset -= 8; current_data += (offset&0x20)>>5; offset&=0x1f; } } }}} // end namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -