⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vopmbenc.cpp

📁 此源码是在VC平台下,实现MPEG4编解码的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	Bool bRestartDelayedQP = TRUE;

	for (iMBY = 0; iMBY < m_iNumMBY; iMBY++) {
		PixelC* ppxlcRefMBY  = ppxlcRefY;
		PixelC* ppxlcRefMBU  = ppxlcRefU;
		PixelC* ppxlcRefMBV  = ppxlcRefV;
		PixelC* ppxlcRefMBBY = ppxlcRefBY;
		PixelC* ppxlcRefMBBUV = ppxlcRefBUV;
		PixelC* ppxlcRefMBA  = ppxlcRefA;
		PixelC* ppxlcOrigMBY = ppxlcOrigY;
		PixelC* ppxlcOrigMBU = ppxlcOrigU;
		PixelC* ppxlcOrigMBV = ppxlcOrigV;
		PixelC* ppxlcOrigMBBY = ppxlcOrigBY;
		PixelC* ppxlcOrigMBA = ppxlcOrigA;

	    // 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);	
		}

		for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, iMB++) {
		  // code current macroblock only if it is not a hole 
			m_bSptMB_NOT_HOLE	 = 	bSptMB_NOT_HOLE;
			if (!m_bSptMB_NOT_HOLE) 
				goto EOMB2;

			// 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) {
				Int iCounter = m_pbitstrmOut -> getCounter();
				if( iCounter - m_iVPCounter > m_volmd.bVPBitTh ) {
					codeVideoPacketHeader (iMBX, iMBY, pmbmd->m_stepSize);	// 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_

			pmbmd->m_bSkip = FALSE;	//reset for direct mode 
			pmbmd->m_bPadded=FALSE;
			copyToCurrBuffWithShape (
				ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, 
				ppxlcOrigMBBY, ppxlcOrigMBA,
				m_iFrameWidthY, m_iFrameWidthUV
			);
			downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV); // downsample original BY now for LPE padding (using original shape)
			decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY);
			if (pmbmd -> m_rgTranspStatus [0] == PARTIAL) {
				LPEPadding (pmbmd);
				m_statsMB.nBitsShape += codeIntraShape (ppxlcRefMBBY, pmbmd, iMBX, iMBY);
				downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV);
				decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY); // need to modify it a little (NONE block won't change)
			}
			else
				m_statsMB.nBitsShape += codeIntraShape (ppxlcRefMBBY, pmbmd, iMBX, iMBY);
			/*BBM// Added for Boundary by Hyundai(1998-5-9)
			if (m_vopmd.bInterlace) initMergedMode (pmbmd);
			// End of Hyundai(1998-5-9)*/
			if(m_volmd.bShapeOnly == FALSE) {// shape only mode
				pmbmd->m_stepSizeDelayed = iQPPrev;

				if (pmbmd -> m_rgTranspStatus [0] != ALL) {
					pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;
					assert (pmbmd->m_stepSize <= iMaxQP && pmbmd->m_stepSize > 0);
					
					if(bRestartDelayedQP)
					{
						pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;
						bRestartDelayedQP = FALSE;
					}
					
					iQPPrev = pmbmd->m_stepSize;
					if (pmbmd->m_intStepDelta == 0)
						pmbmd->m_dctMd = INTRA;
					else
						pmbmd->m_dctMd = INTRAQ;
					if (m_volmd.fAUsage == EIGHT_BIT) {
						// update alpha quant
						if(!m_volmd.bNoGrayQuantUpdate)
						{
							iQPPrevAlpha = (iQPPrev * m_vopmd.intStepIAlpha) / m_vopmd.intStepI;
							if(iQPPrevAlpha<1)
								iQPPrevAlpha=1;
						}
						pmbmd->m_stepSizeAlpha = iQPPrevAlpha;
					}
					/*BBM// Added for Boundary by Hyundai(1998-5-9)
					if (m_vopmd.bInterlace && pmbmd->m_rgTranspStatus[0] == PARTIAL)
						boundaryMacroBlockMerge (pmbmd);
					// End of Hyundai(1998-5-9)*/
					quantizeTextureIntraMB (iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA);
					codeMBTextureHeadOfIVOP (pmbmd);
					sendDCTCoefOfIntraMBTexture (pmbmd);
					if (m_volmd.fAUsage == EIGHT_BIT) {
						codeMBAlphaHeadOfIVOP (pmbmd);
						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++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -