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

📄 errdec.cpp

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

This software module was originally developed by 

	Yoshihiro Kikuchi (TOSHIBA CORPORATION)
	Takeshi Nagai (TOSHIBA CORPORATION)

    and edited by:

	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
  (ISO/IEC 14496-2)> tools as specified by the <MPEG-4 Video(ISO/IEC 14496-2)
  >. ISO/IEC gives users of the <MPEG-4 Video(ISO/IEC 14496-2)> free license
  to this software module or modifications thereof for use in hardware or
  software products claiming conformance to the <MPEG-4 Video(ISO/IEC 14496-2
  )>. 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(ISO/IEC 14496-2)>
  conforming products. TOSHIBA CORPORATION 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-4 Video(ISO/IEC
  14496-2)> conforming products. This copyright notice must be included in
  all copies or derivative works.
  Copyright (c)1997.

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

// Added for error resilience mode By Toshiba
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#include "typeapi.h"
#include "mode.hpp"
#include "codehead.h"
#include "entropy/bitstrm.hpp"
#include "entropy/entropy.hpp"
#include "entropy/huffman.hpp"
#include "global.hpp"
#include "vopses.hpp"
#include "vopsedec.hpp"

#include "dct.hpp"

#ifdef __MFC_
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW				   
#endif // __MFC_

Bool CVideoObjectDecoder::checkResyncMarker()
{
	Int nBitsPeeked;
	Int iStuffedBits = m_pbitstrmIn->peekBitsTillByteAlign (nBitsPeeked);
	Int nBitsResyncMarker = NUMBITS_VP_RESYNC_MARKER;
	if(m_volmd.bShapeOnly==FALSE)
	{
		if(m_vopmd.vopPredType == PVOP)
			nBitsResyncMarker += (m_vopmd.mvInfoForward.uiFCode - 1);
		else if(m_vopmd.vopPredType == BVOP)
			nBitsResyncMarker += max(m_vopmd.mvInfoForward.uiFCode, m_vopmd.mvInfoBackward.uiFCode) - 1;
	}
		
	assert (nBitsPeeked > 0 && nBitsPeeked <= 8);
	if (iStuffedBits == ((1 << (nBitsPeeked - 1)) - 1))
		return (m_pbitstrmIn->peekBitsFromByteAlign (nBitsResyncMarker) == RESYNC_MARKER);
	return FALSE;
}

