📄 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_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 + -