📄 blkenc.cpp
字号:
|| blkn >=A_BLOCK1 && pmbmd->m_bACPredictionAlpha) { Int i, j; //do AC prediction if (pmbmd->m_preddir [blkn - 1] == HORIZONTAL) { for (i = 8, j = 8; j < 2 * BLOCK_SIZE - 1; i += 8, j++) { rgiCoefQ [i] -= (blkmPred == NULL) ? 0 : (iQPcurr == iQPpred) ? blkmPred [j] : divroundnearest(blkmPred [j] * iQPpred, iQPcurr); assert (rgiCoefQ [i] >= -iMaxAC && rgiCoefQ [i] <= iMaxAC); } } else if (pmbmd->m_preddir [blkn - 1] == VERTICAL) { //horizontal zigzag scan for (i = 1; i < BLOCK_SIZE; i++) { rgiCoefQ [i] -= (blkmPred == NULL) ? 0 : (iQPcurr == iQPpred) ? blkmPred [i] : divroundnearest(blkmPred [i] * iQPpred, iQPcurr); assert (rgiCoefQ [i] >= -iMaxAC && rgiCoefQ [i] <= iMaxAC); } } else assert (FALSE); } }}Void CVideoObjectEncoder::quantizeTextureInterBlock (PixelI* ppxliCurrQBlock, Int iWidthCurrQ, Int* rgiCoefQ, Int iQP, Bool bAlphaBlock) {// m_pentrencSet->m_pentrencDCT->bitstream()->trace (rgiCoefQ, "BLK_TEXTURE"); m_pfdct->apply (ppxliCurrQBlock, iWidthCurrQ, m_rgiDCTcoef, BLOCK_SIZE); if (m_volmd.fQuantizer == Q_H263) { quantizeInterDCTcoefH263 (rgiCoefQ, 0, iQP); inverseQuantizeDCTcoefH263 (rgiCoefQ, 0, iQP); } else { quantizeInterDCTcoefMPEG (rgiCoefQ, 0, iQP, bAlphaBlock); inverseQuantizeInterDCTcoefMPEG (rgiCoefQ, 0, iQP, bAlphaBlock); } m_pidct->apply (m_rgiDCTcoef, BLOCK_SIZE, ppxliCurrQBlock, iWidthCurrQ);// m_pentrencSet->m_pentrencDCT->bitstream()->trace (ppxliCurrQBlock, "BLK_TEXTURE_Q");}UInt CVideoObjectEncoder::sendIntraDC (const Int* rgiCoefQ, BlockNum blkn){ UInt nBits = 0; UInt nBitsPerPixel = m_volmd.nBits; // NBIT Int iMaxVal = 1<<nBitsPerPixel; // NBIT assert (rgiCoefQ [0] >= -iMaxVal && rgiCoefQ [0] < iMaxVal); Int iAbsDiffIntraDC = abs (rgiCoefQ [0]); Long lSzDiffIntraDC = 0; for (Int i = nBitsPerPixel; i > 0; i--) if (iAbsDiffIntraDC & (1 << (i - 1))) { lSzDiffIntraDC = i; break; } COutBitStream* pobstrmIntraDC; if (blkn == U_BLOCK || blkn == V_BLOCK) { nBits = m_pentrencSet->m_pentrencIntraDCc->encodeSymbol(lSzDiffIntraDC, "IntraDClen"); // huffman encode pobstrmIntraDC = m_pentrencSet->m_pentrencIntraDCc -> bitstream (); } else { nBits = m_pentrencSet->m_pentrencIntraDCy->encodeSymbol(lSzDiffIntraDC, "IntraDClen"); // huffman encode pobstrmIntraDC = m_pentrencSet->m_pentrencIntraDCy -> bitstream (); } if (lSzDiffIntraDC<=8) { // NBIT if (rgiCoefQ [0] > 0) pobstrmIntraDC->putBits ((Char) rgiCoefQ [0], lSzDiffIntraDC, "IntraDC"); //fix length code else if (rgiCoefQ [0] < 0) pobstrmIntraDC->putBits (~iAbsDiffIntraDC, lSzDiffIntraDC, "IntraDC"); //fix length code nBits += lSzDiffIntraDC; } else { // NBIT: MARKER bit inserted after first 8 bits // UInt uiOffset = lSzDiffIntraDC-8; UInt uiValue = iAbsDiffIntraDC; if (rgiCoefQ [0] < 0) { uiValue = ~iAbsDiffIntraDC; }/* uiValue = ( (uiValue>>uiOffset)<<(uiOffset+1) ) + ( 1<<uiOffset ) + ( uiValue&((1<<uiOffset)-1) ); pobstrmIntraDC->putBits (uiValue, lSzDiffIntraDC+1, "IntraDC");*/ pobstrmIntraDC->putBits (uiValue, lSzDiffIntraDC, "IntraDC"); pobstrmIntraDC->putBits (1, 1, "Marker"); nBits += lSzDiffIntraDC+1; } return nBits;}UInt CVideoObjectEncoder::sendTCOEFIntra (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag){ Bool bIsFirstRun = TRUE; Bool bIsLastRun = FALSE; UInt uiCurrRun = 0; UInt uiPrevRun = 0; // Int iCurrLevel = 0; Int iPrevLevel = 0; //UInt uiCoefToStart = 0; UInt numBits = 0; for (Int j = iStart; j < BLOCK_SQUARE_SIZE; j++) { if (rgiCoefQ [rgiZigzag [j]] == 0) // zigzag here uiCurrRun++; // counting zeros else { if (!bIsFirstRun) numBits += putBitsOfTCOEFIntra (uiPrevRun, iPrevLevel, bIsLastRun); uiPrevRun = uiCurrRun; // reset for next run iPrevLevel = rgiCoefQ [rgiZigzag [j]]; uiCurrRun = 0; bIsFirstRun = FALSE; } } assert (uiPrevRun <= (BLOCK_SQUARE_SIZE - 1) - 1); // Some AC must be non-zero; at least for inter bIsLastRun = TRUE; numBits += putBitsOfTCOEFIntra (uiPrevRun, iPrevLevel, bIsLastRun); return numBits;}UInt CVideoObjectEncoder::sendTCOEFInter (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag){ Bool bIsFirstRun = TRUE; Bool bIsLastRun = FALSE; UInt uiCurrRun = 0; UInt uiPrevRun = 0; //Int iCurrLevel = 0; Int iPrevLevel = 0; UInt numBits = 0; for (Int j = iStart; j < BLOCK_SQUARE_SIZE; j++) { if (rgiCoefQ [rgiZigzag [j]] == 0) // zigzag here uiCurrRun++; // counting zeros else { if (!bIsFirstRun) numBits += putBitsOfTCOEFInter (uiPrevRun, iPrevLevel, bIsLastRun); uiPrevRun = uiCurrRun; // reset for next run iPrevLevel = rgiCoefQ [rgiZigzag [j]]; uiCurrRun = 0; bIsFirstRun = FALSE; } } assert (uiPrevRun <= (BLOCK_SQUARE_SIZE - 1)); // Some AC must be non-zero; at least for inter bIsLastRun = TRUE; numBits += putBitsOfTCOEFInter (uiPrevRun, iPrevLevel, bIsLastRun); return numBits;}UInt CVideoObjectEncoder::putBitsOfTCOEFInter (UInt uiRun, Int iLevel, Bool bIsLastRun){ UInt nBits = 0; Long lVLCtableIndex; if (bIsLastRun == FALSE) { lVLCtableIndex = findVLCtableIndexOfNonLastEvent (bIsLastRun, uiRun, abs(iLevel)); if (lVLCtableIndex != NOT_IN_TABLE) { nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF"); // huffman encode m_pentrencSet->m_pentrencDCT->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF"); nBits++; } else nBits += escapeEncode (uiRun, iLevel, bIsLastRun, g_rgiLMAXinter, g_rgiRMAXinter, &CVideoObjectEncoder::findVLCtableIndexOfNonLastEvent); } else { lVLCtableIndex = findVLCtableIndexOfLastEvent (bIsLastRun, uiRun, abs(iLevel)); if (lVLCtableIndex != NOT_IN_TABLE) { nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF"); // huffman encode m_pentrencSet->m_pentrencDCT->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF"); nBits++; } else nBits += escapeEncode (uiRun, iLevel, bIsLastRun, g_rgiLMAXinter, g_rgiRMAXinter, &CVideoObjectEncoder::findVLCtableIndexOfLastEvent); } return nBits;}UInt CVideoObjectEncoder::putBitsOfTCOEFIntra (UInt uiRun, Int iLevel, Bool bIsLastRun){ //fprintf(stderr,"%d %d %d\n", iLevel,uiRun,bIsLastRun); Int nBits = 0; Long lVLCtableIndex; lVLCtableIndex = findVLCtableIndexOfIntra (bIsLastRun, uiRun, abs(iLevel)); if (lVLCtableIndex != NOT_IN_TABLE) { nBits += m_pentrencSet->m_pentrencDCTIntra->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF"); // huffman encode m_pentrencSet->m_pentrencDCTIntra->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF"); nBits++; } else nBits += escapeEncode (uiRun, iLevel, bIsLastRun, g_rgiLMAXintra, g_rgiRMAXintra, &CVideoObjectEncoder::findVLCtableIndexOfIntra); return nBits;}UInt CVideoObjectEncoder::escapeEncode (UInt uiRun, Int iLevel, Bool bIsLastRun, Int* rgiLMAX, Int* rgiRMAX, FIND_TABLE_INDEX findVLCtableIndex){ UInt nBits = 0; nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(TCOEF_ESCAPE, "Esc_TCOEF"); Int iLevelAbs = abs (iLevel); Int iLevelPlus = iLevelAbs - rgiLMAX [(uiRun & 0x0000003F) + (bIsLastRun << 6)]; //hashing the table Int iVLCtableIndex = (this->*findVLCtableIndex) (bIsLastRun, uiRun, abs (iLevelPlus)); if (iVLCtableIndex != NOT_IN_TABLE) { m_pbitstrmOut->putBits (0, 1, "Esc_0"); nBits++; nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(iVLCtableIndex, "Esc_1_Vlc_TCOEF"); // huffman encode m_pbitstrmOut->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF"); nBits++; } else { Int iRunPlus = uiRun - rgiRMAX [(iLevelAbs & 0x0000001F) + (bIsLastRun << 5)]; //RMAX table includes + 1 already iVLCtableIndex = (this->*findVLCtableIndex) (bIsLastRun, (UInt) iRunPlus, iLevelAbs); if (iVLCtableIndex != NOT_IN_TABLE) { m_pbitstrmOut->putBits (2, 2, "Esc_10"); nBits += 2; nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(iVLCtableIndex, "Esc_01_Vlc_TCOEF"); // huffman encode m_pbitstrmOut->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF"); nBits++; } else { m_pbitstrmOut->putBits (3, 2, "Esc_11"); nBits += 2; nBits += fixLengthCode (uiRun, iLevel, bIsLastRun); } } return nBits;}UInt CVideoObjectEncoder::fixLengthCode (UInt uiRun, Int iLevel, Bool bIsLastRun){ UInt nBits = 0; m_pentrencSet->m_pentrencDCT->bitstream()->putBits ((Char) bIsLastRun, 1, "Last_Run_TCOEF"); nBits++; assert (uiRun < BLOCK_SQUARE_SIZE); m_pentrencSet->m_pentrencDCT->bitstream()->putBits (uiRun, NUMBITS_ESC_RUN, "Run_Esc_TCOEF"); nBits+=NUMBITS_ESC_RUN; Int iLevelBits = 12; // 12 bit FLC (= m_volmd.nBits?) Int iMaxAC = (1<<(iLevelBits - 1)) - 1; // NBIT assert (iLevel >= -iMaxAC && iLevel <= iMaxAC && iLevel != 0); if (iLevel < 0) iLevel = (1<<iLevelBits) - abs(iLevel); m_pentrencSet->m_pentrencDCT->bitstream()->putBits (1, 1, "Marker"); m_pentrencSet->m_pentrencDCT->bitstream()->putBits (iLevel, iLevelBits, "Level_Esc_TCOEF"); m_pentrencSet->m_pentrencDCT->bitstream()->putBits (1, 1, "Marker"); nBits += iLevelBits + 2; return nBits;}Int CVideoObjectEncoder::findVLCtableIndexOfNonLastEvent (Bool bIsLastRun, UInt uiRun, UInt uiLevel){ assert (uiRun >= 0); if (uiRun > 26 || (uiLevel > grgIfNotLastNumOfLevelAtRun [uiRun])) return NOT_IN_TABLE; else { UInt uiTableIndex = 0; for (UInt i = 0; i < uiRun; i++) uiTableIndex += grgIfNotLastNumOfLevelAtRun [i]; uiTableIndex += uiLevel; uiTableIndex--; // make it zero-based; see Table H13/H.263 return uiTableIndex; }}Int CVideoObjectEncoder::findVLCtableIndexOfLastEvent (Bool bIsLastRun, UInt uiRun, UInt uiLevel){ assert (uiRun >= 0); if (uiRun > 40 || (uiLevel > grgIfLastNumOfLevelAtRun [uiRun])) return NOT_IN_TABLE; else { UInt uiTableIndex = 0; for (UInt i = 0; i < uiRun; i++) uiTableIndex += grgIfLastNumOfLevelAtRun [i]; uiTableIndex += uiLevel; uiTableIndex += 57; // make it zero-based and return uiTableIndex; //correction of offset; see Table H13/H.263 }}Int CVideoObjectEncoder::findVLCtableIndexOfIntra (Bool bIsLastRun, UInt uiRun, UInt uiLevel){ UInt i; assert (uiRun >= 0); if (uiRun > 20 || uiLevel > 27) return NOT_IN_TABLE; else { //UInt uiTableIndex = 0; for (i = 0; i < TCOEF_ESCAPE; i++) { UInt iHashing = (bIsLastRun << 10) | (uiRun << 5) | uiLevel; if (iHashing == grgiIntraYAVCLHashingTable [i]) return i; } return NOT_IN_TABLE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -