📄 errdec.cpp
字号:
/*************************************************************************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_FILEstatic 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 shapeInt 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;}#elseInt CVideoObjectDecoder::decodeVideoPacketHeader(Int& iCurrentQP){ UInt uiHEC = 0; 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 = wmay */ 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 = wmay */ m_pbitstrmIn -> getBits (NUMBITS_VOP_WIDTH); Int marker; marker = m_pbitstrmIn -> getBits (1); // marker bit assert(marker==1); /* Int height = wmay */ 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 = wmay */ 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;}#endifInt 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 + -