📄 shpenc.cpp
字号:
Int iSrc = rgiSubBlkIndxSrc [iSubBlk]; Int iDst = rgiSubBlkIndxDst [iSubBlk]; for (CoordI iY = 0; iY < 4; iY++) { for (CoordI iX = 0; iX < 4; iX++) { iError += abs (rgppxlcSrc [iSrc] - rgppxlcDst [iDst]); iSrc++; iDst++; } if (iError > m_volmd.iBinaryAlphaTH) return TRUE; iSrc += iSizeSrc - 4; iDst += iSizeDst - 4; } } return FALSE;}UInt CVideoObjectEncoder::encodeCAEIntra (ShapeMode shpmd, CAEScanDirection shpdir){ assert (shpmd == INTRA_CAE);// m_pbitstrmOut->trace (m_rgiCurrShp, TOTAL_BAB_SQUARE_SIZE, "MB_BAB"); UInt nBits = 0; nBits += codeCrAndSt (shpdir, m_iInverseCR); //the real arithmatic encoding StartArCoder (m_parcodec); if (shpdir == HORIZONTAL) { const PixelC* ppxlcSrcRow = m_rgpxlcCaeSymbol + m_iWidthCurrBAB * BAB_BORDER + BAB_BORDER; for (Int iRow = BAB_BORDER; iRow < m_iWidthCurrBAB - BAB_BORDER; iRow++) { const PixelC* ppxlcSrc = ppxlcSrcRow; for (Int iCol = BAB_BORDER; iCol < m_iWidthCurrBAB - BAB_BORDER; iCol++) { Int iContext = contextIntra (ppxlcSrc);#ifdef __TRACE_AND_STATS_ // m_pbitstrmOut->trace (iContext, "MB_CAE_Context");#endif // __TRACE_AND_STATS_ ArCodeSymbol ((*ppxlcSrc == MPEG4_OPAQUE), gCAEintraProb [iContext], m_parcodec, m_pbitstrmShapeMBOut); ppxlcSrc++; } ppxlcSrcRow += m_iWidthCurrBAB; } } else { const PixelC* ppxlcSrcCol = m_rgpxlcCaeSymbol + m_iWidthCurrBAB * BAB_BORDER + BAB_BORDER; for (Int iCol = BAB_BORDER; iCol < m_iWidthCurrBAB - BAB_BORDER; iCol++) { const PixelC* ppxlcSrc = ppxlcSrcCol; for (Int iRow = BAB_BORDER; iRow < m_iWidthCurrBAB - BAB_BORDER; iRow++) { Int iContext = contextIntraTranspose (ppxlcSrc);#ifdef __TRACE_AND_STATS_ //m_pbitstrmOut->trace (iContext, "MB_CAE_Context");#endif // __TRACE_AND_STATS_ ArCodeSymbol ((*ppxlcSrc == MPEG4_OPAQUE), gCAEintraProb [iContext], m_parcodec, m_pbitstrmShapeMBOut); ppxlcSrc += m_iWidthCurrBAB ; } ppxlcSrcCol++; } } StopArCoder (m_parcodec, m_pbitstrmShapeMBOut); nBits += m_parcodec->nBits; return nBits;}UInt CVideoObjectEncoder::encodeCAEInter (ShapeMode shpmd, CAEScanDirection shpdir){ assert (shpmd == INTER_CAE_MVDNZ || shpmd == INTER_CAE_MVDZ); // m_pbitstrmOut->trace (m_rgiCurrShp, TOTAL_BAB_SQUARE_SIZE, "MB_BAB"); UInt nBits = 0; nBits += codeCrAndSt (shpdir, m_iInverseCR); const PixelC *ppxlcPredBAB = m_puciPredBAB->pixels(); Int iSizeMB = m_iWidthCurrBAB-BAB_BORDER*2; Int iSizePredBAB = iSizeMB+MC_BAB_BORDER*2; if(m_iInverseCR==2) { downSampleShapeMCPred(ppxlcPredBAB,m_ppxlcPredBABDown2,2); ppxlcPredBAB = m_ppxlcPredBABDown2; } else if(m_iInverseCR==4) { downSampleShapeMCPred(ppxlcPredBAB,m_ppxlcPredBABDown4,4); ppxlcPredBAB = m_ppxlcPredBABDown4; } //the real arithmatic encoding StartArCoder (m_parcodec); if (shpdir == HORIZONTAL) { const PixelC* ppxlcSrcRow = m_rgpxlcCaeSymbol + m_iWidthCurrBAB * BAB_BORDER + BAB_BORDER; const PixelC* ppxlcPredRow = ppxlcPredBAB + iSizePredBAB * MC_BAB_BORDER + MC_BAB_BORDER; for (Int iRow = 0; iRow < iSizeMB; iRow++) { const PixelC* ppxlcSrc = ppxlcSrcRow; const PixelC* ppxlcPred = ppxlcPredRow; for (Int iCol = 0; iCol < iSizeMB; iCol++) { Int iContext = contextInter (ppxlcSrc, ppxlcPred);#ifdef __TRACE_AND_STATS_ //m_pbitstrmOut->trace (iContext, "MB_CAE_Context");#endif // __TRACE_AND_STATS_ ArCodeSymbol ((*ppxlcSrc == MPEG4_OPAQUE), gCAEinterProb [iContext], m_parcodec, m_pbitstrmShapeMBOut); ppxlcSrc++; ppxlcPred++; } ppxlcSrcRow += m_iWidthCurrBAB; ppxlcPredRow += iSizePredBAB; } } else { const PixelC* ppxlcSrcCol = m_rgpxlcCaeSymbol + m_iWidthCurrBAB * BAB_BORDER + BAB_BORDER; const PixelC* ppxlcPredCol = ppxlcPredBAB + iSizePredBAB * MC_BAB_BORDER + MC_BAB_BORDER; for (Int iCol = 0; iCol < iSizeMB; iCol++) { const PixelC* ppxlcSrc = ppxlcSrcCol; const PixelC* ppxlcPred = ppxlcPredCol; for (Int iRow = 0; iRow < iSizeMB; iRow++) { Int iContext = contextInterTranspose (ppxlcSrc, ppxlcPred);#ifdef __TRACE_AND_STATS_ //m_pbitstrmOut->trace (iContext, "MB_CAE_Context");#endif // __TRACE_AND_STATS_ ArCodeSymbol ((*ppxlcSrc == MPEG4_OPAQUE), gCAEinterProb [iContext], m_parcodec, m_pbitstrmShapeMBOut); ppxlcSrc += m_iWidthCurrBAB; ppxlcPred += iSizePredBAB; } ppxlcSrcCol++; ppxlcPredCol++; } } StopArCoder (m_parcodec, m_pbitstrmShapeMBOut); nBits += m_parcodec->nBits; return nBits;}UInt CVideoObjectEncoder::encodeMVDS (CMotionVector mvBYD){ assert (!mvBYD.isZero()); m_pentrencSet->m_pentrencShapeMV1->attachStream(*m_pbitstrmShapeMBOut); m_pentrencSet->m_pentrencShapeMV2->attachStream(*m_pbitstrmShapeMBOut); UInt nBits = 0; nBits += m_pentrencSet->m_pentrencShapeMV1->encodeSymbol (abs (mvBYD.iMVX), "MB_SHP_MVDX"); if (mvBYD.iMVX != 0) { m_pbitstrmShapeMBOut->putBits (signOf(mvBYD.iMVX), (UInt) 1, "MB_SHP_MVDX_Sign"); nBits++; nBits += m_pentrencSet->m_pentrencShapeMV1->encodeSymbol (abs (mvBYD.iMVY), "MB_SHP_MVDY"); } else nBits += m_pentrencSet->m_pentrencShapeMV2->encodeSymbol (abs (mvBYD.iMVY) - 1, "MB_SHP_MVDY"); if (mvBYD.iMVY != 0) { m_pbitstrmShapeMBOut->putBits (signOf(mvBYD.iMVY), (UInt) 1, "MB_SHP_MVDY_Sign"); nBits++; } m_pentrencSet->m_pentrencShapeMV1->attachStream(*m_pbitstrmOut); m_pentrencSet->m_pentrencShapeMV2->attachStream(*m_pbitstrmOut); return nBits;}Bool CVideoObjectEncoder::sameBlockTranspStatus (const CMBMode* pmbmd, PixelC pxlcRecon) //assume src is 16 x 16 buffer{ if (pxlcRecon == opaqueValue) return ((pmbmd->m_rgTranspStatus [Y_BLOCK1] != ALL) && //if recon is all opaque (pmbmd->m_rgTranspStatus [Y_BLOCK2] != ALL) && //then each orig. blk has to be not all transp (pmbmd->m_rgTranspStatus [Y_BLOCK3] != ALL) && (pmbmd->m_rgTranspStatus [Y_BLOCK4] != ALL)); return TRUE;}Bool CVideoObjectEncoder::sameBlockTranspStatus (const CMBMode* pmbmd, const PixelC* pxlcRecon, Int iSizeRecon) //src: 16x16 Recon: 18 x 18 || 20 x 20{ Int iBorder = (iSizeRecon == 18) ? 1 : 2; const PixelC* ppxlcBlk1 = pxlcRecon + iBorder + iBorder * iSizeRecon; const PixelC* ppxlcBlk2 = ppxlcBlk1 + BLOCK_SIZE; const PixelC* ppxlcBlk3 = pxlcRecon + iSizeRecon * iSizeRecon / 2 + iBorder; const PixelC* ppxlcBlk4 = ppxlcBlk3 + BLOCK_SIZE; static PixelC rgnOpaquePixels [4]; rgnOpaquePixels [0] = rgnOpaquePixels [1] = rgnOpaquePixels [2] = rgnOpaquePixels [3] = 0; CoordI ix, iy; for (iy = 0; iy < BLOCK_SIZE; iy++) { for (ix = 0; ix < BLOCK_SIZE; ix++) { rgnOpaquePixels [0] += ppxlcBlk1 [ix]; rgnOpaquePixels [1] += ppxlcBlk2 [ix]; rgnOpaquePixels [2] += ppxlcBlk3 [ix]; rgnOpaquePixels [3] += ppxlcBlk4 [ix]; } ppxlcBlk1 += iSizeRecon; ppxlcBlk2 += iSizeRecon; ppxlcBlk3 += iSizeRecon; ppxlcBlk4 += iSizeRecon; } Int iBlk; for (iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++) if (pmbmd->m_rgTranspStatus [iBlk] == ALL) //if org. blk is all transp, the recon can be otherwise if (rgnOpaquePixels [iBlk - 1] != 0) return FALSE; return TRUE;}UInt CVideoObjectEncoder::codeCrAndSt (CAEScanDirection shpdir, Int iInverseCR){ UInt nBits = 0; if (m_volmd.bNoCrChange == FALSE) { UInt nBitsCR = (iInverseCR == 1) ? 1 : 2; Int iCode = (iInverseCR == 1) ? 0 : (iInverseCR == 2) ? 2 : 3; m_pbitstrmShapeMBOut->putBits (iCode, nBitsCR, "MB_CR"); nBits += nBitsCR; } //Scan direction m_pbitstrmShapeMBOut->putBits ((shpdir == HORIZONTAL) ? 1 : 0, (UInt) 1, "MB_ST"); nBits++; return nBits;}Void CVideoObjectEncoder::copyReconShapeToRef (PixelC* ppxlcRefFrm, PixelC pxlcSrc) //no need to reset MB buffer{ for (Int i = 0; i < MB_SIZE; i++) { pxlcmemset (ppxlcRefFrm, pxlcSrc, MB_SIZE); ppxlcRefFrm+= m_iFrameWidthY; }}Void CVideoObjectEncoder::copyReconShapeToRef (PixelC* ppxlcRefFrm, const PixelC* ppxlcSrc, Int iSrcWidth, Int iBorder){ ppxlcSrc += iSrcWidth * iBorder + iBorder; Int iUnit = sizeof(PixelC); // NBIT: for memcpy for (Int i = 0; i < MB_SIZE; i++) { memcpy (ppxlcRefFrm, ppxlcSrc, MB_SIZE*iUnit); ppxlcRefFrm += m_iFrameWidthY; ppxlcSrc += iSrcWidth; }}Int CVideoObjectEncoder::sadForShape (const PixelC* ppxlcRefBY) const{ Int iInitSAD = 0; CoordI ix, iy; const PixelC* ppxlcCurrBY = m_ppxlcCurrMBBY; for (iy = 0; iy < MB_SIZE; iy++) { for (ix = 0; ix < MB_SIZE; ix++) iInitSAD += abs (ppxlcCurrBY [ix] - ppxlcRefBY [ix]); ppxlcCurrBY += MB_SIZE; ppxlcRefBY += m_iFrameWidthY; } return iInitSAD;}Void CVideoObjectEncoder::blkmatchForShape ( CVOPU8YUVBA* pvopcRefQ, CMotionVector* pmv, const CVector& mvPredHalfPel, CoordI iX, CoordI iY){ Int mbDiff; CoordI x = iX + (mvPredHalfPel.x >> 1), y = iY + (mvPredHalfPel.y >> 1); Int iXDest = x, iYDest = y; CoordI ix, iy; const PixelC* ppxlcRefMBY = pvopcRefQ->pixelsBY () + m_rctRefFrameY.offset (x, y); Int iMinSAD = sadForShape (ppxlcRefMBY); pmv->iMVX = pmv->iMVY = 0; Int uiPosInLoop, iLoop; // Spiral Search for the rest for (iLoop = 1; iLoop <= 16; iLoop++) { x++; y++; ppxlcRefMBY += m_iFrameWidthY + 1; for (uiPosInLoop = 0; uiPosInLoop < (iLoop << 3); uiPosInLoop++) { // inside each spiral loop if ( x >= m_rctRefVOPY0.left && y >= m_rctRefVOPY0.top && x <= m_rctRefVOPY0.right - MB_SIZE && y <= m_rctRefVOPY0.bottom - MB_SIZE ) { const PixelC* ppxlcTmpC = m_ppxlcCurrMBBY; const PixelC* ppxlcRefMB = ppxlcRefMBY; mbDiff = 0; for (iy = 0; iy < MB_SIZE; iy++) { for (ix = 0; ix < MB_SIZE; ix++) mbDiff += abs (ppxlcTmpC [ix] - ppxlcRefMB [ix]); if (mbDiff >= iMinSAD) goto NEXT_POSITION; // skip the current position ppxlcRefMB += m_iFrameWidthY; ppxlcTmpC += MB_SIZE; } iMinSAD = mbDiff; iXDest = x; iYDest = y; }NEXT_POSITION: if (uiPosInLoop < (iLoop << 1)) { ppxlcRefMBY--; x--; } else if (uiPosInLoop < (iLoop << 2)) { ppxlcRefMBY -= m_iFrameWidthY; y--; } else if (uiPosInLoop < (iLoop * 6)) { ppxlcRefMBY++; x++; } else { ppxlcRefMBY += m_iFrameWidthY; y++; } } } *pmv = CMotionVector (iXDest - iX, iYDest - iY);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -