📄 mbenc.cpp
字号:
{ PixelC* ppxlcCurrMBY = m_ppxlcCurrMBY; PixelC* ppxlcCurrMBU = m_ppxlcCurrMBU; PixelC* ppxlcCurrMBV = m_ppxlcCurrMBV; Int ic; for (ic = 0; ic < BLOCK_SIZE; ic++) { memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*sizeof(PixelC)); memcpy (ppxlcCurrMBU, ppxlcCurrU, BLOCK_SIZE*sizeof(PixelC)); memcpy (ppxlcCurrMBV, ppxlcCurrV, BLOCK_SIZE*sizeof(PixelC)); ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += iWidthY; ppxlcCurrMBU += BLOCK_SIZE; ppxlcCurrU += iWidthUV; ppxlcCurrMBV += BLOCK_SIZE; ppxlcCurrV += iWidthUV; memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*sizeof(PixelC)); // two rows for Y ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += iWidthY; }}// compute error signalVoid CVideoObjectEncoder::computeTextureError (){ CoordI ix; // Y for (ix = 0; ix < MB_SQUARE_SIZE; ix++) m_ppxliErrorMBY [ix] = m_ppxlcCurrMBY [ix] - m_ppxlcPredMBY [ix]; // UV for (ix = 0; ix < BLOCK_SQUARE_SIZE; ix++) { m_ppxliErrorMBU [ix] = m_ppxlcCurrMBU [ix] - m_ppxlcPredMBU [ix]; m_ppxliErrorMBV [ix] = m_ppxlcCurrMBV [ix] - m_ppxlcPredMBV [ix]; } // Alpha if(m_volmd.fAUsage==EIGHT_BIT) for (ix = 0; ix < MB_SQUARE_SIZE; ix++) m_ppxliErrorMBA [ix] = m_ppxlcCurrMBA [ix] - m_ppxlcPredMBA [ix];}Void CVideoObjectEncoder::computeTextureErrorWithShape (){ CoordI ix; // Y for (ix = 0; ix < MB_SQUARE_SIZE; ix++) { if (m_ppxlcCurrMBBY [ix] == transpValue) m_ppxliErrorMBY [ix] = 0; // zero padding else m_ppxliErrorMBY [ix] = m_ppxlcCurrMBY [ix] - m_ppxlcPredMBY [ix]; } // UV for (ix = 0; ix < BLOCK_SQUARE_SIZE; ix++) { if (m_ppxlcCurrMBBUV [ix] == transpValue) m_ppxliErrorMBU [ix] = m_ppxliErrorMBV [ix] = 0; else { m_ppxliErrorMBU [ix] = m_ppxlcCurrMBU [ix] - m_ppxlcPredMBU [ix]; m_ppxliErrorMBV [ix] = m_ppxlcCurrMBV [ix] - m_ppxlcPredMBV [ix]; } } if(m_volmd.fAUsage==EIGHT_BIT) for (ix = 0; ix < MB_SQUARE_SIZE; ix++) { if (m_ppxlcCurrMBBY [ix] == transpValue) m_ppxliErrorMBA [ix] = 0; // zero padding else m_ppxliErrorMBA [ix] = m_ppxlcCurrMBA [ix] - m_ppxlcPredMBA [ix]; }}Void CVideoObjectEncoder::computeAlphaError (){ CoordI ix; for (ix = 0; ix < MB_SQUARE_SIZE; ix++) { if (m_ppxlcCurrMBBY [ix] == transpValue) m_ppxliErrorMBA [ix] = 0; // zero padding else m_ppxliErrorMBA [ix] = m_ppxlcCurrMBA [ix] - m_ppxlcPredMBA [ix]; }}Void CVideoObjectEncoder::quantizeTextureIntraMB ( Int imbX, Int imbY, CMBMode* pmbmd, PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV, PixelC* ppxlcCurrQMBA){ assert (pmbmd != NULL); assert (pmbmd -> m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ); assert (pmbmd -> m_rgTranspStatus [0] != ALL); Int iQP = pmbmd->m_stepSize;#ifdef __TRACE_AND_STATS_ m_statsMB.nQMB++; m_statsMB.nQp += iQP;#endif // __TRACE_AND_STATS_ Int iDcScalerY, iDcScalerC, iDcScalerA = 0; if (iQP <= 4) { iDcScalerY = 8; iDcScalerC = 8; } else if (iQP >= 5 && iQP <= 8) { iDcScalerY = 2 * iQP; iDcScalerC = (iQP + 13) / 2; } else if (iQP >= 9 && iQP <= 24) { iDcScalerY = iQP + 8; iDcScalerC = (iQP + 13) / 2; } else { iDcScalerY = 2 * iQP - 16; iDcScalerC = iQP - 6; } Int iQPA = 0; pmbmd->m_CODAlpha = ALPHA_CODED; if(m_volmd.fAUsage == EIGHT_BIT) { if (pmbmd -> m_stepSizeAlpha < 1) pmbmd -> m_stepSizeAlpha = 1; iQPA = pmbmd->m_stepSizeAlpha; if (iQPA <= 4) iDcScalerA = 8; else if (iQPA >= 5 && iQPA <= 8) iDcScalerA = 2 * iQPA; else if (iQPA >= 9 && iQPA <= 24) iDcScalerA = iQPA + 8; else iDcScalerA = 2 * iQPA - 16; if(pmbmd->m_rgTranspStatus [0] == NONE) { // need to test gray alpha vals // CODA = 1 if all==255, can't use TranspStatus, has to be 255 Int i; Int iThresh = 256 - iQPA; pmbmd->m_CODAlpha = ALPHA_ALL255; for(i = 0; i<MB_SQUARE_SIZE; i++) if(m_ppxlcCurrMBA[i]<=iThresh) { pmbmd->m_CODAlpha = ALPHA_CODED; break; } if(pmbmd->m_CODAlpha == ALPHA_ALL255) { pxlcmemset(m_ppxlcCurrMBA, 255, MB_SQUARE_SIZE); PixelC *ppxlc = ppxlcCurrQMBA; for(i = 0; i<MB_SIZE; i++, ppxlc += m_iFrameWidthY) pxlcmemset(ppxlc, 255, MB_SIZE); } } } Int iCoefToStart; assert (pmbmd -> m_stepSizeDelayed > 0); if (pmbmd -> m_stepSizeDelayed >= grgiDCSwitchingThreshold [m_vopmd.iIntraDcSwitchThr]) { pmbmd->m_bCodeDcAsAc = TRUE; //pmbmd->m_bCodeDcAsAcAlpha = TRUE; // decision should really be based on alpha quantiser iCoefToStart = 0; } else { pmbmd->m_bCodeDcAsAc = FALSE; //pmbmd->m_bCodeDcAsAcAlpha = FALSE; iCoefToStart = 1; } pmbmd->m_bCodeDcAsAcAlpha = FALSE; //for intra pred MacroBlockMemory* pmbmLeft = NULL; MacroBlockMemory* pmbmTop = NULL; MacroBlockMemory* pmbmLeftTop = NULL; CMBMode* pmbmdLeft = NULL; CMBMode* pmbmdTop = NULL; CMBMode* pmbmdLeftTop = NULL; Int iMBnum = imbY * m_iNumMBX + imbX; if (!bVPNoTop(iMBnum)) { pmbmTop = m_rgpmbmAbove [imbX]; pmbmdTop = pmbmd - m_iNumMBX; } if (!bVPNoLeft(iMBnum, imbX)) { pmbmLeft = m_rgpmbmCurr [imbX - 1]; pmbmdLeft = pmbmd - 1; } if (!bVPNoLeftTop(iMBnum, imbX)) { pmbmLeftTop = m_rgpmbmAbove [imbX - 1]; pmbmdLeftTop = pmbmd - m_iNumMBX - 1; }// INTERLACE if((pmbmd->m_rgTranspStatus [0] == NONE)&&(m_vopmd.bInterlace == TRUE) ) { pmbmd->m_bFieldDCT = FrameFieldDCTDecideC(m_ppxlcCurrMBY); m_statsMB.nFieldDCTMB += (Int) pmbmd->m_bFieldDCT; } else pmbmd->m_bFieldDCT = 0; pmbmd->m_bSkip = FALSE; // for direct mode reference // ~INTERLACE PixelC* rgchBlkDst = NULL; PixelC* rgchBlkSrc = NULL; Int iWidthDst, iWidthSrc; Int iDcScaler; Int* rgiCoefQ; Int iSumErr = 0; //sum of error to determine intra ac prediction Int iBlk; Int iBlkEnd; if(m_volmd.fAUsage == EIGHT_BIT) iBlkEnd = A_BLOCK4; else iBlkEnd = V_BLOCK; for (iBlk = (Int) Y_BLOCK1; iBlk <= iBlkEnd; iBlk++) { // + 1 is because of the indexing if (iBlk < (Int) U_BLOCK || iBlk > (Int) V_BLOCK) { if(iBlk==A_BLOCK1) iSumErr = 0; // start again for alpha if (pmbmd -> m_rgTranspStatus [iBlk % 6] == ALL) // %6 hack!! continue; switch (iBlk) { case (Y_BLOCK1): rgchBlkDst = ppxlcCurrQMBY; rgchBlkSrc = m_ppxlcCurrMBY; break; case (Y_BLOCK2): rgchBlkDst = ppxlcCurrQMBY + BLOCK_SIZE; rgchBlkSrc = m_ppxlcCurrMBY + BLOCK_SIZE; break; case (Y_BLOCK3): rgchBlkDst = ppxlcCurrQMBY + m_iFrameWidthYxBlkSize; rgchBlkSrc = m_ppxlcCurrMBY + MB_SIZE * BLOCK_SIZE; break; case (Y_BLOCK4): rgchBlkDst = ppxlcCurrQMBY + m_iFrameWidthYxBlkSize + BLOCK_SIZE; rgchBlkSrc = m_ppxlcCurrMBY + MB_SIZE * BLOCK_SIZE + BLOCK_SIZE; break; case (A_BLOCK1): rgchBlkDst = ppxlcCurrQMBA; rgchBlkSrc = m_ppxlcCurrMBA; break; case (A_BLOCK2): rgchBlkDst = ppxlcCurrQMBA + BLOCK_SIZE; rgchBlkSrc = m_ppxlcCurrMBA + BLOCK_SIZE; break; case (A_BLOCK3): rgchBlkDst = ppxlcCurrQMBA + m_iFrameWidthYxBlkSize; rgchBlkSrc = m_ppxlcCurrMBA + MB_SIZE * BLOCK_SIZE; break; case (A_BLOCK4): rgchBlkDst = ppxlcCurrQMBA + m_iFrameWidthYxBlkSize + BLOCK_SIZE; rgchBlkSrc = m_ppxlcCurrMBA + MB_SIZE * BLOCK_SIZE + BLOCK_SIZE; break; } iWidthDst = m_iFrameWidthY; iWidthSrc = MB_SIZE; if(iBlk<=V_BLOCK) iDcScaler = iDcScalerY; //m_rgiDcScalerY [iQP]; else iDcScaler = iDcScalerA; } else { iWidthDst = m_iFrameWidthUV; iWidthSrc = BLOCK_SIZE; rgchBlkDst = (iBlk == U_BLOCK) ? ppxlcCurrQMBU: ppxlcCurrQMBV; rgchBlkSrc = (iBlk == U_BLOCK) ? m_ppxlcCurrMBU: m_ppxlcCurrMBV; iDcScaler = iDcScalerC; //m_rgiDcScalerC [iQP]; } if (m_volmd.nBits<=8) { // NBIT: not always valid when nBits>8 assert(iDcScaler > 0 && iDcScaler < 128); } rgiCoefQ = m_rgpiCoefQ [iBlk - 1]; iSumErr += quantizeIntraBlockTexture ( rgchBlkSrc, iWidthSrc, rgchBlkDst, iWidthDst, rgiCoefQ, (iBlk<=V_BLOCK ? iQP : iQPA), iDcScaler, iBlk, //from here til last pmbmLeft, pmbmTop, pmbmLeftTop, m_rgpmbmCurr [imbX], pmbmdLeft, pmbmdTop, pmbmdLeftTop, pmbmd ); //all for intra-pred if(iBlk>=A_BLOCK1) pmbmd->m_bACPredictionAlpha = (pmbmd->m_CODAlpha == ALPHA_CODED && iSumErr >= 0); else pmbmd->m_bACPrediction =(iSumErr >= 0); /*BBM// Added for Boundary by Hyundai(1998-5-9) if (m_vopmd.bInterlace && pmbmd->m_bMerged [0]) { Int iDstBlk = 0; switch (iBlk) { case (Y_BLOCK1): if (pmbmd->m_bMerged [1]) iDstBlk = (Int) Y_BLOCK2; else if (pmbmd->m_bMerged [3]) iDstBlk = (Int) Y_BLOCK3; else if (pmbmd->m_bMerged [5]) iDstBlk = (Int) Y_BLOCK4; break; case (Y_BLOCK2): if (pmbmd->m_bMerged [4]) iDstBlk = (Int) Y_BLOCK4; else if (pmbmd->m_bMerged [6]) iDstBlk = (Int) Y_BLOCK3; break; case (Y_BLOCK3): if (pmbmd->m_bMerged [2]) iDstBlk = (Int) Y_BLOCK4; break; case (A_BLOCK1): if (pmbmd->m_bMerged [1]) iDstBlk = (Int) A_BLOCK2; else if (pmbmd->m_bMerged [3]) iDstBlk = (Int) A_BLOCK3; else if (pmbmd->m_bMerged [5]) iDstBlk = (Int) A_BLOCK4; break; case (A_BLOCK2): if (pmbmd->m_bMerged [4]) iDstBlk = (Int) A_BLOCK4; else if (pmbmd->m_bMerged [6]) iDstBlk = (Int) A_BLOCK3; break; case (A_BLOCK3): if (pmbmd->m_bMerged [2]) iDstBlk = (Int) A_BLOCK4; break; } if (iDstBlk) { MacroBlockMemory* pmbmCurr = m_rgpmbmCurr [imbX]; pmbmCurr->rgblkm [iDstBlk-1][0] = pmbmCurr->rgblkm [iBlk-1][0]; for (UInt x = 1; x < (BLOCK_SIZE<<1)-1; x++) pmbmCurr->rgblkm [iDstBlk-1][x] = 0; } } // End of Hyundai(1998-5-9)*/ }// INTERLACE if ((pmbmd->m_rgTranspStatus [0] == NONE) && (m_vopmd.bInterlace == TRUE) && (pmbmd->m_bFieldDCT == TRUE)) fieldDCTtoFrameC(ppxlcCurrQMBY);// ~INTERLACE for (iBlk = (UInt) Y_BLOCK1; iBlk <= iBlkEnd; iBlk++) { // + 1 is because of the indexing if (pmbmd->m_rgTranspStatus [iBlk % 6] == ALL) { // hack %6 ok if [6]==[0] pmbmd->setCodedBlockPattern ((BlockNum) iBlk, FALSE); continue; } rgiCoefQ = m_rgpiCoefQ [iBlk - 1]; if (iBlk < (Int) U_BLOCK) iDcScaler = iDcScalerY; //m_rgiDcScalerY [iQP]; else if(iBlk < (Int) A_BLOCK1) iDcScaler = iDcScalerC; //m_rgiDcScalerC [iQP]; else iDcScaler = iDcScalerA; intraPred ((BlockNum) iBlk, pmbmd, rgiCoefQ, (iBlk<=V_BLOCK ? iQP : iQPA), iDcScaler, m_rgblkmCurrMB [iBlk - 1], m_rgiQPpred [iBlk - 1]); Bool bCoded = FALSE; UInt i; if(iBlk >=(Int) A_BLOCK1) iCoefToStart = pmbmd->m_bCodeDcAsAcAlpha==TRUE ? 0 : 1; for (i = iCoefToStart; i < BLOCK_SQUARE_SIZE; i++) { if (rgiCoefQ [i] != 0) { bCoded = TRUE; break; } } pmbmd->setCodedBlockPattern ((BlockNum) iBlk, bCoded); }}Void CVideoObjectEncoder::quantizeTextureInterMB (CMBMode* pmbmd, const CMotionVector* pmv, PixelC *ppxlcCurrQMBA, Bool bSkip) //bSkip: tested mv is zero{ assert (pmbmd != NULL); assert (pmbmd -> m_dctMd == INTER || pmbmd -> m_dctMd == INTERQ); assert (pmbmd->m_rgTranspStatus [0] != ALL); Int iQuantMax = (1<<m_volmd.uiQuantPrecision) - 1; if (pmbmd -> m_stepSize < 1) pmbmd -> m_stepSize = 1; else if (pmbmd -> m_stepSize > iQuantMax) pmbmd -> m_stepSize = iQuantMax; Int iQP = pmbmd->m_stepSize;#ifdef __TRACE_AND_STATS_ m_statsMB.nQMB++; m_statsMB.nQp += iQP;#endif // __TRACE_AND_STATS_// INTERLACE if ((pmbmd->m_rgTranspStatus [0] == NONE) && (m_vopmd.bInterlace == TRUE)) { pmbmd->m_bFieldDCT = FrameFieldDCTDecideI(m_ppxliErrorMBY); m_statsMB.nFieldDCTMB += (Int) pmbmd->m_bFieldDCT; } else pmbmd->m_bFieldDCT = 0; Bool bMBCoded = FALSE;// ~INTERLACE Int iQPA = 0; pmbmd->m_CODAlpha = ALPHA_CODED; Int iBlkEnd = V_BLOCK; if(m_volmd.fAUsage == EIGHT_BIT) { iBlkEnd = A_BLOCK4; if (pmbmd -> m_stepSizeAlpha < 1) pmbmd -> m_stepSizeAlpha = 1; iQPA = pmbmd->m_stepSizeAlpha; Int i, iThresh = 256 - iQPA; pmbmd->m_CODAlpha = ALPHA_ALL255; for(i = 0; i<MB_SQUARE_SIZE; i++) if(m_ppxlcCurrMBA[i] <= iThresh) { pmbmd->m_CODAlpha = ALPHA_CODED; break; } }// Bool bSkip = pmbmd->m_bhas4MVForward ? (bSkipAllowed && pmv [1].isZero () && pmv [2].isZero () && pmv [3].isZero () && pmv [4].isZero ())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -