📄 shpenc.cpp
字号:
UInt nBitsMV=0; UInt nBitsModeInter = codeShapeModeInter (pmbmd->m_shpmd, shpmdColocatedMB); if(pmbmd->m_shpmd==INTER_CAE_MVDNZ) nBitsMV = encodeMVDS (mvBYD);#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ("MB_CAE_INTER_VERTICAL_CODING (TRIAL)");#endif // __TRACE_AND_STATS_ UInt nBitsVInter = encodeCAEInter (pmbmd->m_shpmd, VERTICAL);#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ("MB_CAE_INTER_HORIZONTAL_CODING (TRIAL)");#endif // __TRACE_AND_STATS_ UInt nBitsHInter = encodeCAEInter (pmbmd->m_shpmd, HORIZONTAL); UInt nBitsInter = nBitsModeInter + nBitsMV + min (nBitsVInter, nBitsHInter); m_pbitstrmShapeMBOut->gotoBookmark (); if (nBitsInter < nBitsIntra) { // choose inter coding#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ("MB_CAE_INTER_CODING (REAL)"); m_pbitstrmOut->trace (mvShapeMVP, "MB_SHP_MV_PRED (half pel)"); m_pbitstrmOut->trace (*pmvBY, "MB_SHP_MV (half pel)"); m_pbitstrmOut->trace (mvBYD, "MB_SHP_MVD (half pel)");#endif // __TRACE_AND_STATS_ codeShapeModeInter (pmbmd->m_shpmd, shpmdColocatedMB); if(pmbmd->m_shpmd==INTER_CAE_MVDNZ) encodeMVDS (mvBYD); if(nBitsVInter<nBitsHInter) encodeCAEInter (pmbmd->m_shpmd, VERTICAL); else encodeCAEInter (pmbmd->m_shpmd, HORIZONTAL); return nBitsInter; } else { // choose intra coding#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ("MB_CAE_INTRA_CODING (REAL)");#endif // __TRACE_AND_STATS_ pmvBY->iMVX = NOT_MV; pmvBY->iMVY = NOT_MV; pmbmd->m_shpmd = INTRA_CAE; codeShapeModeInter (pmbmd->m_shpmd, shpmdColocatedMB); if(nBitsVIntra<nBitsHIntra) encodeCAEIntra (pmbmd->m_shpmd, VERTICAL); else encodeCAEIntra (pmbmd->m_shpmd, HORIZONTAL); return nBitsIntra; } } case MVDZ_NOUPDT: case MVDNZ_NOUPDT: {#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ("MB_CAE_INTER_CODING_NO_UPDATE"); m_pbitstrmOut->trace (mvShapeMVP, "MB_SHP_MV_PRED (half pel)"); m_pbitstrmOut->trace (*pmvBY, "MB_SHP_MV (half pel)"); m_pbitstrmOut->trace (mvBYD, "MB_SHP_MVD (half pel)");#endif // __TRACE_AND_STATS_ copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, m_puciPredBAB->pixels (), MC_BAB_SIZE, MC_BAB_BORDER);#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ((PixelC *)m_puciPredBAB->pixels(), MC_BAB_SIZE, MC_BAB_SIZE, "MB_MC_PRED_BAB");#endif // __TRACE_AND_STATS_ Int nBits = codeShapeModeInter (pmbmd->m_shpmd, shpmdColocatedMB); if(pmbmd->m_shpmd==MVDNZ_NOUPDT) nBits += encodeMVDS (mvBYD); return nBits; } default: assert(FALSE); return 0; }}UInt CVideoObjectEncoder::codeShapeModeIntra (ShapeMode shpmd, const CMBMode* pmbmd, Int iMBX, Int iMBY){ UInt nBits = 0; assert (shpmd == ALL_TRANSP || shpmd == ALL_OPAQUE || shpmd == INTRA_CAE); //static Int iLeftTopMostMB = 0; //Int iRightMostMB = m_iNumMBX - 1; //get previous shape codes; Bool bLeftBndry, bRightTopBndry, bTopBndry, bLeftTopBndry; Int iMBnum = VPMBnum(iMBX, iMBY); bLeftBndry = bVPNoLeft(iMBnum, iMBX); bTopBndry = bVPNoTop(iMBnum); bRightTopBndry = bVPNoRightTop(iMBnum, iMBX); bLeftTopBndry = bVPNoLeftTop(iMBnum, iMBX); ShapeMode shpmdTop = ALL_TRANSP; ShapeMode shpmdTopRight = ALL_TRANSP; ShapeMode shpmdTopLeft = ALL_TRANSP; ShapeMode shpmdLeft = ALL_TRANSP; // Modified for error resilient mode by Toshiba(1997-11-14) if (!bTopBndry) shpmdTop = (pmbmd - m_iNumMBX)->m_shpmd; if (!bRightTopBndry) shpmdTopRight = (pmbmd - m_iNumMBX + 1)->m_shpmd; if (!bLeftBndry) shpmdLeft = (pmbmd - 1)->m_shpmd; if (!bLeftTopBndry) shpmdTopLeft = (pmbmd - m_iNumMBX - 1)->m_shpmd; //if (iMBY > iLeftTopMostMB) { // shpmdTop = (pmbmd - m_iNumMBX)->m_shpmd; // if (iMBX < iRightMostMB) // shpmdTopRight = (pmbmd - m_iNumMBX + 1)->m_shpmd; //} //if (iMBX > iLeftTopMostMB) { // shpmdLeft = (pmbmd - 1)->m_shpmd; // if (iMBY > iLeftTopMostMB) // shpmdTopLeft = (pmbmd - m_iNumMBX - 1)->m_shpmd; //} // End Toshiba(1997-11-14) assert (shpmdTop != UNKNOWN && shpmdTopRight != UNKNOWN && shpmdTopLeft != UNKNOWN && shpmdLeft != UNKNOWN); //get code and its size UInt uiTblIndex = shpmdTopLeft * 81 + shpmdTop * 27 + shpmdTopRight * 9 + shpmdLeft * 3 + shpmd; assert (uiTblIndex >= 0 && uiTblIndex < 243); assert (grgchFirstShpCd [uiTblIndex] == 0 || grgchFirstShpCd [uiTblIndex] == 2 || grgchFirstShpCd [uiTblIndex] == 3); // Modified for error resilient mode by Toshiba(1997-11-14) UInt nCodeSize = (grgchFirstShpCd [uiTblIndex] == 0) ? 1 : grgchFirstShpCd [uiTblIndex];#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ((Int) shpmd, "MB_Curr_ShpMd");#endif // __TRACE_AND_STATS_ m_pbitstrmShapeMBOut->putBits ((Int) 1, nCodeSize, "MB_Shape_Mode"); // End Toshiba(1997-11-14) nBits += nCodeSize; return nBits;}UInt CVideoObjectEncoder::codeShapeModeInter (const ShapeMode& shpmd, const ShapeMode& shpmdColocatedMB){ assert (shpmdColocatedMB != UNKNOWN && shpmd != UNKNOWN); UInt nBits = 0; CEntropyEncoder* pentrenc = m_pentrencSet->m_ppentrencShapeMode [shpmdColocatedMB];#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ((Int) shpmdColocatedMB, "MB_Colocated_ShpMd"); m_pbitstrmOut->trace ((Int) shpmd, "MB_Curr_ShpMd");#endif // __TRACE_AND_STATS_ pentrenc->attachStream(*m_pbitstrmShapeMBOut); nBits += pentrenc->encodeSymbol (shpmd, "MB_Shape_Mode"); pentrenc->attachStream(*m_pbitstrmOut); return nBits;}// find appropriate size for coded babsShapeMode CVideoObjectEncoder::round (PixelC* ppxlcSrcFrm, const CMBMode* pmbmd) //only to partial BABs{ ShapeMode shpmd; Bool bIsErrorLarge; if (m_volmd.bNoCrChange == FALSE) { // attempt to reduce bab size m_bNoShapeChg = FALSE; #define iThreshD4 (7 * MPEG4_OPAQUE) // reduce by factor 4 downSampleShape (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, m_ppxlcCurrMBBYDown4, m_rgiPxlIndx8x8, 4, iThreshD4, 16); // see if this size is acceptable shpmd = INTRA_CAE; m_iInverseCR = 4; m_iWidthCurrBAB = 8; // subsample border before upsample to original size subsampleLeftTopBorderFromVOP (ppxlcSrcFrm, m_ppxlcCurrMBBYDown4); makeRightBottomBorder (m_ppxlcCurrMBBYDown4, 8); upSampleShape(ppxlcSrcFrm,m_ppxlcCurrMBBYDown4,m_ppxlcReconCurrBAB); // check if approximation is acceptable bIsErrorLarge = isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, m_ppxlcReconCurrBAB, m_rgiSubBlkIndx20x20, 20, pmbmd); if(!bIsErrorLarge) { // ok, so assign encoding buffer m_rgpxlcCaeSymbol = m_ppxlcCurrMBBYDown4; return shpmd; } #define iThreshD2 (MPEG4_OPAQUE) // factor 4 failed, so try to reduce by factor 2 downSampleShape (m_ppxlcCurrMBBY, m_rgiSSubBlkIndx16x16, m_ppxlcCurrMBBYDown2, m_rgiPxlIndx12x12, 2, iThreshD2, 64); // mixed, so see if this size is acceptable shpmd = INTRA_CAE; m_iInverseCR = 2; m_iWidthCurrBAB = 12; // subsample border before upsample to original size subsampleLeftTopBorderFromVOP (ppxlcSrcFrm, m_ppxlcCurrMBBYDown2); makeRightBottomBorder (m_ppxlcCurrMBBYDown2, 12); upSampleShape(ppxlcSrcFrm,m_ppxlcCurrMBBYDown2, m_ppxlcReconCurrBAB); // check if approximation is acceptable bIsErrorLarge = isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, m_ppxlcReconCurrBAB, m_rgiSubBlkIndx20x20, 20, pmbmd); if(!bIsErrorLarge) { // ok, so assign encoding buffer m_rgpxlcCaeSymbol = m_ppxlcCurrMBBYDown2; return shpmd; } } // has to be original size m_bNoShapeChg = TRUE; shpmd = INTRA_CAE; m_iInverseCR = 1; m_iWidthCurrBAB = BAB_SIZE; // copy data to ReconCurrBAB PixelC* ppxlcDst = m_ppxlcReconCurrBAB + BAB_BORDER + BAB_BORDER * TOTAL_BAB_SIZE; PixelC* ppxlcSrc = m_ppxlcCurrMBBY; Int iUnit = sizeof(PixelC); // NBIT: for memcpy Int i; for (i = 0; i < MB_SIZE; i++) { memcpy (ppxlcDst, ppxlcSrc, MB_SIZE*iUnit); ppxlcSrc += MB_SIZE; ppxlcDst += BAB_SIZE; } // make borders copyLeftTopBorderFromVOP (ppxlcSrcFrm, m_ppxlcReconCurrBAB); makeRightBottomBorder (m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE); // assign encoding buffer m_rgpxlcCaeSymbol = m_ppxlcReconCurrBAB; return shpmd;}Int CVideoObjectEncoder::downSampleShape (const PixelC* ppxlcSrc, Int* rgiSrcSubBlk, PixelC* ppxlcDst, Int* piDstPxl, Int iRate, Int iThreshold, Int nSubBlk){ Int nOpaquePixel = 0, iSum = 0; Int iSubBlk; for (iSubBlk = 0; iSubBlk < nSubBlk; iSubBlk++) { Int i = rgiSrcSubBlk [iSubBlk]; iSum = 0; for (CoordI iY = 0; iY < iRate; iY++) { for (CoordI iX = 0; iX < iRate; iX++) { iSum += abs (ppxlcSrc [i++]); //abs??? } i += MB_SIZE - iRate; } ppxlcDst [*piDstPxl] = (iSum > iThreshold) ? MPEG4_OPAQUE : MPEG4_TRANSPARENT; nOpaquePixel += ppxlcDst [*piDstPxl]; piDstPxl++; } return (nOpaquePixel /= MPEG4_OPAQUE);}Bool CVideoObjectEncoder::isErrorLarge (const PixelC* rgppxlcSrc, const Int* rgiSubBlkIndx, Int iWidthSrc, PixelC pxlcRecon, const CMBMode* pmbmd){ if (pmbmd->m_bhas4MVForward == TRUE) { if (!sameBlockTranspStatus (pmbmd, pxlcRecon)) return TRUE; } //check error in each 4x4 subblock Int iSubBlk; Int iError = 0; for (iSubBlk = 0; iSubBlk < 16; iSubBlk++) { Int i = rgiSubBlkIndx [iSubBlk]; for (CoordI iY = 0; iY < 4; iY++) { for (CoordI iX = 0; iX < 4; iX++) { iError += abs (rgppxlcSrc [i++] - pxlcRecon); } if (iError > m_volmd.iBinaryAlphaTH) return TRUE; i += iWidthSrc - 4; } } return FALSE;}Bool CVideoObjectEncoder::isErrorLarge (const PixelC* rgppxlcSrc, const Int* rgiSubBlkIndxSrc, const Int iSizeSrc, const PixelC* rgppxlcDst, const Int* rgiSubBlkIndxDst, const Int iSizeDst, const CMBMode* pmbmd){ if (pmbmd->m_bhas4MVForward == TRUE) { if (!sameBlockTranspStatus (pmbmd, rgppxlcDst, iSizeDst)) return TRUE; } //check error in each 4x4 subblock Int iSubBlk; Int iError = 0; for (iSubBlk = 0; iSubBlk < 16; iSubBlk++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -