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

📄 shpenc.cpp

📁 《Visual C++小波变换技术与工程实践》靳济芳编著的光盘程序。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************

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)

and also edited by 
	Takefumi Nagumo  (nagumo@av.crl.sony.co.jp) Sony Corporation
    Sehoon Son (shson@unitel.co.kr) Samsung AIT

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:
	Feb.01	2000: Bug fixed OBSS by Takefumi Nagumo (SONY)

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

#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"
#include "dct.hpp"  // HHI Schueuer: inserted for deriveSADCTRowLengths

//OBSS_SAIT_991015
#include <math.h>				
#define SIGN(n)	(n>0)?1:((n<0)?-1:0)		
//~OBSS_SAIT_991015

#ifdef __MFC_
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

#define new DEBUG_NEW				   
#endif // __MFC_

// HHI Schueuer: inserted for SADCT 
Void CVideoObjectEncoder::deriveSADCTRowLengths(Int **piCoeffWidths, const PixelC* ppxlcMBBY, const PixelC* ppxlcCurrMBBUV, 
												const TransparentStatus *pTransparentStatus)
{
	CFwdSADCT *pfdct = (CFwdSADCT *)m_pfdct;
	const PixelC *pSrc;
    
	for (int i=Y_BLOCK1; i<U_BLOCK; i++) {
		if (pTransparentStatus[i] != PARTIAL) {
        	memset(piCoeffWidths[i], 0, BLOCK_SIZE * sizeof(piCoeffWidths[i][0]));
			continue;
		}
		switch (i) {
		case Y_BLOCK1: 
			pSrc = ppxlcMBBY;
			break;
		case Y_BLOCK2:	
			pSrc = ppxlcMBBY + BLOCK_SIZE;
			break;
		case Y_BLOCK3:
			pSrc = ppxlcMBBY + BLOCK_SIZE*MB_SIZE;
			break;
		case Y_BLOCK4:
			pSrc = ppxlcMBBY + BLOCK_SIZE*MB_SIZE + BLOCK_SIZE;
			break;
		}

		pfdct->getRowLength(piCoeffWidths[i], pSrc, MB_SIZE);
#ifdef _DEBUG
		for (int iy=0; iy<BLOCK_SIZE; iy++) {
        	int l = *(piCoeffWidths[i] + iy);
        	assert(l>=0 && l<=BLOCK_SIZE); 
		}
#endif		
	}
    if (pTransparentStatus[U_BLOCK] == PARTIAL) {
 		pfdct->getRowLength(piCoeffWidths[U_BLOCK], ppxlcCurrMBBUV, BLOCK_SIZE);    
#ifdef _DEBUG
		for (int iy=0; iy<BLOCK_SIZE; iy++) {
        	int l = *(piCoeffWidths[i] + iy);
        	assert(l>=0 && l<=BLOCK_SIZE); 
		}
#endif	 
    }
	else
    	memset(piCoeffWidths[U_BLOCK], 0, BLOCK_SIZE * sizeof(piCoeffWidths[i][0]));
      
#ifdef __TRACE_DECODING_
	m_ptrcer->dumpSADCTRowLengths(piCoeffWidths);
#endif
}
// end 

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
//OBSSFIX_MODE3 
		if( m_volmd.volType == ENHN_LAYER && m_volmd.bSpatialScalability == 1 && m_volmd.iHierarchyType == 0 &&
			m_volmd.iEnhnType != 0 && m_volmd.iuseRefShape == 1 && m_vopmd.vopPredType == PVOP){
			//Set predictor of Shape coding of OBSS (simulcast shape case)
            mvShapeMVP.setToZero();
			memset((void *)m_puciPredBAB->pixels(),255, MC_BAB_SIZE*MC_BAB_SIZE);
		}else{
			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
		}
//		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
//~OBSSFIX_MODE3
		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;
//OBSSFIX_MODE3
			if(m_volmd.volType == ENHN_LAYER && m_volmd.bSpatialScalability == 1 && m_volmd.iHierarchyType == 0 &&
			   m_volmd.iEnhnType != 0 && m_volmd.iuseRefShape == 1 && m_vopmd.vopPredType == PVOP){
               mvShapeMVP.setToZero();
               memset((void *)m_puciPredBAB->pixels(),255, MC_BAB_SIZE*MC_BAB_SIZE);
            }else{  
				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
			}

//			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
//~OBSSFIX_MODE3
		}
		
		// 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_

⌨️ 快捷键说明

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