#if 0 // revised HEC for shape
Int	CVideoObjectDecoder::decodeVideoPacketHeader(Int& iCurrentQP)
{
	m_pbitstrmIn -> flush(8);

	Int nBitsResyncMarker = NUMBITS_VP_RESYNC_MARKER;
	if(m_volmd.bShapeOnly==FALSE)
	{
		if(m_vopmd.vopPredType == PVOP)
			nBitsResyncMarker += (m_vopmd.mvInfoForward.uiFCode - 1);
		else if(m_vopmd.vopPredType == BVOP)
			nBitsResyncMarker += max(m_vopmd.mvInfoForward.uiFCode, m_vopmd.mvInfoBackward.uiFCode) - 1;
	}

	UInt uiResyncMarker = m_pbitstrmIn -> getBits (nBitsResyncMarker);

	Int	NumOfMB = m_iNumMBX * m_iNumMBY;
	assert (NumOfMB>0);

	//Int LengthOfMBNumber = (Int)(log(NumOfMB-1)/log(2)) + 1;

	Int iVal = NumOfMB - 1;
	Int iLengthOfMBNumber = 0;
	for(; iVal; iLengthOfMBNumber++)
		iVal>>=1;

	UInt uiMBNumber = 0;
	
	if(NumOfMB>1)
		uiMBNumber = m_pbitstrmIn -> getBits (iLengthOfMBNumber);
	
	m_iVPMBnum = uiMBNumber;
	if(m_volmd.bShapeOnly==FALSE) {
		Int stepDecoded = m_pbitstrmIn -> getBits (NUMBITS_VP_QUANTIZER);
		iCurrentQP = stepDecoded; 
	}

	UInt uiHEC = m_pbitstrmIn -> getBits (NUMBITS_VP_HEC);
	if (uiHEC){

		// Time reference and VOP_pred_type
		Int iModuloInc = 0;
		while (m_pbitstrmIn -> getBits (1) != 0)
			iModuloInc++;
		Time tCurrSec = iModuloInc + (m_vopmd.vopPredType != BVOP ? m_tOldModuloBaseDecd : m_tOldModuloBaseDisp);
		UInt uiMarker = m_pbitstrmIn -> getBits (1);
		assert(uiMarker == 1);
		Time tVopIncr = m_pbitstrmIn -> getBits (m_iNumBitsTimeIncr);
		uiMarker = m_pbitstrmIn -> getBits (1);
		assert(uiMarker == 1);
		// this is bogus - swinder.
		//assert (m_t == tCurrSec * 60 + tVopIncr * 60 / m_volmd.iClockRate); //in terms of 60Hz clock ticks

		VOPpredType vopPredType = (VOPpredType) m_pbitstrmIn -> getBits (NUMBITS_VP_PRED_TYPE);
		assert(m_vopmd.vopPredType == vopPredType);

		if(m_volmd.bShapeOnly==FALSE) {
			Int	iIntraDcSwitchThr = m_pbitstrmIn->getBits (NUMBITS_VP_INTRA_DC_SWITCH_THR);
			assert(m_vopmd.iIntraDcSwitchThr == iIntraDcSwitchThr);
			if (m_vopmd.vopPredType == PVOP) {
				UInt uiFCode = m_pbitstrmIn -> getBits (NUMBITS_VOP_FCODE);
				assert(uiFCode == m_vopmd.mvInfoForward.uiFCode);
			}
			else if (m_vopmd.vopPredType == BVOP) {
				UInt uiForwardFCode = m_pbitstrmIn -> getBits (NUMBITS_VOP_FCODE);
				UInt uiBackwardFCode = m_pbitstrmIn -> getBits (NUMBITS_VOP_FCODE);
				assert(uiForwardFCode == m_vopmd.mvInfoForward.uiFCode);
				assert(uiBackwardFCode == m_vopmd.mvInfoBackward.uiFCode);
			}
		}
	}
	return	TRUE;
}
#else
Int	CVideoObjectDecoder::decodeVideoPacketHeader(Int& iCurrentQP)
{
	UInt uiHEC;
	m_pbitstrmIn -> flush(8);

	Int nBitsResyncMarker = NUMBITS_VP_RESYNC_MARKER;
	if(m_volmd.bShapeOnly==FALSE)
	{
		if(m_vopmd.vopPredType == PVOP)
			nBitsResyncMarker += (m_vopmd.mvInfoForward.uiFCode - 1);
		else if(m_vopmd.vopPredType == BVOP)
			nBitsResyncMarker += max(m_vopmd.mvInfoForward.uiFCode, m_vopmd.mvInfoBackward.uiFCode) - 1;
	}

	UInt uiResyncMarker = m_pbitstrmIn -> getBits (nBitsResyncMarker);

	Int	NumOfMB = m_iNumMBX * m_iNumMBY;
	assert (NumOfMB>0);

	//Int LengthOfMBNumber = (Int)(log(NumOfMB-1)/log(2)) + 1;

	Int iVal = NumOfMB - 1;
	Int iLengthOfMBNumber = 0;
	for(; iVal; iLengthOfMBNumber++)
		iVal>>=1;

	UInt uiMBNumber = 0;
	
	if (m_volmd.fAUsage != RECTANGLE) {
		uiHEC = m_pbitstrmIn -> getBits (NUMBITS_VP_HEC);
	  if (uiHEC && !(m_uiSprite == 1 && m_vopmd.vopPredType == IVOP)) {
		Int width = m_pbitstrmIn -> getBits (NUMBITS_VOP_WIDTH);
		Int marker;
		marker = m_pbitstrmIn -> getBits (1); // marker bit
		assert(marker==1);
		Int height = m_pbitstrmIn -> getBits (NUMBITS_VOP_HEIGHT);
		marker = m_pbitstrmIn -> getBits (1); // marker bit
		assert(marker==1);
		//wchen: cd changed to 2s complement
		Int left = (m_pbitstrmIn -> getBits (1) == 0) ?
					m_pbitstrmIn->getBits (NUMBITS_VOP_HORIZONTAL_SPA_REF - 1) : 
					((Int)m_pbitstrmIn->getBits (NUMBITS_VOP_HORIZONTAL_SPA_REF - 1) - (1 << (NUMBITS_VOP_HORIZONTAL_SPA_REF - 1)));
		marker = m_pbitstrmIn -> getBits (1); // marker bit
		assert(marker==1);
		Int top = (m_pbitstrmIn -> getBits (1) == 0) ?
				   m_pbitstrmIn->getBits (NUMBITS_VOP_VERTICAL_SPA_REF - 1) : 
				   ((Int)m_pbitstrmIn->getBits (NUMBITS_VOP_VERTICAL_SPA_REF - 1) - (1 << (NUMBITS_VOP_VERTICAL_SPA_REF - 1)));
		marker = m_pbitstrmIn -> getBits (1); // marker bit
		assert(marker==1);
		assert(((left | top)&1)==0); // must be even pix unit
	  }
	}

	if(NumOfMB>1)
		uiMBNumber = m_pbitstrmIn -> getBits (iLengthOfMBNumber);
	
	m_iVPMBnum = uiMBNumber;
	if(m_volmd.bShapeOnly==FALSE) {
		Int stepDecoded = m_pbitstrmIn -> getBits (NUMBITS_VP_QUANTIZER);
		iCurrentQP = stepDecoded; 
	}

	if (m_volmd.fAUsage == RECTANGLE)
		uiHEC = m_pbitstrmIn -> getBits (NUMBITS_VP_HEC);
		
	if (uiHEC){

		// Time reference and VOP_pred_type
		Int iModuloInc = 0;
		while (m_pbitstrmIn -> getBits (1) != 0)
			iModuloInc++;
		Time tCurrSec = iModuloInc + (m_vopmd.vopPredType != BVOP ? m_tOldModuloBaseDecd : m_tOldModuloBaseDisp);
		UInt uiMarker = m_pbitstrmIn -> getBits (1);
		assert(uiMarker == 1);
		Time tVopIncr = m_pbitstrmIn -> getBits (m_iNumBitsTimeIncr);
		uiMarker = m_pbitstrmIn -> getBits (1);
		assert(uiMarker == 1);
		// this is bogus - swinder.
		//assert (m_t == tCurrSec * 60 + tVopIncr * 60 / m_volmd.iClockRate); //in terms of 60Hz clock ticks

		VOPpredType vopPredType = (VOPpredType) m_pbitstrmIn -> getBits (NUMBITS_VP_PRED_TYPE);
		assert(m_vopmd.vopPredType == vopPredType);

		if (m_volmd.fAUsage != RECTANGLE) {
			m_volmd.bNoCrChange = m_pbitstrmIn -> getBits (1);	//VOP_CR_Change_Disable
	        if (m_volmd.bShapeOnly==FALSE && m_vopmd.vopPredType != IVOP)
			{	
				m_vopmd.bShapeCodingType = m_pbitstrmIn -> getBits (1);
        	}
		}

		if(m_volmd.bShapeOnly==FALSE) {
			Int	iIntraDcSwitchThr = m_pbitstrmIn->getBits (NUMBITS_VP_INTRA_DC_SWITCH_THR);
			assert(m_vopmd.iIntraDcSwitchThr == iIntraDcSwitchThr);
			if (m_vopmd.vopPredType == PVOP) {
				UInt uiFCode = m_pbitstrmIn -> getBits (NUMBITS_VOP_FCODE);
				assert(uiFCode == m_vopmd.mvInfoForward.uiFCode);
			}
			else if (m_vopmd.vopPredType == BVOP) {
				UInt uiForwardFCode = m_pbitstrmIn -> getBits (NUMBITS_VOP_FCODE);
				UInt uiBackwardFCode = m_pbitstrmIn -> getBits (NUMBITS_VOP_FCODE);
				assert(uiForwardFCode == m_vopmd.mvInfoForward.uiFCode);
				assert(uiBackwardFCode == m_vopmd.mvInfoBackward.uiFCode);
			}
		}
	}
	return	TRUE;
}
#endif

Int	CVideoObjectDecoder::checkMotionMarker()
{
	return (m_pbitstrmIn -> peekBits (NUMBITS_DP_MOTION_MARKER) == MOTION_MARKER);
}
Int	CVideoObjectDecoder::checkDCMarker()
{
	return (m_pbitstrmIn -> peekBits (NUMBITS_DP_DC_MARKER) == DC_MARKER);
}

Void CVideoObjectDecoder::decodeIVOP_DataPartitioning ()	
{
//	assert (m_volmd.nBits==8);
	//in case the IVOP is used as an ref for direct mode
// bug fix by toshiba 98-9-24 start
//	memset (m_rgmv, 0, m_iNumMB * 5 * sizeof (CMotionVector));
	memset (m_rgmv, 0, m_iNumMB * PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
// bug fix by toshiba 98-9-24 end

	Int iMBX=0, iMBY=0;
	CMBMode* pmbmd = m_rgmbmd;
	pmbmd->m_stepSize = m_vopmd.intStepI;
	PixelC* ppxlcRefY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY;
	PixelC* ppxlcRefU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV;
	PixelC* ppxlcRefV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV;

	Int iCurrentQP  = m_vopmd.intStepI;		
	Int	iVideoPacketNumber = 0;
	m_iVPMBnum = 0;

	m_piMCBPC = new Int[m_iNumMBX*m_iNumMBY];
	Int*	piMCBPC = m_piMCBPC;
	m_piIntraDC = new Int[m_iNumMBX*m_iNumMBY*V_BLOCK];
	Int*	piIntraDC = m_piIntraDC;

	Int	i;
	Int	mbn = 0, mbnFirst = 0;
	Bool bRestartDelayedQP = TRUE;

	do{
		if( checkResyncMarker() ){
			decodeVideoPacketHeader(iCurrentQP);
			iVideoPacketNumber++;
			bRestartDelayedQP = TRUE;
		}

		CMBMode* pmbmdFirst = pmbmd;
		Int* piMCBPCFirst = piMCBPC;
		Int* piIntraDCFirst = piIntraDC;
		mbnFirst = mbn;
		do{
			pmbmd->m_iVideoPacketNumber = iVideoPacketNumber;

			*piMCBPC = m_pentrdecSet->m_pentrdecMCBPCintra->decodeSymbol ();
			assert (*piMCBPC >= 0 && *piMCBPC <= 7);			
			pmbmd->m_dctMd = INTRA;
			if (*piMCBPC > 3)
				pmbmd->m_dctMd = INTRAQ;
			decodeMBTextureDCOfIVOP_DataPartitioning (pmbmd, iCurrentQP, piIntraDC, bRestartDelayedQP);
			pmbmd++;
			mbn++;
			piMCBPC++;
			piIntraDC+=V_BLOCK;
		} while( !checkDCMarker() );
		m_pbitstrmIn -> getBits (NUMBITS_DP_DC_MARKER);

		pmbmd = pmbmdFirst;
		piMCBPC = piMCBPCFirst;
		for(i=mbnFirst;i<mbn;i++) {
			decodeMBTextureHeadOfIVOP_DataPartitioning (pmbmd, piMCBPC);
			pmbmd++;
			piMCBPC++;
		}

		pmbmd = pmbmdFirst;
		piIntraDC = piIntraDCFirst;
		ppxlcRefY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY + (mbnFirst/m_iNumMBX)*m_iFrameWidthYxMBSize;
		ppxlcRefU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV + (mbnFirst/m_iNumMBX)*m_iFrameWidthUVxBlkSize;
		ppxlcRefV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV + (mbnFirst/m_iNumMBX)*m_iFrameWidthUVxBlkSize;
		PixelC* ppxlcRefMBY = ppxlcRefY + (mbnFirst%m_iNumMBX)*MB_SIZE;
		PixelC* ppxlcRefMBU = ppxlcRefU + (mbnFirst%m_iNumMBX)*BLOCK_SIZE;
		PixelC* ppxlcRefMBV = ppxlcRefV + (mbnFirst%m_iNumMBX)*BLOCK_SIZE;
		for(i=mbnFirst;i<mbn;i++) {
			iMBX = i % m_iNumMBX;
			iMBY = i / m_iNumMBX;
			if(iMBX == 0 ) {
				ppxlcRefMBY = ppxlcRefY;
				ppxlcRefMBU = ppxlcRefU;
				ppxlcRefMBV = ppxlcRefV;
			}

			decodeTextureIntraMB_DataPartitioning (pmbmd, iMBX, iMBY, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, piIntraDC);

			pmbmd++;
			piIntraDC += V_BLOCK;
			ppxlcRefMBY += MB_SIZE;
			ppxlcRefMBU += BLOCK_SIZE;
			ppxlcRefMBV += BLOCK_SIZE;
			if(iMBX == m_iNumMBX - 1) {
				MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove;
				m_rgpmbmAbove = m_rgpmbmCurr;
				m_rgpmbmCurr  = ppmbmTemp;
				ppxlcRefY += m_iFrameWidthYxMBSize;
				ppxlcRefU += m_iFrameWidthUVxBlkSize;
				ppxlcRefV += m_iFrameWidthUVxBlkSize;
			}
		}
	} while( checkResyncMarker() );
	delete m_piMCBPC;
}

Void CVideoObjectDecoder::decodeMBTextureDCOfIVOP_DataPartitioning (CMBMode* pmbmd, Int& iCurrentQP,
																	Int* piIntraDC, Bool &bUseNewQPForVlcThr)
{
	Int iBlk = 0;
	pmbmd->m_stepSize = iCurrentQP;
	pmbmd->m_stepSizeDelayed = iCurrentQP;
	if (pmbmd->m_dctMd == INTRAQ)	{
		Int iDQUANT = m_pbitstrmIn->getBits (2);
		switch (iDQUANT) {
		case 0:
			pmbmd->m_intStepDelta = -1;
			break;

⌨️ 快捷键说明

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