📄 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) and also edited by: Yoshinori Suzuki (Hitachi, Ltd.) and also edited by: Hideaki Kimata (NTT)and also edited by Fujitsu Laboratories Ltd. (contact: Eishi Morimatsu) 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.Module Name: errdec.cppRevision History: Sep.06 1999 : RRV added by Eishi Morimatsu (Fujitsu Laboratories Ltd.) Mar.13 2000 : MB stuffing decoding added by Hideaki Kimata (NTT) May.25 2000 : MB stuffing decoding on the last MB by Hideaki Kimata (NTT)*************************************************************************/// 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"// NEWPRED#include "newpred.hpp"// ~NEWPRED// RRV insertion#include "rrv.hpp"// ~RRV#ifdef __MFC_#ifdef _DEBUG#undef THIS_FILEstatic char BASED_CODE THIS_FILE[] = __FILE__;#endif#define new DEBUG_NEW #endif // __MFC_Bool CVideoObjectDecoder::checkResyncMarker(){ if(short_video_header) return FALSE; // added by swinder Int nBitsPeeked; Int iStuffedBits = m_pbitstrmIn->peekBitsTillByteAlign (nBitsPeeked); Int nBitsResyncMarker = NUMBITS_VP_RESYNC_MARKER; if(m_volmd.bShapeOnly==FALSE) { if(m_vopmd.vopPredType == PVOP || (m_uiSprite == 2 && m_vopmd.vopPredType == SPRITE)) // GMC 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;}// May.25 2000 for MB stuffing decoding on the last MBBool CVideoObjectDecoder::checkStartCode(){ Int nBitsPeeked; Int iStuffedBits = m_pbitstrmIn->peekBitsTillByteAlign (nBitsPeeked); assert (nBitsPeeked > 0 && nBitsPeeked <= 8); if (iStuffedBits == ((1 << (nBitsPeeked - 1)) - 1)) return (m_pbitstrmIn->peekBitsFromByteAlign (NUMBITS_START_CODE_PREFIX) == START_CODE_PREFIX); return FALSE;}// ~May.25 2000 for MB stuffing decoding on the last MBInt 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 || (m_uiSprite == 2 && m_vopmd.vopPredType == SPRITE)) // GMC_V2 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);// RRV modification Int NumOfMB = m_iNumMBX * m_iNumMBY *m_iRRVScale *m_iRRVScale;// Int NumOfMB = m_iNumMBX * m_iNumMBY;// ~RRV 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 = 0; if(m_iNumBitsTimeIncr!=0) 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);// GMC_V2 if (m_uiSprite == 2 && m_vopmd.vopPredType == SPRITE && m_iNumOfPnts > 0) decodeWarpPoints ();// ~GMC_V2// RRV insertion if((m_volmd.breduced_resolution_vop_enable == 1)&&(m_volmd.fAUsage == RECTANGLE)&& ((m_vopmd.vopPredType == PVOP)||(m_vopmd.vopPredType == IVOP))) { UInt uiVOP_RR = m_pbitstrmIn -> getBits (1); assert(uiVOP_RR == (UInt)m_vopmd.RRVmode.iRRVOnOff); } // ~RRV if (m_vopmd.vopPredType == PVOP || (m_uiSprite == 2 && m_vopmd.vopPredType == SPRITE)) { // GMC_V2 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); } } }// NEWPRED if (m_volmd.bNewpredEnable) { m_vopmd.m_iVopID = m_pbitstrmIn -> getBits(m_vopmd.m_iNumBitsVopID); m_vopmd.m_iVopID4Prediction_Indication = m_pbitstrmIn -> getBits(NUMBITS_VOP_ID_FOR_PREDICTION_INDICATION); if( m_vopmd.m_iVopID4Prediction_Indication ) m_vopmd.m_iVopID4Prediction = m_pbitstrmIn -> getBits(m_vopmd.m_iNumBitsVopID); m_pbitstrmIn -> getBits(MARKER_BIT); g_pNewPredDec->GetRef( NP_VP_HEADER, m_vopmd.vopPredType, m_vopmd.m_iVopID, m_vopmd.m_iVopID4Prediction_Indication, m_vopmd.m_iVopID4Prediction ); }// ~NEWPRED return TRUE;}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 () { char pSlicePoint[128]; pSlicePoint[0] = '0'; pSlicePoint[1] = '0'; //NULL; memset (m_rgmv, 0, m_iNumMB * PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector)); Int iMBX=0, iMBY=0; CMBMode* pmbmd = m_rgmbmd; 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+1]; 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; //printf("VP"); if (m_volmd.bNewpredEnable) { if (m_volmd.bNewpredSegmentType == 0) if(m_iRRVScale == 2) { Int iMBX_t = mbn % m_iNumMBX; Int iMBY_t = mbn / m_iNumMBX; Int i_mbn = (iMBY_t *m_iRRVScale) *(m_iNumMBX *m_iRRVScale) + (iMBX_t *m_iRRVScale); sprintf(pSlicePoint, "%s,%d",pSlicePoint, i_mbn); // set slice number } else { sprintf(pSlicePoint, "%s,%d",pSlicePoint, mbn); // set slice number } else pSlicePoint[0] = '1'; } } 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 <= 8); if (*piMCBPC == 8) { if( checkDCMarker() ) break; continue; } pmbmd->m_dctMd = INTRA; if (*piMCBPC > 3) pmbmd->m_dctMd = INTRAQ; decodeMBTextureDCOfIVOP_DataPartitioning (pmbmd, iCurrentQP, piIntraDC, &bRestartDelayedQP); //printf("(%d:%d:%d)", *piMCBPC, pmbmd->m_bCodeDcAsAc, iCurrentQP); 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;// RRV modification PixelC* ppxlcRefMBY = ppxlcRefY + (mbnFirst%m_iNumMBX)*(MB_SIZE *m_iRRVScale); PixelC* ppxlcRefMBU = ppxlcRefU + (mbnFirst%m_iNumMBX)*(BLOCK_SIZE *m_iRRVScale); PixelC* ppxlcRefMBV = ppxlcRefV + (mbnFirst%m_iNumMBX)*(BLOCK_SIZE *m_iRRVScale);// ~RRV 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;// RRV modification ppxlcRefMBY += (MB_SIZE *m_iRRVScale); ppxlcRefMBU += (BLOCK_SIZE *m_iRRVScale); ppxlcRefMBV += (BLOCK_SIZE *m_iRRVScale);// ~RRV 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() ); // RRV insertion if(m_vopmd.RRVmode.iRRVOnOff == 1) { PixelC* ppxlcCurrQY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY; PixelC* ppxlcCurrQU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV; PixelC* ppxlcCurrQV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV; filterCodedPictureForRRV(ppxlcCurrQY, ppxlcCurrQU, ppxlcCurrQV, m_iVOPWidthY, m_rctCurrVOPY.height(), m_iNumMBX, m_iNumMBY, m_pvopcRefQ0->whereY ().width, m_pvopcRefQ0->whereUV ().width); }// ~RRV// NEWPRED if (m_volmd.bNewpredEnable) { int iCurrentVOP_id = g_pNewPredDec->GetCurrentVOP_id(); // temporarily store Vop_id from old NEWPRED object if (g_pNewPredDec != NULL) delete g_pNewPredDec; // delete old NEWPRED object g_pNewPredDec = new CNewPredDecoder(); // make new NEWPRED object g_pNewPredDec->SetObject( m_iNumBitsTimeIncr,// RRV modification m_iNumMBX*MB_SIZE *m_iRRVScale, m_iNumMBY*MB_SIZE *m_iRRVScale,// ~RRV pSlicePoint, m_volmd.bNewpredSegmentType, m_volmd.fAUsage, m_volmd.bShapeOnly, m_pvopcRefQ0, m_pvopcRefQ1, m_rctRefFrameY, m_rctRefFrameUV ); g_pNewPredDec->ResetObject(iCurrentVOP_id); // restore Vop_id in new NEWPRED object Int i; Int noStore_vop_id; // stored Vop_id // set NEWPRED reference picture memory g_pNewPredDec->SetQBuf( m_pvopcRefQ0, m_pvopcRefQ1 ); // store decoded picture in NEWPRED reference picture memory for (i=0; i < g_pNewPredDec->m_iNumSlice; i++ ) { noStore_vop_id = g_pNewPredDec->make_next_decbuf(g_pNewPredDec->m_pNewPredControl, g_pNewPredDec->GetCurrentVOP_id(), i); } }// ~NEWPRED delete m_piMCBPC; delete m_piIntraDC;}Void CVideoObjectDecoder::decodePVOP_DataPartitioning (){ Int iMBX, iMBY; CMBMode* pmbmd = m_rgmbmd; CMotionVector* pmv = m_rgmv; PixelC* ppxlcCurrQY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY; PixelC* ppxlcCurrQU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV; PixelC* ppxlcCurrQV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV; Int iCurrentQP = m_vopmd.intStep; Int iVideoPacketNumber = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -