📄 blkenc.cpp
字号:
} else { pmbmdCurr->m_preddir [blkn - 1] = HORIZONTAL; if (blkmLeft != NULL) { *pblkmRet = blkmLeft; iQPpred = iQPpredLeft; if (bDecideDCOnly != TRUE) { for (i = 8, j = 8; i < BLOCK_SQUARE_SIZE; i += 8, j++) { Int iDiff = rgiCoefQ [i] - divroundnearest(blkmLeft [j] * iQPpred, iQPcurr); if (iDiff >= -iRange && iDiff <= iRange) //hack to deal with vm deficiency: ac pred out of range; dc pred is not dealt with iSumErr += abs (rgiCoefQ [i]) - abs (iDiff); else return -100000; //arbitrary negative number to turn off ac pred. } } } } return iSumErr;}Void CVideoObjectEncoder::intraPred (Int blkn, const CMBMode* pmbmd, Int* rgiCoefQ, Int iQPcurr, Int iDcScaler, const BlockMemory blkmPred, Int iQPpred){ Int iDefVal; // NBIT: start to calculate default value UInt nBits = m_volmd.nBits; Int iMaxDC = (1<<nBits) - 1; Int iLevelBits = 12; // 12 bit FLC (= m_volmd.nBits?) Int iMaxAC = (1<<(iLevelBits - 1)) - 1; // NBIT 127 iDefVal = 1<<(nBits + 2); //do DC prediction if (blkmPred == NULL)/* NBIT: change 1024 to iDefVal rgiCoefQ [0] -= (1024 + (iDcScaler >> 1)) / iDcScaler;*/ rgiCoefQ [0] -= divroundnearest(iDefVal, iDcScaler); else { rgiCoefQ [0] -= divroundnearest(blkmPred [0], iDcScaler);/* NBIT: change 255 to iMaxVal assert (rgiCoefQ [0] >= -255 && rgiCoefQ [0] <= 255);*/ assert (rgiCoefQ [0] >= -iMaxDC && rgiCoefQ [0] <= iMaxDC); if ((blkn < A_BLOCK1 && pmbmd->m_bACPrediction) || (blkn >=A_BLOCK1 && pmbmd->m_pbACPredictionAlpha[(blkn-7)/4])) { 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); } }}// HHI Schueuer: added const PixelC *rgpxlcBlkShape, Int iBlkShapeWidthVoid CVideoObjectEncoder::quantizeTextureInterBlock (PixelI* ppxliCurrQBlock, Int iWidthCurrQ, Int* rgiCoefQ, Int iQP, Bool bAlphaBlock, const PixelC *rgpxlcBlkShape, Int iBlkShapeWidth, Int iBlk) {// m_pentrencSet->m_pentrencDCT->bitstream()->trace (rgiCoefQ, "BLK_TEXTURE");// HHI Schueuer : rgpxlcBlkShape, iBlkShapeWidth, lx added Int *lx = new Int [iBlkShapeWidth]; m_pfdct->apply (ppxliCurrQBlock, iWidthCurrQ, m_rgiDCTcoef, BLOCK_SIZE, rgpxlcBlkShape, iBlkShapeWidth, lx); // end HHI// RRV insertion if(m_vopmd.RRVmode.iOnOff == 1) { cutoffDCTcoef(); }// ~RRV if (m_volmd.fQuantizer == Q_H263) { quantizeInterDCTcoefH263 (rgiCoefQ, 0, iQP); // HHI Schueuer if (rgpxlcBlkShape && !m_volmd.bSadctDisable) { // assert(pmbmd->m_rgTranspStatus [iBlk] == PARTIAL); // brute force method to clean out mispredictions outside the active region // Int *lx = m_rgiCurrMBCoeffWidth[iBlk]; Int iy, ix; for (iy = 0; iy < BLOCK_SIZE; iy++) { for (ix=lx[iy]; ix<BLOCK_SIZE; ix++) rgiCoefQ[ix + iy * BLOCK_SIZE] = 0; } } // end HHI inverseQuantizeDCTcoefH263 (rgiCoefQ, 0, iQP); } else { quantizeInterDCTcoefMPEG (rgiCoefQ, 0, iQP, bAlphaBlock); // HHI Schueuer if (rgpxlcBlkShape && !m_volmd.bSadctDisable) { // assert(pmbmd->m_rgTranspStatus [iBlk] == PARTIAL); // brute force method to clean out mispredictions outside the active region // Int *lx = m_rgiCurrMBCoeffWidth[iBlk]; Int iy, ix; for (iy = 0; iy < BLOCK_SIZE; iy++) { for (ix=lx[iy]; ix<BLOCK_SIZE; ix++) rgiCoefQ[ix + iy * BLOCK_SIZE] = 0; } } // end HHI inverseQuantizeInterDCTcoefMPEG (rgiCoefQ, 0, iQP, bAlphaBlock, 0); } // m_pidct->apply (m_rgiDCTcoef, BLOCK_SIZE, ppxliCurrQBlock, iWidthCurrQ); // HHI Schueuer : added rgpxlcBlkShape, iBlkShapeWidth, lx m_pidct->apply (m_rgiDCTcoef, BLOCK_SIZE, ppxliCurrQBlock, iWidthCurrQ, rgpxlcBlkShape, iBlkShapeWidth, lx); delete lx; // end HHI// m_pentrencSet->m_pentrencDCT->bitstream()->trace (ppxliCurrQBlock, "BLK_TEXTURE_Q");}UInt CVideoObjectEncoder::sendIntraDC (const Int* rgiCoefQ, Int 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 + -