📄 vopmbenc.cpp
字号:
sendDCTCoefOfIntraMBAlpha (pmbmd); } /*BBM// Added for Boundary by Hyundai(1998-5-9) if (m_vopmd.bInterlace && pmbmd->m_bMerged[0]) mergedMacroBlockSplit (pmbmd, ppxlcRefMBY, ppxlcRefMBA); // End of Hyundai(1998-5-9)*/ // MC padding // Added for field based MC padding by Hyundai(1998-5-9) if (!m_vopmd.bInterlace) { if (pmbmd -> m_rgTranspStatus [0] == PARTIAL) mcPadCurrMB (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA); padNeighborTranspMBs ( iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA ); } // End of Hyundai(1998-5-9) } else { // Added for field based MC padding by Hyundai(1998-5-9) if (!m_vopmd.bInterlace) { padCurrAndTopTranspMBFromNeighbor ( iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA ); } // End of Hyundai(1998-5-9) } }EOMB2: ppxlcRefMBA += MB_SIZE; ppxlcOrigMBBY += MB_SIZE; ppxlcOrigMBA += MB_SIZE; pmbmd++;#ifdef __TRACE_AND_STATS_ m_statsVOP += m_statsMB;#endif // __TRACE_AND_STATS_ ppxlcRefMBY += MB_SIZE; ppxlcRefMBU += BLOCK_SIZE; ppxlcRefMBV += BLOCK_SIZE; ppxlcRefMBBY += MB_SIZE; ppxlcRefMBBUV += BLOCK_SIZE; ppxlcOrigMBY += MB_SIZE; ppxlcOrigMBU += BLOCK_SIZE; ppxlcOrigMBV += BLOCK_SIZE; // Identify whether next Sprite object macroblock is not a hole and should be coded ? if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE) bSptMB_NOT_HOLE = SptPieceMB_NOT_HOLE(iMBX+1, iMBY, pmbmd); } MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove; m_rgpmbmAbove = m_rgpmbmCurr; // dshu: begin of modification if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE) SaveMBmCurrRow (iMBY, m_rgpmbmCurr); // save current row pointed by *m_rgpmbmCurr // dshu: end of modification m_rgpmbmCurr = ppmbmTemp; ppxlcRefY += m_iFrameWidthYxMBSize; ppxlcRefA += m_iFrameWidthYxMBSize; ppxlcRefU += m_iFrameWidthUVxBlkSize; ppxlcRefV += m_iFrameWidthUVxBlkSize; ppxlcRefBY += m_iFrameWidthYxMBSize; ppxlcRefBUV += m_iFrameWidthUVxBlkSize; ppxlcOrigY += m_iFrameWidthYxMBSize; ppxlcOrigBY += m_iFrameWidthYxMBSize; ppxlcOrigA += m_iFrameWidthYxMBSize; ppxlcOrigU += m_iFrameWidthUVxBlkSize; ppxlcOrigV += m_iFrameWidthUVxBlkSize; } // Added for field based MC padding by Hyundai(1998-5-9) if (m_vopmd.bInterlace && m_volmd.bShapeOnly == FALSE) fieldBasedMCPadding (field_pmbmd, m_pvopcRefQ1); // End of Hyundai(1998-5-9)}Void CVideoObjectEncoder::encodeNSForPVOP () { if (m_uiSprite == 0) //low latency: not motion esti motionEstPVOP (); // Rate Control if (m_uiRateControl==RC_MPEG4) { Double Ec = m_iMAD / (Double) (m_iNumMBY * m_iNumMBX * 16 * 16); m_statRC.setMad (Ec); if (m_statRC.noCodedFrame () >= RC_START_RATE_CONTROL) { UInt newQStep = m_statRC.updateQuanStepsize (); m_vopmd.intStepDiff = newQStep - m_vopmd.intStep; // DQUANT m_vopmd.intStep = newQStep; } cout << "\t" << "Q:" << "\t\t\t" << m_vopmd.intStep << "\n"; m_statRC.setQc (m_vopmd.intStep); } // MB rate control //Int iIndexofQ = 0; //Int rgiQ [4] = {-1, -2, 1, 2}; // ----- Int iMBX, iMBY, iMB = 0; Int iMaxQP = (1<<m_volmd.uiQuantPrecision)-1; // NBIT CoordI y = 0; CMBMode* pmbmd = m_rgmbmd; Int iQPPrev = m_vopmd.intStep; if (m_uiRateControl>=RC_TM5) iQPPrev = m_tm5rc.tm5rc_start_mb(); CMotionVector* pmv = m_rgmv; PixelC* ppxlcRefY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY; PixelC* ppxlcRefU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV; PixelC* ppxlcRefV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV; PixelC* ppxlcOrigY = (PixelC*) m_pvopcOrig->pixelsBoundY (); PixelC* ppxlcOrigU = (PixelC*) m_pvopcOrig->pixelsBoundU (); PixelC* ppxlcOrigV = (PixelC*) m_pvopcOrig->pixelsBoundV (); Bool bRestartDelayedQP = TRUE; for (iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += MB_SIZE) { PixelC* ppxlcRefMBY = ppxlcRefY; PixelC* ppxlcRefMBU = ppxlcRefU; PixelC* ppxlcRefMBV = ppxlcRefV; PixelC* ppxlcOrigMBY = ppxlcOrigY; PixelC* ppxlcOrigMBU = ppxlcOrigU; PixelC* ppxlcOrigMBV = ppxlcOrigV; CoordI x = 0; // In a given Sprite update piece, identify whether current macroblock is not a hole and should be coded ? Bool bSptMB_NOT_HOLE= TRUE; if (m_uiSprite == 1 && m_vopmd.SpriteXmitMode != STOP) { bSptMB_NOT_HOLE = SptUpdateMB_NOT_HOLE(0, iMBY, pmbmd); m_statsMB.nBitsShape = 0; } for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, x += MB_SIZE, iMB++) { // skip current Sprite update macroblock if it is transparent if (m_uiSprite == 1 && m_vopmd.SpriteXmitMode != STOP && pmbmd -> m_rgTranspStatus [0] == ALL) goto EOMB3; else if (m_uiSprite == 1) { m_bSptMB_NOT_HOLE = bSptMB_NOT_HOLE; pmv -> setToZero (); pmbmd->m_bhas4MVForward = FALSE ; pmbmd -> m_dctMd = INTER ; }#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y"); m_statsMB.reset ();#endif // __TRACE_AND_STATS_ pmbmd->m_intStepDelta = 0; // MB rate control if (m_uiRateControl>=RC_TM5) { pmbmd->m_intStepDelta = m_tm5rc.tm5rc_calc_mquant(iMB, m_statsVOP.total()) - iQPPrev; if (pmbmd->m_intStepDelta>2) pmbmd->m_intStepDelta = 2; else if (pmbmd->m_intStepDelta<-2) pmbmd->m_intStepDelta = -2; }#ifdef _MBQP_CHANGE_ if (!pmbmd ->m_bhas4MVForward && !pmbmd ->m_bSkip) { iIndexofQ = (iIndexofQ + 1) % 4; pmbmd->m_intStepDelta = rgiQ [iIndexofQ]; Int iQuantMax = (1<<m_volmd.uiQuantPrecision) - 1; if ((iQPPrev + pmbmd->m_intStepDelta) > iQuantMax) pmbmd->m_intStepDelta = 0; if ((iQPPrev + pmbmd->m_intStepDelta) <= 0) pmbmd->m_intStepDelta = 0; if (pmbmd->m_intStepDelta != 0) { if (pmbmd->m_dctMd == INTRA) pmbmd->m_dctMd = INTRAQ; else if (pmbmd ->m_dctMd == INTER) pmbmd->m_dctMd = INTERQ; } } // -----#endif //_MBQP_CHANGE_ pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;/* NBIT: change 31 to iMaxQP assert (pmbmd->m_stepSize <= 31 && pmbmd->m_stepSize > 0);*/ assert (pmbmd->m_stepSize <= iMaxQP && pmbmd->m_stepSize > 0); if ( m_volmd.bVPBitTh >= 0) { Int iCounter = m_pbitstrmOut -> getCounter(); if( iCounter - m_iVPCounter > m_volmd.bVPBitTh ) { // reset DQ to use QP in VP header pmbmd->m_intStepDelta = 0; if (pmbmd->m_dctMd == INTRAQ) pmbmd->m_dctMd = INTRA; else if (pmbmd ->m_dctMd == INTERQ) pmbmd->m_dctMd = INTER; iQPPrev = pmbmd->m_stepSize; codeVideoPacketHeader (iMBX, iMBY, pmbmd->m_stepSize); // video packet header m_iVPCounter = iCounter; bRestartDelayedQP = TRUE; } } if(bRestartDelayedQP) pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize; else pmbmd->m_stepSizeDelayed = iQPPrev; copyToCurrBuff (ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, m_iFrameWidthY, m_iFrameWidthUV); encodePVOPMB ( ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pmbmd, pmv, iMBX, iMBY, x, y ); if (!pmbmd->m_bSkip) { iQPPrev = pmbmd->m_stepSize; bRestartDelayedQP = FALSE; }EOMB3: pmbmd++; pmv += PVOP_MV_PER_REF_PER_MB;#ifdef __TRACE_AND_STATS_ m_statsVOP += m_statsMB;#endif // __TRACE_AND_STATS_ ppxlcRefMBY += MB_SIZE; ppxlcRefMBU += BLOCK_SIZE; ppxlcRefMBV += BLOCK_SIZE; ppxlcOrigMBY += MB_SIZE; ppxlcOrigMBU += BLOCK_SIZE; ppxlcOrigMBV += BLOCK_SIZE; // Identify whether next Sprite update macroblock is not a hole and should be coded ? if (m_uiSprite == 1 && m_vopmd.SpriteXmitMode != STOP && iMBX < (m_iNumMBX-1)) bSptMB_NOT_HOLE = SptUpdateMB_NOT_HOLE(iMBX+1, iMBY, pmbmd); } MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove; m_rgpmbmAbove = m_rgpmbmCurr; m_rgpmbmCurr = ppmbmTemp; ppxlcRefY += m_iFrameWidthYxMBSize; ppxlcRefU += m_iFrameWidthUVxBlkSize; ppxlcRefV += m_iFrameWidthUVxBlkSize; ppxlcOrigY += m_iFrameWidthYxMBSize; ppxlcOrigU += m_iFrameWidthUVxBlkSize; ppxlcOrigV += m_iFrameWidthUVxBlkSize; }}Void CVideoObjectEncoder::encodeNSForPVOP_WithShape (){ Int iMBX, iMBY, iMB = 0; motionEstPVOP_WithShape (); // shape bitstream is set to shape cache m_pbitstrmShapeMBOut = m_pbitstrmShape; // Rate Control if (m_uiRateControl==RC_MPEG4) { Double Ec = m_iMAD / (Double) (m_iNumMBY * m_iNumMBX * 16 * 16); m_statRC.setMad (Ec); if (m_statRC.noCodedFrame () >= RC_START_RATE_CONTROL) { UInt newQStep = m_statRC.updateQuanStepsize (); m_vopmd.intStepDiff = newQStep - m_vopmd.intStep; // DQUANT m_vopmd.intStep = newQStep; } cout << "\t" << "Q:" << "\t\t\t" << m_vopmd.intStep << "\n"; m_statRC.setQc (m_vopmd.intStep); } CoordI y = m_rctCurrVOPY.top; CMBMode* pmbmd = m_rgmbmd; // Added for field based MC padding by Hyundai(1998-5-9) CMBMode* field_pmbmd = m_rgmbmd; // End of Hyundai(1998-5-9) Int iQPPrev = m_vopmd.intStep; Int iQPPrevAlpha = m_vopmd.intStepPAlpha; if (m_uiRateControl>=RC_TM5) iQPPrev = m_tm5rc.tm5rc_start_mb(); CMotionVector* pmv = m_rgmv; CMotionVector* pmvBY = m_rgmvBY; PixelC* ppxlcRefY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY; PixelC* ppxlcRefU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV; PixelC* ppxlcRefV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV; PixelC* ppxlcRefBY = (PixelC*) m_pvopcRefQ1->pixelsBY () + m_iStartInRefToCurrRctY; PixelC *ppxlcRefA = NULL, * ppxlcOrigA = NULL; PixelC* ppxlcOrigY = (PixelC*) m_pvopcOrig->pixelsBoundY (); PixelC* ppxlcOrigU = (PixelC*) m_pvopcOrig->pixelsBoundU (); PixelC* ppxlcOrigV = (PixelC*) m_pvopcOrig->pixelsBoundV (); PixelC* ppxlcOrigBY = (PixelC*) m_pvopcOrig->pixelsBoundBY (); if (m_volmd.fAUsage == EIGHT_BIT) { ppxlcRefA = (PixelC*) m_pvopcRefQ1->pixelsA () + m_iStartInRefToCurrRctY; ppxlcOrigA = (PixelC*) m_pvopcOrig->pixelsBoundA (); } Bool bRestartDelayedQP = TRUE;// Added for error resilient mode by Toshiba(1997-11-14) Bool bCodeVPHeaderNext = FALSE; // needed only for OBMC Int iTempVPMBnum = 0;// End Toshiba(1997-11-14) for (iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += MB_SIZE) { PixelC* ppxlcRefMBY = ppxlcRefY; PixelC* ppxlcRefMBU = ppxlcRefU; PixelC* ppxlcRefMBV = ppxlcRefV; PixelC* ppxlcRefMBBY = ppxlcRefBY; PixelC* ppxlcRefMBA = ppxlcRefA; PixelC* ppxlcOrigMBY = ppxlcOrigY; PixelC* ppxlcOrigMBU = ppxlcOrigU; PixelC* ppxlcOrigMBV = ppxlcOrigV; PixelC* ppxlcOrigMBBY = ppxlcOrigBY; PixelC* ppxlcOrigMBA = ppxlcOrigA; CoordI x = m_rctCurrVOPY.left;#ifdef __TRACE_AND_STATS_ m_statsMB.reset ();#endif // __TRACE_AND_STATS_ // initiate advance shape coding // Added for error resilient mode by Toshiba(1997-11-14) // The following operation is needed only for OBMC if ( m_volmd.bVPBitTh >= 0) { Int iCounter = m_pbitstrmOut -> getCounter(); bCodeVPHeaderNext = iCounter - m_iVPCounter > m_volmd.bVPBitTh; if( bCodeVPHeaderNext ) { iTempVPMBnum = m_iVPMBnum; m_iVPMBnum = VPMBnum(0, iMBY); m_iVPCounter = iCounter; } } else { bCodeVPHeaderNext = FALSE; }// End Toshiba(1997-11-14) copyToCurrBuffJustShape (ppxlcOrigMBBY, m_iFrameWidthY); // Modified for error resilient mode by Toshiba(1997-11-14) ShapeMode shpmdColocatedMB; if(m_vopmd.bShapeCodingType) { shpmdColocatedMB = m_rgmbmdRef [ min (max (0, iMBY), m_iNumMBYRef - 1) * m_iNumMBXRef].m_shpmd; encodePVOPMBJustShape(ppxlcRefMBBY, pmbmd, shpmdColocatedMB, pmv, pmvBY, x, y, 0, iMBY); } else { m_statsMB.nBitsShape += codeIntraShape (ppxlcRefMBBY, pmbmd, 0, iMBY); decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY); } // End Toshiba(1997-11-14) // Added for error resilient mode by Toshiba(1997-11-14) // The following operation is needed only for OBMC if( bCodeVPHeaderNext ) m_iVPMBnum = iTempVPMBnum; // End Toshiba(1997-11-14) if(pmbmd->m_bhas4MVForward) padMotionVectors(pmbmd,pmv); for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, x += MB_SIZE, iMB++) { // MB rate control if (m_uiRateControl>=RC_TM5) { pmbmd->m_intStepDelta = m_tm5rc.tm5rc_calc_mquant(iMB, m_statsVOP.total()) - iQPPrev; if (pmbmd->m_intStepDelta>2) pmbmd->m_intStepDelta = 2; else if (pmbmd->m_intStepDelta<-2) pmbmd->m_intStepDelta = -2; } // Added for error resilient mode by Toshiba(1997-11-14) pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta; if ( m_volmd.bVPBitTh >= 0) { if( bCodeVPHeaderNext ) { codeVideoPacketHeader (iMBX, iMBY, pmbmd->m_stepSize); // video packet header bRestartDelayedQP = TRUE; } } else { bCodeVPHeaderNext = FALSE; } // End Toshiba(1997-11-14) #ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y (Texture)"); // shape quantization part m_statsMB.reset ();#endif // __TRACE_AND_STATS_ pmbmd->m_bPadded=FALSE; dumpCachedShapeBits(); if(iMBX<m_iNumMBX-1) { // Added for error resilient mode by Toshiba(1997-11-14) // The following operation is needed only for OBMC if ( m_volmd.bVPBitTh >= 0) { Int iCounter = m_pbitstrmOut -> getCounter(); bCodeVPHeaderNext = iCounter - m_iVPCounter > m_volmd.bVPBitTh; if( bCodeVPHeaderNext ) { iTempVPMBnum = m_iVPMBnum; m_iVPMBnum = VPMBnum(iMBX+1, iMBY); m_iVPCounter = iCounter; } } else { bCodeVPHeaderNext = FALSE; } // End Toshiba(1997-11-14) // code shape 1mb in advance copyToCurrBuffJustShape (ppxlcOrigMBBY+MB_SIZE,m_iFrameWidthY); // Modified for error resilient mode by Toshiba(1997-11-14) if(m_vopmd.bShapeCodingType) { shpmdColocatedMB = m_rgmbmdRef [ min (max (0, iMBX+1), m_iNumMBXRef-1) + min (max (0, iMBY), m_iNumMBYRef-1) * m_iNumMBXRef ].m_shpmd; encodePVOPMBJustShape( ppxlcRefMBBY+MB_SIZE, pmbmd+1, shpmdColocatedMB, pmv + PVOP_MV_PER_REF_PER_MB, pmvBY+1, x+MB_SIZE, y, iMBX+1, iMBY ); } else { m_statsMB.nBitsShape += codeIntraShape ( ppxlcRefMBBY+MB_SIZE, pmbmd+1, iMBX+1, iMBY ); decideTransparencyStatus (pmbmd+1, m_ppxlcCurrMBBY); } // End Toshiba(1997-11-14) // Added for error resilient mode by Toshiba(1997-11-14) // The following operation is needed only for OBMC if( bCodeVPHeaderNext ) m_iVPMBnum = iTempVPMBnum; // End Toshiba(1997-11-14) // shape needs padded mvs ready for next mb if((pmbmd+1)->m_bhas4MVForward) padMotionVectors(pmbmd+1, pmv + PVOP_MV_PER_REF_PER_MB); } /*BBM// Added for Boundary by Hyundai(1998-5-9)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -