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

📄 vopmbenc.cpp

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

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 Center

and 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.cpp

Abstract:

	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_FILE
static 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, *ppxlcOrigA;
	
	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 ();
	}

⌨️ 快捷键说明

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