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

📄 vopmbenc.cpp

📁 网络MPEG4IP流媒体开发源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************This software module was originally developed by 	Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation	Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation	Bruce Lin (blin@microsoft.com), Microsoft Corporation	Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation	Simon Winder (swinder@microsoft.com), Microsoft Corporation	(date: March, 1996)and edited by        Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Centerand also edited by	Yoshihiro Kikuchi (TOSHIBA CORPORATION)	Takeshi Nagai (TOSHIBA CORPORATION)	Toshiaki Watanabe (TOSHIBA CORPORATION)	Noboru Yamaguchi (TOSHIBA CORPORATION)in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). This software module is an implementation of a part of one or more MPEG-4 Video tools as specified by the MPEG-4 Video. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-4 Video conforming products. Microsoft retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. This copyright notice must be included in all copies or derivative works. Copyright (c) 1996, 1997.Module Name:	vopmbEnc.cppAbstract:	Encode MB's for each VOP (I-, P-, and B-VOP's)Revision History:	Dec. 11, 1997:	Interlaced tools added by NextLevel Systems (GI)                    B. Eifrig, (beifrig@nlvl.com) X. Chen, (xchen@nlvl.com)        May. 9   1998:  add boundary by Hyundai Electronics                                   Cheol-Soo Park (cspark@super5.hyundai.co.kr)         May. 9   1998:  add field based MC padding by Hyundai Electronics                                   Cheol-Soo Park (cspark@super5.hyundai.co.kr) 	May 9, 1999:	tm5 rate control by DemoGraFX, duhoff@mediaone.net*************************************************************************/#include <stdio.h>#include <math.h>#include <stdlib.h>#include <iostream.h>#include "typeapi.h"#include "codehead.h"#include "entropy/bitstrm.hpp"#include "entropy/entropy.hpp"#include "entropy/huffman.hpp"#include "mode.hpp"#include "global.hpp"#include "vopses.hpp"#include "vopseenc.hpp"#ifdef __MFC_#ifdef _DEBUG#undef THIS_FILEstatic char BASED_CODE THIS_FILE[] = __FILE__;#endif#define new DEBUG_NEW				   #endif // __MFC_Void CVideoObjectEncoder::encodeVOP ()	{	if (m_uiRateControl>=RC_TM5) {		m_tm5rc.tm5rc_init_pict(m_vopmd.vopPredType,								m_pvopcOrig->pixelsBoundY (),								m_iFrameWidthY,								m_iNumMBX,								m_iNumMBY);	}// Added for Data Partitioning mode by Toshiba(1998-1-16)	if( m_volmd.bDataPartitioning ) {		if (m_volmd.fAUsage == RECTANGLE) {			switch( m_vopmd.vopPredType ) {			case PVOP:				encodeNSForPVOP_DP ();				break;			case IVOP:				encodeNSForIVOP_DP ();				break;			case BVOP:				encodeNSForBVOP ();				break;			default:					assert(FALSE);			// B-VOP and Sprite-VOP are not supported in DP-mode			}		} else {			switch( m_vopmd.vopPredType ) {			case PVOP:				encodeNSForPVOP_WithShape_DP ();				break;			case IVOP:				encodeNSForIVOP_WithShape_DP ();				break;			case BVOP:				encodeNSForBVOP_WithShape ();				break;			default:				assert(FALSE);			// B-VOP and Sprite-VOP are not supported in DP-mode			}		}	} else// End Toshiba(1998-1-16)	if (m_volmd.fAUsage == RECTANGLE) {		if (m_vopmd.vopPredType == PVOP)			encodeNSForPVOP ();		else if (m_vopmd.vopPredType == IVOP)			encodeNSForIVOP ();		else			encodeNSForBVOP ();	}	else {		if (m_vopmd.vopPredType == PVOP)	{			if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE && m_vopmd.SpriteXmitMode != STOP)				encodeNSForPVOP ();			else				encodeNSForPVOP_WithShape ();		}		else if (m_vopmd.vopPredType == IVOP)			encodeNSForIVOP_WithShape ();		else			encodeNSForBVOP_WithShape ();	}	if (m_uiRateControl>=RC_TM5) {		m_tm5rc.tm5rc_update_pict(m_vopmd.vopPredType, m_statsVOP.total());	}}//// size://		m_pvopcCurr: original size (QCIF or CIF), same memory through out the session// 		m_pvopfRef: expanded original size (QCIF or CIF expanded by 16), same memory through out the session//		pmbmd and pmv: VOP.  need to reallocate every time//// things don't need to recompute://		m_iWidthY, m_iWidthUV, m_iWidthRefY, m_iWidthRefUV// need to recompute://		m_uintNumMBX, m_uintNumMBY, m_uintNumMB//Void CVideoObjectEncoder::encodeNSForIVOP ()	{	//in case the IVOP is used as an ref for direct mode	memset (m_rgmv, 0, m_iNumMB * PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));	CMBMode* pmbmd = m_rgmbmd;	Int iQPPrev = m_vopmd.intStepI;	//initialization	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 ();	// MB rate control	//Int iIndexofQ = 0;	//Int rgiQ [4] = {-1, -2, 1, 2};	if (m_uiRateControl>=RC_TM5) iQPPrev = m_tm5rc.tm5rc_start_mb();	// -----	Bool bRestartDelayedQP = TRUE;		Int iMBX, iMBY, iMB = 0;	Int iMaxQP = (1<<m_volmd.uiQuantPrecision)-1; // NBIT	for (iMBY = 0; iMBY < m_iNumMBY; iMBY++) {		PixelC* ppxlcRefMBY  = ppxlcRefY;		PixelC* ppxlcRefMBU  = ppxlcRefU;		PixelC* ppxlcRefMBV  = ppxlcRefV;		PixelC* ppxlcOrigMBY = ppxlcOrigY;		PixelC* ppxlcOrigMBU = ppxlcOrigU;		PixelC* ppxlcOrigMBV = ppxlcOrigV;		// 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)		//low latency				goto EOMB1;#ifdef __TRACE_AND_STATS_			m_statsMB.reset ();			m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y");#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_			iIndexofQ = (iIndexofQ + 1) % 4;			pmbmd->m_intStepDelta = rgiQ [iIndexofQ];#endif //_MBQP_CHANGE_			pmbmd->m_bSkip = FALSE;			//reset for direct mode			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) { // modified by Sharp (98/4/13)				Int iCounter = m_pbitstrmOut -> getCounter();				if( iCounter - m_iVPCounter > m_volmd.bVPBitTh ) {					pmbmd->m_intStepDelta = 0;	// reset DQ to use QP in VP header					codeVideoPacketHeader (iMBX, iMBY, pmbmd->m_stepSize);	// video packet header					m_iVPCounter = iCounter;					bRestartDelayedQP = TRUE;				}			}// End Toshiba(1998-1-16)			if(bRestartDelayedQP)			{				pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;				bRestartDelayedQP = FALSE;			}			else				pmbmd->m_stepSizeDelayed = iQPPrev;			iQPPrev = pmbmd->m_stepSize;			if (pmbmd->m_intStepDelta == 0)				pmbmd->m_dctMd = INTRA;			else				pmbmd->m_dctMd = INTRAQ;			pmbmd->m_bFieldMV = 0;			copyToCurrBuff (ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, m_iFrameWidthY, m_iFrameWidthUV); 			quantizeTextureIntraMB (iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, NULL);			codeMBTextureHeadOfIVOP (pmbmd);			sendDCTCoefOfIntraMBTexture (pmbmd);EOMB1:			pmbmd++;#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;			if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE)	{				bSptMB_NOT_HOLE = SptPieceMB_NOT_HOLE(iMBX+1, iMBY, pmbmd);				m_iNumSptMB++ ;			}		}				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;		ppxlcRefU  += m_iFrameWidthUVxBlkSize;		ppxlcRefV  += m_iFrameWidthUVxBlkSize;		ppxlcOrigY += m_iFrameWidthYxMBSize;		ppxlcOrigU += m_iFrameWidthUVxBlkSize;		ppxlcOrigV += m_iFrameWidthUVxBlkSize;	}}Void CVideoObjectEncoder::encodeNSForIVOP_WithShape (){	//in case the IVOP is used as an ref for direct mode	memset (m_rgmv, 0, m_iNumMB * PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));	memset (m_rgmvBY, 0, m_iNumMB * sizeof (CMotionVector));	Int iMBX, iMBY, iMB = 0;	Int iMaxQP = (1<<m_volmd.uiQuantPrecision)-1; // NBIT	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.intStepI;	//initialization	Int iQPPrevAlpha = m_vopmd.intStepIAlpha;	if (m_uiRateControl>=RC_TM5) iQPPrev = m_tm5rc.tm5rc_start_mb();	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* ppxlcRefBUV = (PixelC*) m_pvopcRefQ1->pixelsBUV () + m_iStartInRefToCurrRctUV;	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;	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);

⌨️ 快捷键说明

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