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

📄 shpenc.cpp

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

This software module was originally developed by 

	Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
	(April, 1997)
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:

	shpenc.hpp

Abstract:

	binary shape encoder with context-based arithmatic coder

Revision History:

*************************************************************************/

#include "typeapi.h"
#include "entropy/entropy.hpp"
#include "entropy/huffman.hpp"
#include "entropy/bitstrm.hpp"
#include "global.hpp"
#include "mode.hpp"
#include "codehead.h"
#include "cae.h"
#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_

Int CVideoObjectEncoder::codeIntraShape (PixelC* ppxlcSrcFrm, CMBMode* pmbmd, Int iMBX, Int iMBY)
{
	m_iInverseCR = 1;
	m_iWidthCurrBAB = BAB_SIZE;

#ifdef __TRACE_AND_STATS_

	if(pmbmd->m_rgTranspStatus [0] == NONE)
		m_pbitstrmOut->trace ("ORIGINAL BAB IS ALL OPAQUE");
	else if(pmbmd->m_rgTranspStatus [0] == ALL)
		m_pbitstrmOut->trace ("ORIGINAL BAB IS ALL TRANSP");
	else
		m_pbitstrmOut->trace (m_ppxlcCurrMBBY, MB_SIZE, MB_SIZE, "ORIGINAL_BAB");
#endif // __TRACE_AND_STATS_

		Int iMBnum = VPMBnum(iMBX, iMBY);
		m_bVPNoLeft = bVPNoLeft(iMBnum, iMBX);
		m_bVPNoTop = bVPNoTop(iMBnum);
		m_bVPNoRightTop = bVPNoRightTop(iMBnum, iMBX);
		m_bVPNoLeftTop = bVPNoLeftTop(iMBnum, iMBX);

	if (pmbmd->m_rgTranspStatus [0] == NONE)
		pmbmd->m_shpmd = ALL_OPAQUE;
	else if (pmbmd->m_rgTranspStatus [0] == ALL)
		pmbmd->m_shpmd = ALL_TRANSP;
	else if (!isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, TRANSPARENT, pmbmd))
	{
		pmbmd->m_shpmd = ALL_TRANSP;
		if ( !isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, OPAQUE, pmbmd))
		{
			// both opaque and transparent are good, so count pixels to decide
			Int i,iSum=0;
			for(i=0;i<MB_SQUARE_SIZE;i++)
				iSum+=(m_ppxlcCurrMBBY[i]>0);
			if(iSum>=(MB_SQUARE_SIZE>>1))
				pmbmd->m_shpmd = ALL_OPAQUE;
		}
	}
	else if (!isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, OPAQUE, pmbmd))
		pmbmd->m_shpmd = ALL_OPAQUE;
	else
		pmbmd->m_shpmd = round (ppxlcSrcFrm, pmbmd);

	if(pmbmd->m_shpmd==ALL_TRANSP)
	{
#ifdef __TRACE_AND_STATS_
		m_pbitstrmOut->trace ("MB_ALL_TRANSP");
#endif // __TRACE_AND_STATS_
		copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, TRANSPARENT);					
		return codeShapeModeIntra (ALL_TRANSP, pmbmd, iMBX, iMBY);
	}
	else if(pmbmd->m_shpmd==ALL_OPAQUE)
	{
#ifdef __TRACE_AND_STATS_
		m_pbitstrmOut->trace ("MB_ALL_OPAQUE");
#endif // __TRACE_AND_STATS_
		copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, OPAQUE);					
		return codeShapeModeIntra (ALL_OPAQUE, pmbmd, iMBX, iMBY);
	}
	else
	{
		// intra CAE
		assert(pmbmd->m_shpmd == INTRA_CAE);
#ifdef __TRACE_AND_STATS_
		m_pbitstrmOut->trace (m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, TOTAL_BAB_SIZE, "MB_RECON_BAB (Ignore border)");
		m_pbitstrmOut->trace (m_rgpxlcCaeSymbol, m_iWidthCurrBAB , m_iWidthCurrBAB , "MB_ENCODED_BAB");
#endif // __TRACE_AND_STATS_

		if (m_bNoShapeChg)				//must be partial
			copyReconShapeToRef (ppxlcSrcFrm, m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, BAB_BORDER);
		else
			copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, BAB_BORDER);
		UInt nBitsMode = codeShapeModeIntra (INTRA_CAE, pmbmd, iMBX, iMBY);			
		m_pbitstrmShapeMBOut->setBookmark ();
		UInt nBitsV = encodeCAEIntra (INTRA_CAE, VERTICAL);
		m_pbitstrmShapeMBOut->gotoBookmark ();
		UInt nBitsH = encodeCAEIntra (INTRA_CAE, HORIZONTAL);

		if (nBitsV < nBitsH)
		{
			m_pbitstrmShapeMBOut->gotoBookmark ();
			nBitsV = encodeCAEIntra (INTRA_CAE, VERTICAL);
			return nBitsV+nBitsMode;
		}
		else
			return nBitsH+nBitsMode;
	}
}

Int CVideoObjectEncoder::codeInterShape (PixelC* ppxlcSrcFrm,
										 CVOPU8YUVBA* pvopcRefQ,
										 CMBMode* pmbmd, 
										 const ShapeMode& shpmdColocatedMB,
										 const CMotionVector* pmv, 
										 CMotionVector* pmvBY, 
										 CoordI iX, CoordI iY, 
										 Int iMBX, Int iMBY)
{
	m_iInverseCR = 1;
	m_iWidthCurrBAB = BAB_SIZE;
	pmbmd->m_shpmd = UNKNOWN;
	CMotionVector mvBYD (0, 0);
	CMotionVector mvShapeMVP;

#ifdef __TRACE_AND_STATS_
	if(pmbmd->m_rgTranspStatus [0] == NONE)
		m_pbitstrmOut->trace ("ORIGINAL BAB IS ALL OPAQUE");
	else if(pmbmd->m_rgTranspStatus [0] == ALL)
		m_pbitstrmOut->trace ("ORIGINAL BAB IS ALL TRANSP");
	else
		m_pbitstrmOut->trace (m_ppxlcCurrMBBY, MB_SIZE, MB_SIZE, "ORIGINAL_BAB");
#endif // __TRACE_AND_STATS_

	Int iMBnum = VPMBnum(iMBX, iMBY);
	m_bVPNoLeft = bVPNoLeft(iMBnum, iMBX);
	m_bVPNoTop = bVPNoTop(iMBnum);
	m_bVPNoRightTop = bVPNoRightTop(iMBnum, iMBX);
	m_bVPNoLeftTop = bVPNoLeftTop(iMBnum, iMBX);

	if (pmbmd->m_rgTranspStatus [0] == ALL)
		pmbmd->m_shpmd = ALL_TRANSP;
	else if (!isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, TRANSPARENT, pmbmd))
	{
		pmbmd->m_shpmd = ALL_TRANSP;
		if ( !isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, OPAQUE, pmbmd))
		{
			// both opaque and transparent are good, so count pixels to decide
			Int i,iSum=0;
			for(i=0;i<MB_SQUARE_SIZE;i++)
				iSum+=(m_ppxlcCurrMBBY[i]>0);
			if(iSum>=(MB_SQUARE_SIZE>>1))
				pmbmd->m_shpmd = ALL_OPAQUE;
		}
	}
	else if(pmbmd->m_rgTranspStatus [0] == NONE)
		pmbmd->m_shpmd = ALL_OPAQUE;
	else if(!isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, OPAQUE, pmbmd))
		pmbmd->m_shpmd = ALL_OPAQUE;

	if(pmbmd->m_shpmd!=ALL_TRANSP)
	{
		// find motion vectors
		mvShapeMVP = findShapeMVP (pmv, pmvBY, pmbmd, iMBX, iMBY);
		assert (mvShapeMVP.iMVX != NOT_MV && mvShapeMVP.iMVY != NOT_MV);
		//	mvShapeMVP = CMotionVector ((mvShapeMVP.iMVX * 2 + mvShapeMVP.iHalfX) / 2, 	//rounding
		//								(mvShapeMVP.iMVY * 2 + mvShapeMVP.iHalfY) / 2);	
		motionCompBY ((PixelC*) m_puciPredBAB->pixels (),
					  (PixelC*) pvopcRefQ->getPlane (BY_PLANE)->pixels (),
					  mvShapeMVP.iMVX + iX - 1,		
					  mvShapeMVP.iMVY + iY - 1);	//-1 due to 18x18 motion comp
		if (!isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16,
						  m_puciPredBAB->pixels (), m_rgiSubBlkIndx18x18, 18, pmbmd))
			// zero mvd is ok
			*pmvBY = mvShapeMVP;
		else
		{
			// do block matching
			CMotionVector mvShape;
			blkmatchForShape (pvopcRefQ,&mvShape, mvShapeMVP.trueMVHalfPel (), iX, iY);
			assert (mvShape.iMVX != NOT_MV && mvShape.iMVY != NOT_MV);
			*pmvBY = mvShape;
			mvBYD = mvShape - mvShapeMVP;
			motionCompBY ((PixelC*) m_puciPredBAB->pixels (),
						  (PixelC*) pvopcRefQ->getPlane (BY_PLANE)->pixels (),
						  mvShape.iMVX + iX - 1,
						  mvShape.iMVY + iY - 1);	//-1 due to 18x18 motion comp
		}
		
		// check status of motion compensated prediction BAB
		PixelC *ppxlcPredBAB = (PixelC *)m_puciPredBAB->pixels()+MC_BAB_SIZE*MC_BAB_BORDER;
		Int iXX,iYY,iOpaqueCount = 0;
		for(iYY=MC_BAB_BORDER;iYY<MC_BAB_SIZE-MC_BAB_BORDER;iYY++,ppxlcPredBAB+=MC_BAB_SIZE)
			for(iXX=MC_BAB_BORDER;iXX<MC_BAB_SIZE-MC_BAB_BORDER;iXX++)
				if(ppxlcPredBAB[iXX] == opaqueValue)
					iOpaqueCount++;

		if(iOpaqueCount==0 || isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16,
			m_puciPredBAB->pixels (), m_rgiSubBlkIndx18x18, 18, pmbmd))
		{
			// MC BAB is all transparent or not acceptable, so code.
			round(ppxlcSrcFrm, pmbmd);
			if(mvBYD.isZero())
				pmbmd->m_shpmd = INTER_CAE_MVDZ;
			else
				pmbmd->m_shpmd = INTER_CAE_MVDNZ;
		}
		else if(pmbmd->m_shpmd==ALL_OPAQUE && !mvBYD.isZero())
			;
		else if(pmbmd->m_rgTranspStatus[0] == NONE && iOpaqueCount!=MB_SQUARE_SIZE)
			pmbmd->m_shpmd=ALL_OPAQUE;
		else if(mvBYD.isZero())
			pmbmd->m_shpmd = MVDZ_NOUPDT;
		else
			pmbmd->m_shpmd = MVDNZ_NOUPDT;
	}

	switch(pmbmd->m_shpmd)
	{
	case ALL_OPAQUE:
#ifdef __TRACE_AND_STATS_
		m_pbitstrmOut->trace ("MB_ALL_OPAQUE");
#endif // __TRACE_AND_STATS_
		pmvBY->iMVX = NOT_MV;
		pmvBY->iMVY = NOT_MV;
		copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, OPAQUE);					
		return (codeShapeModeInter (ALL_OPAQUE, shpmdColocatedMB));

	case ALL_TRANSP:
#ifdef __TRACE_AND_STATS_
		m_pbitstrmOut->trace ("MB_ALL_TRANSP");
#endif // __TRACE_AND_STATS_
		pmvBY->iMVX = NOT_MV;
		pmvBY->iMVY = NOT_MV;
		copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, TRANSPARENT);					
		return (codeShapeModeInter (ALL_TRANSP, shpmdColocatedMB));
		
	case INTER_CAE_MVDZ:
	case INTER_CAE_MVDNZ:
		{
			if (m_bNoShapeChg)
				copyReconShapeToRef (ppxlcSrcFrm, m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, BAB_BORDER);
			else
				copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, BAB_BORDER);
#ifdef __TRACE_AND_STATS_
			m_pbitstrmOut->trace ((PixelC *)m_puciPredBAB->pixels(), MC_BAB_SIZE, MC_BAB_SIZE, "MB_MC_PRED_BAB");
			m_pbitstrmOut->trace (m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, TOTAL_BAB_SIZE, "MB_RECON_BAB (Ignore Borders)");
			m_pbitstrmOut->trace (m_rgpxlcCaeSymbol, m_iWidthCurrBAB , m_iWidthCurrBAB , "MB_ENCODED_BAB");
#endif // __TRACE_AND_STATS_

			m_pbitstrmShapeMBOut->setBookmark ();

			// try intra
			UInt nBitsModeIntra = codeShapeModeInter (INTRA_CAE, shpmdColocatedMB);
#ifdef __TRACE_AND_STATS_
			m_pbitstrmOut->trace ("MB_CAE_INTRA_HORIZONTAL_CODING (TRIAL)");
#endif // __TRACE_AND_STATS_
			UInt nBitsHIntra = encodeCAEIntra (INTRA_CAE, HORIZONTAL);
#ifdef __TRACE_AND_STATS_
			m_pbitstrmOut->trace ("MB_CAE_INTRA_VERTICAL_CODING (TRIAL)");
#endif // __TRACE_AND_STATS_
			UInt nBitsVIntra = encodeCAEIntra (INTRA_CAE, VERTICAL);
			UInt nBitsIntra = nBitsModeIntra + min (nBitsVIntra, nBitsHIntra);

			// try inter

⌨️ 快捷键说明

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