📄 vopmbenc.cpp
字号:
//PixelC* ppxlcOrigMBA = ppxlcOrigA; if (m_volmd.fAUsage == EIGHT_BIT) { for(Int iAuxComp=0;iAuxComp<m_volmd.iAuxCompCount;iAuxComp++) { pppxlcRefMBA[iAuxComp] = pppxlcRefA[iAuxComp]; pppxlcOrigMBA[iAuxComp] = pppxlcOrigA[iAuxComp]; } } // In a given Sprite object piece, identify whether current macroblock is not a hole and should be coded ? Bool bSptMB_NOT_HOLE= TRUE; if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE && m_vopmd.SpriteXmitMode != STOP) { bSptMB_NOT_HOLE = SptPieceMB_NOT_HOLE(0, iMBY, pmbmd); RestoreMBmCurrRow (iMBY, m_rgpmbmCurr); } CoordI x = m_rctCurrVOPY.left; for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, iMB++, x+=16) { // code current macroblock only if it is not a hole pmbmd->m_dctMd = INTRA; pmbmd->m_bSkip = FALSE; //reset for direct mode pmbmd->m_bMCSEL = FALSE; //reset for direct mode pmbmd->m_bPadded = FALSE; //printf("(%d,%d)",iMBX,iMBY); m_bSptMB_NOT_HOLE = bSptMB_NOT_HOLE; if (!m_bSptMB_NOT_HOLE) goto EOMB2; if (m_uiRateControl>=RC_TM5) // mb rate control updateQP(pmbmd, iQPPrev, m_tm5rc.tm5rc_calc_mquant(iMB, m_statsVOP.total())); else {#ifdef _MBQP_CHANGE_ Int iDQuant = (rand() % 5) - 2; updateQP(pmbmd, iQPPrev, iQPPrev + iDQuant);#else // no change in step size, but still need to call... updateQP(pmbmd, iQPPrev, iQPPrev);#endif //_MBQP_CHANGE_ } if ( m_volmd.bVPBitTh >= 0) { Int iCounter = m_pbitstrmOut -> getCounter(); if( iCounter - m_iVPCounter > m_volmd.bVPBitTh ) { codeVideoPacketHeader (iMBX, iMBY, iQPPrev); // video packet header m_iVPCounter = iCounter; bRestartDelayedQP = TRUE; } } // End Toshiba(1997-11-14) #ifdef __TRACE_AND_STATS_ m_statsMB.reset (); m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y");#endif // __TRACE_AND_STATS_ copyToCurrBuffWithShape ( ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, ppxlcOrigMBBY, pppxlcOrigMBA, m_iFrameWidthY, m_iFrameWidthUV ); //Changed HHI 2000-04-11 decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY); downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV, pmbmd); // downsample original BY now for LPE padding (using original shape) if (pmbmd -> m_rgTranspStatus [0] == PARTIAL) { LPEPadding (pmbmd); m_statsMB.nBitsShape += codeIntraShape (ppxlcRefMBBY, pmbmd, iMBX, iMBY); //Changed HHI 2000-04-11 decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY); // need to modify it a little (NONE block won't change) downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV, pmbmd); } else m_statsMB.nBitsShape += codeIntraShape (ppxlcRefMBBY, pmbmd, iMBX, iMBY); if(m_volmd.bShapeOnly == FALSE) {// not shape only mode if (pmbmd -> m_rgTranspStatus [0] != ALL) { setDCVLCMode(pmbmd, &bRestartDelayedQP); // HHI Schueuer: sadct if (!m_volmd.bSadctDisable) deriveSADCTRowLengths (m_rgiCurrMBCoeffWidth, m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV, pmbmd->m_rgTranspStatus); // end HHI // HHI Schueuer: sadct if (!m_volmd.bSadctDisable) quantizeTextureIntraMB (iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pppxlcRefMBA, m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV); else quantizeTextureIntraMB (iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pppxlcRefMBA); // end HHI codeMBTextureHeadOfIVOP (pmbmd); sendDCTCoefOfIntraMBTexture (pmbmd); if (m_volmd.fAUsage == EIGHT_BIT) { for(Int iAuxComp=0;iAuxComp<m_volmd.iAuxCompCount;iAuxComp++) { // MAC (SB) 29-Nov-99 codeMBAlphaHeadOfIVOP (pmbmd,iAuxComp); sendDCTCoefOfIntraMBAlpha (pmbmd,iAuxComp); } } // MC padding if (!m_vopmd.bInterlace) { if (pmbmd -> m_rgTranspStatus [0] == PARTIAL) mcPadCurrMB (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pppxlcRefMBA); padNeighborTranspMBs ( iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pppxlcRefMBA ); } } else { // all transparent so no update possible (set dquant=0) cancelQPUpdate(pmbmd); if (!m_vopmd.bInterlace) { padCurrAndTopTranspMBFromNeighbor ( iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pppxlcRefMBA ); } } iQPPrev = pmbmd->m_stepSize; }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; if (m_volmd.fAUsage == EIGHT_BIT) { for(Int iAuxComp=0;iAuxComp<m_volmd.iAuxCompCount;iAuxComp++) { pppxlcRefMBA[iAuxComp] += MB_SIZE; pppxlcOrigMBA[iAuxComp] += MB_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; if (m_volmd.fAUsage == EIGHT_BIT) { for(Int iAuxComp=0;iAuxComp<m_volmd.iAuxCompCount;iAuxComp++) { pppxlcRefA[iAuxComp] += m_iFrameWidthYxMBSize; pppxlcOrigA[iAuxComp] += m_iFrameWidthYxMBSize; } } } // 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) if (m_volmd.fAUsage == EIGHT_BIT) { delete [] pppxlcRefA; delete [] pppxlcOrigA; delete [] pppxlcRefMBA; delete [] pppxlcOrigMBA; }}Void CVideoObjectEncoder::encodeNSForPVOP () { if (m_uiSprite == 0 || m_uiSprite == 2) // GMC motionEstPVOP (); UInt newQStep = m_vopmd.intStep; // for frame based rate control // vopmd.intStep is updated at bottom of this function // Rate Control if (m_uiRateControl==RC_MPEG4) { Double Ec = m_iMAD / (Double) (m_iNumMBY * m_iNumMBX * 16 * 16 * m_iRRVScale *m_iRRVScale); m_statRC.setMad (Ec); // calculate for next frame (should be this frame, but its too late to send vop qp!) newQStep = m_statRC.updateQuanStepsize (m_vopmd.intStep); // this is not the correct way to use rate control m_statRC.setQc (m_vopmd.intStep); } //printf("(%d %d)\n", m_vopmd.intStep, newQStep); CMotionVector *pmv_RRV = new CMotionVector[m_iNumMB *PVOP_MV_PER_REF_PER_MB]; if(m_vopmd.RRVmode.iRRVOnOff == 1) { for(Int i = 0; i < (m_iNumMB *PVOP_MV_PER_REF_PER_MB); i ++) { pmv_RRV[i] = m_rgmv[i]; } MotionVectorScalingUp(pmv_RRV, m_iNumMB, PVOP_MV_PER_REF_PER_MB); for(Int j = 0; j < (m_iNumMB *PVOP_MV_PER_REF_PER_MB); j ++) { m_rgmv[j].m_vctTrueHalfPel_x2.x = pmv_RRV[j].m_vctTrueHalfPel.x; m_rgmv[j].m_vctTrueHalfPel_x2.y = pmv_RRV[j].m_vctTrueHalfPel.y; pmv_RRV[j].m_vctTrueHalfPel_x2.x = pmv_RRV[j].m_vctTrueHalfPel.x; pmv_RRV[j].m_vctTrueHalfPel_x2.y = pmv_RRV[j].m_vctTrueHalfPel.y; } } Int iVideoPacketNumber = 0; Int iMBX, iMBY, iMB = 0; CoordI y = 0; CMBMode* pmbmd = m_rgmbmd; Int iQPPrev = m_vopmd.intStep; CMotionVector* pmv = m_rgmv; CMotionVector* plmv_RRV = pmv_RRV; 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; const PixelC* RefbufY = m_pvopcRefQ0-> pixelsY (); const PixelC* RefbufU = m_pvopcRefQ0-> pixelsU (); const PixelC* RefbufV = m_pvopcRefQ0-> pixelsV (); if (m_volmd.bNewpredEnable) { g_pNewPredEnc->CopyReftoBuf(RefbufY, RefbufU, RefbufV, m_rctRefFrameY, m_rctRefFrameUV); for (iMBY = 0; iMBY < m_iNumMBY; iMBY++) { for (iMBX = 0; iMBX < m_iNumMBX; iMBX++) { (pmbmd + iMBX + m_iNumMBX*iMBY) -> m_iNPSegmentNumber = g_pNewPredEnc->GetSliceNum((iMBX *m_iRRVScale),(iMBY *m_iRRVScale)); } } } for (iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += (MB_SIZE *m_iRRVScale)) { 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 *m_iRRVScale), iMB++) { if((m_volmd.bNewpredEnable) && g_pNewPredEnc->CheckSlice((iMBX *m_iRRVScale),(iMBY *m_iRRVScale))) { PixelC* RefpointY = (PixelC*) m_pvopcRefQ0->pixelsY () + m_iStartInRefToCurrRctY + iMBY * (MB_SIZE *m_iRRVScale) * m_rctRefFrameY.width; PixelC* RefpointU = (PixelC*) m_pvopcRefQ0->pixelsU () + m_iStartInRefToCurrRctUV + iMBY * (BLOCK_SIZE *m_iRRVScale) * m_rctRefFrameUV.width; PixelC* RefpointV = (PixelC*) m_pvopcRefQ0->pixelsV () + m_iStartInRefToCurrRctUV + iMBY * (BLOCK_SIZE *m_iRRVScale) * m_rctRefFrameUV.width; g_pNewPredEnc->ChangeRefOfSlice((const PixelC* )RefpointY, RefbufY,(const PixelC* ) RefpointU, RefbufU, (const PixelC* )RefpointV, RefbufV, (iMBX *m_iRRVScale), (iMBY *m_iRRVScale),m_rctRefFrameY, m_rctRefFrameUV); m_rctRefVOPZoom0 = m_rctRefVOPY0.upSampleBy2 (); biInterpolateY (m_pvopcRefQ0, m_rctRefVOPY0, m_puciRefQZoom0, m_rctRefVOPZoom0, m_vopmd.iRoundingControl); } // 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_ // MB rate control if (m_uiRateControl>=RC_TM5) { updateQP(pmbmd, iQPPrev, m_tm5rc.tm5rc_calc_mquant(iMB, m_statsVOP.total()) ); } else {#ifdef _MBQP_CHANGE_ Int iDQuant = (rand() % 5) - 2; updateQP(pmbmd, iQPPrev, iQPPrev + iDQuant);#else // no change in step size, but still need to call... updateQP(pmbmd, iQPPrev, iQPPrev);#endif //_MBQP_CHANGE_ } if ( m_volmd.bVPBitTh >= 0) { Int iCounter = m_pbitstrmOut -> getCounter(); if( ((m_volmd.bNewpredEnable) && (m_volmd.bNewpredSegmentType == 0)) ? g_pNewPredEnc->CheckSlice((iMBX *m_iRRVScale),(iMBY *m_iRRVScale),FALSE) : (iCounter - m_iVPCounter > m_volmd.bVPBitTh) ) { codeVideoPacketHeader (iMBX, iMBY, iQPPrev); // video packet header // prev qp is used in header, since it can be updated by dq of next mb //printf("VP"); m_iVPCounter = iCounter; bRestartDelayedQP = TRUE; iVideoPacketNumber++; } } copyToCurrBuff (ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, m_iFrameWidthY, m_iFrameWidthUV); pmbmd->m_iVideoPacketNumber = iVideoPacketNumber; encodePVOPMB ( ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pmbmd, pmv, plmv_RRV, iMBX, iMBY, x, y, &bRestartDelayedQP ); //printf("(%d)", pmbmd->m_stepSize); iQPPrev = pmbmd->m_stepSize;EOMB3: pmbmd++; pmv += PVOP_MV_PER_REF_PER_MB;// RRV insertion if (m_vopmd.RRVmode.iRRVOnOff == 1) { plmv_RRV += PVOP_MV_PER_REF_PER_MB; }// ~RRV#ifdef __TRACE_AND_STATS_ m_statsVOP += m_statsMB;#endif // __TRACE_AND_STATS_// RRV modification ppxlcRefMBY += (MB_SIZE *m_iRRVScale); ppxlcRefMBU += (BLOCK_SIZE *m_iRRVScale); ppxlcRefMBV += (BLOCK_SIZE *m_iRRVScale); ppxlcOrigMBY += (MB_SIZE *m_iRRVScale); ppxlcOrigMBU += (BLOCK_SIZE *m_iRRVScale); ppxlcOrigMBV += (BLOCK_SIZE *m_iRRVScale);// ppxlcRefMBY += MB_SIZE;// ppxlcRefMBU += BLOCK_SIZE;// ppxlcRefMBV += BLOCK_SIZE;// ppxlcOrigMBY += MB_SIZE;// ppxlcOrigMBU += BLOCK_SIZE;// ppxlcOrigMBV += BLOCK_SIZE;// ~RRV // 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; }// RRV insertion if(m_vopmd.RRVmode.iRRVOnOff == 1) { ppxlcRefY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY; ppxlcRefU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV; ppxlcRefV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV; filterCodedPictureForRRV(ppxlcRefY, ppxlcRefU, ppxlcRefV, m_ivolWidth, m_ivolHeight, m_iNumMBX, m_iNumMBY, m_iFrameWidthY, m_iFrameWidthUV); }// ~RRV// NEWPRED if(m_volmd.bNewpredEnable) { for( int iSlice = 0; iSlice < g_pNewPredEnc->m_iNumSlice; iSlice++ ) { int iMBY = g_pNewPredEnc->NowMBA(iSlice)/((g_pNewPredEnc->getwidth())/MB_SIZE); PixelC* RefpointY = (PixelC*) m_pvopcRefQ0->pixelsY () + (m_iStartInRefToCurrRctY-EXPANDY_REF_FRAME) + iMBY * MB_SIZE * m_rctRefFrameY.width; PixelC* RefpointU = (PixelC*) m_pvopcRefQ0->pixelsU () + (m_iStartInRefToCurrRctUV-EXPANDUV_REF_FRAME) + iMBY * BLOCK_SIZE * m_rctRefFrameUV.width; PixelC* RefpointV = (PixelC*) m_pvopcRefQ0->pixelsV () + (m_iStartInRefToCurrRctUV-EXPANDUV_REF_FRAME) + iMBY * BLOCK_SIZE * m_rctRefFrameUV.width; g_pNewPredEnc->CopyNPtoPrev(iSlice, RefpointY, RefpointU, RefpointV); } repeatPadYOrA ((PixelC*) m_pvopcRefQ0->pixelsY () + m_iOffsetForPadY, m_pvopcRefQ0); repeatPadUV (m_pvopcRefQ0); }// ~NEWPRED delete pmv_RRV; // update the vop header qp if changed by rate control m_vopmd.intStep = newQStep;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -