📄 blkdec.c
字号:
/*************************************************************************This software module was originally developed by Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation Bruce Lin (blin@microsoft.com), Microsoft Corporation Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation (date: July, 1997)and edited by Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Centerand also edited by Yoshihiro Kikuchi (TOSHIBA CORPORATION) Takeshi Nagai (TOSHIBA CORPORATION) Toshiaki Watanabe (TOSHIBA CORPORATION) Noboru Yamaguchi (TOSHIBA CORPORATION)and also edited by Dick van Smirren (D.vanSmirren@research.kpn.com), KPN Research Cor Quist (C.P.Quist@research.kpn.com), KPN Research (date: July, 1998)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 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: blkdec.cAbstract: Block decoding functionsRevision History Dec 20, 1977 Interlaced tools added by NextLevel Systems Sep.06 1999 : RRV added by Eishi Morimatsu (Fujitsu Laboratories Ltd.) *************************************************************************/#include <stdlib.h>#include <math.h>#include "typeapi.h"#include "codehead.h"#include "mode.h"#include "global.h"#ifdef UNDER_CE#include "bitstrm.h"#include "huffman.h"#else#include "entropy/bitstrm.h"#include "entropy/huffman.h"#endif#include "vopses.h"#include "vopsedec.h"Int* rgiZigzagIntra;// Block decoding functionsINLINE Void decideIntraPred (CMBMode*, Int *, Int, MacroBlockMemory* , MacroBlockMemory*, MacroBlockMemory*, MacroBlockMemory*, CMBMode*, CMBMode*, CMBMode*, BlockMemory*);INLINE Void decodeTextureIntraBlock (Int, Int, Int, MacroBlockMemory*, CMBMode*, BlockMemory, Int);INLINE Void decodeIntraDCmpeg (Bool bIsYBlk); //decode the intra-dc: mpeg2 methodINLINE Void decodeIntraTCOEF (Int, Int*);INLINE Void inverseDCACPred (CMBMode*, Int, Int, Int, BlockMemory, Int);INLINE Void decodeIntraVLCtableIndex (Int, Int*, Int*, Int*, Int); // return islastrun, run and levelINLINE extern Void decodeEscape (Int*, Int*, Int*, Int*, Int*, PPHUFFMAN_DEC_STRUCT, Bool);INLINE Void decodeEscape_WithFastBS (Int*, Int*, Int*, Int*, Int*, PPHUFFMAN_DEC_STRUCT, Bool, UInt, UInt *);INLINE Void decodeTextureInterBlock ();INLINE Void decodeInterTCOEF ();INLINE Void decodeInterVLCtableIndex (Int, Int*, Int*, Bool*, Int); // return islastrun, run and level//#define USE_BSFAST#define INTRA_LEVELMASK 0x0000001F#define INTRA_RUNMASK 0x000003E0#define INTRA_LASTRUNMASK 0x00000400#define DIVROUNDNEAREST(i, iDenom) (i>=0)?((i+(iDenom>>1))/iDenom):((i-(iDenom>>1))/iDenom)#define MP4V_DECODESHORTHEADERINTRAMBDC()\\ UInt uiIntraDC = getBits(8);\\ g_pIQOutput [1] = (uiIntraDC == 255) ? 128 : uiIntraDC;INLINE Void decodeTextureIntraBlock (Int iQP, Int iDcScaler, Int iIntraBlk, MacroBlockMemory* pmbmCurr, CMBMode* pmbmd, BlockMemory blkmPred, Int iQpPred){ Int iCoefStart = 0, i, j, iBlkMinus1 = iIntraBlk - 1; rgiZigzagIntra = grgiStandardZigzag; // Parse thru the right block & update the dst pointer with the correct // block data pointer.Also, custom memset this to 0 ClearBlockDataPointer(iBlkMinus1); if (!main_short_video_header) { if (pmbmd->m_bCodeDcAsAc==FALSE) { decodeIntraDCmpeg (iIntraBlk <= Y_BLOCK4); iCoefStart++; } } else // short_header { MP4V_DECODESHORTHEADERINTRAMBDC(); // 8 bits FLC & fixed quantizer op 8. iCoefStart++; } if (GETCODEDBLOCKPATTERN2 (pmbmd, iBlkMinus1)) {#ifdef ENABLE_NON_RECTANGLE_USAGE if (g_pVOP->bAlternateScan) // 12.22.98 Changes rgiZigzagIntra = grgiVerticalZigzag; else#endif if (pmbmd->m_bACPrediction) rgiZigzagIntra = (pmbmd->m_preddir [iBlkMinus1] == HORIZONTAL) ? grgiVerticalZigzag : grgiHorizontalZigzag; decodeIntraTCOEF (iCoefStart, rgiZigzagIntra); } inverseDCACPred (pmbmd, iBlkMinus1, iQP, iDcScaler, blkmPred, iQpPred);#ifdef ENABLE_H263_SUPPORT if (!main_short_video_header) #endif pmbmCurr->rgblkm [iBlkMinus1] [0] = g_pIQOutput [1] * iDcScaler; //save recon value of DC for intra pred#ifdef ENABLE_H263_SUPPORT else { pmbmCurr->rgblkm [iBlkMinus1] [0] = g_pIQOutput [1] * 8; //save recon value of DC for intra pred g_pHeader0->dcluma = g_pHeader0->dcchroma = 8; }#endif //save Qcoef in memory for (i = 1, j = 8; i < BLOCK_SIZE; i++, j += BLOCK_SIZE) { pmbmCurr->rgblkm [iBlkMinus1] [i] = g_pIQOutput [i ^ 1]; pmbmCurr->rgblkm [iBlkMinus1] [i + 7] = g_pIQOutput [j ^ 1]; }}INLINE Void decodeTextureInterBlock (){ // Get the pointer to the block that we need to fill in. Also, custom memset this to 0 ClearBlockDataPointer(nCodedBlocks); decodeInterTCOEF ();//else don't add error signal}INLINE Void findPredictorBlock (Int iBlkOrig, IntraPredDirection predDir, MacroBlockMemory* pmbmLeft, MacroBlockMemory* pmbmTop, MacroBlockMemory* pmbmLeftTop, MacroBlockMemory* pmbmCurr, CMBMode* pmbmdLeft, CMBMode* pmbmdTop, CMBMode* pmbmdLeftTop, CMBMode* pmbmdCurr,Int *iQPpred, BlockMemory *blkmRet){ *blkmRet = NULL; if (predDir == HORIZONTAL) { switch (iBlkOrig) { case Y_BLOCK1: case Y_BLOCK3: if (pmbmLeft != NULL && (pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ)) { *blkmRet = pmbmLeft->rgblkm [iBlkOrig]; *iQPpred = pmbmdLeft->m_stepSize; } break; case Y_BLOCK2: case Y_BLOCK4: *blkmRet = pmbmCurr->rgblkm [iBlkOrig - 2]; *iQPpred = pmbmdCurr->m_stepSize; break; default: if (pmbmLeft != NULL && (pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ)) { *blkmRet = pmbmLeft->rgblkm [iBlkOrig - 1]; *iQPpred = pmbmdLeft->m_stepSize; } } } else if (predDir == VERTICAL) { switch (iBlkOrig) { case Y_BLOCK1: case Y_BLOCK2: if (pmbmTop != NULL && (pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ)) { *blkmRet = pmbmTop->rgblkm [iBlkOrig + 1]; *iQPpred = pmbmdTop->m_stepSize; } break; case Y_BLOCK3: case Y_BLOCK4: *blkmRet = pmbmCurr->rgblkm [iBlkOrig - 3]; *iQPpred = pmbmdCurr->m_stepSize; break; default: if (pmbmTop != NULL && (pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ)) { *blkmRet = pmbmTop->rgblkm [iBlkOrig - 1]; *iQPpred = pmbmdTop->m_stepSize; } } } else if (predDir == DIAGONAL) { switch (iBlkOrig) { case Y_BLOCK1: if (pmbmLeftTop != NULL && (pmbmdLeftTop->m_dctMd == INTRA || pmbmdLeftTop->m_dctMd == INTRAQ)) { *blkmRet = pmbmLeftTop->rgblkm [Y_BLOCK4 - 1]; *iQPpred = pmbmdLeftTop->m_stepSize; } break; case Y_BLOCK2: if (pmbmTop != NULL && (pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ)) { *blkmRet = pmbmTop->rgblkm [Y_BLOCK3 - 1]; *iQPpred = pmbmdTop->m_stepSize; } break; case Y_BLOCK3: if (pmbmLeft != NULL && (pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ)) { *blkmRet = pmbmLeft->rgblkm [Y_BLOCK2 - 1]; *iQPpred = pmbmdLeft->m_stepSize; } break; case Y_BLOCK4: *blkmRet = pmbmCurr->rgblkm [Y_BLOCK1 - 1]; *iQPpred = pmbmdCurr->m_stepSize; break; default: if (pmbmLeftTop != NULL && (pmbmdLeftTop->m_dctMd == INTRA || pmbmdLeftTop->m_dctMd == INTRAQ)) { *blkmRet = pmbmLeftTop->rgblkm [iBlkOrig - 1]; *iQPpred = pmbmdLeftTop->m_stepSize; } } }#ifndef NO_ASSERTS else assert (FALSE);#endif}INLINE Void decideIntraPred (CMBMode* pmbmdCurr, Int *iQPpred, Int blkn, MacroBlockMemory* pmbmLeft, MacroBlockMemory* pmbmTop, MacroBlockMemory* pmbmLeftTop, MacroBlockMemory* pmbmCurr, CMBMode* pmbmdLeft, CMBMode* pmbmdTop,CMBMode* pmbmdLeftTop, BlockMemory *blkmPred){ Int iQPpredTop, iQPpredLeftTop, iQPpredLeft; BlockMemory blkmTop; BlockMemory blkmLeftTop; BlockMemory blkmLeft; Int iDefVal = 1<<(g_pVOL->nBits+2); // NBIT Int iPredLeftTop, iHorizontalGrad, iVerticalGrad; *blkmPred = NULL; findPredictorBlock (blkn, VERTICAL, pmbmLeft, pmbmTop, pmbmLeftTop, pmbmCurr, pmbmdLeft, pmbmdTop, pmbmdLeftTop, pmbmdCurr, &iQPpredTop, &blkmTop); findPredictorBlock (blkn, DIAGONAL, pmbmLeft, pmbmTop, pmbmLeftTop, pmbmCurr, pmbmdLeft, pmbmdTop, pmbmdLeftTop, pmbmdCurr, &iQPpredLeftTop, &blkmLeftTop); findPredictorBlock (blkn, HORIZONTAL, pmbmLeft, pmbmTop, pmbmLeftTop, pmbmCurr, pmbmdLeft, pmbmdTop, pmbmdLeftTop, pmbmdCurr, &iQPpredLeft, &blkmLeft); iPredLeftTop = (blkmLeftTop == NULL) ? iDefVal : blkmLeftTop [0]; iHorizontalGrad = ((blkmTop == NULL) ? iDefVal : blkmTop [0]) - iPredLeftTop; iVerticalGrad = ((blkmLeft == NULL) ? iDefVal : blkmLeft [0]) - iPredLeftTop; if (abs(iVerticalGrad) < abs (iHorizontalGrad)) { pmbmdCurr->m_preddir [blkn - 1] = VERTICAL; if (blkmTop != NULL) { *blkmPred = (BlockMemory)blkmTop; *iQPpred = iQPpredTop; } } else { pmbmdCurr->m_preddir [blkn - 1] = HORIZONTAL; if (blkmLeft != NULL) { *blkmPred = (BlockMemory)blkmLeft; *iQPpred = iQPpredLeft; } }}INLINE Void decodeEscape (Int *iLevel, Int *iRun, Int *bIsLastRun, Int* rgiLMAX, Int* rgiRMAX, PPHUFFMAN_DEC_STRUCT pHD, Bool bIntra){ Int iIndex, iLevelPlusAbs, iLevelAbs, iLevelBits, iMarker, iLevelIndex, nLocalBit; if (!main_short_video_header) // Added bij KPN [FDS] { MP4V_RETSINGLEBIT (&nLocalBit); //vlc; Level+ if (!nLocalBit) { iIndex = decodeSymbol(pHD); MP4V_RETSINGLEBIT (&nLocalBit); // sign bit if (bIntra) decodeIntraVLCtableIndex (iIndex, iLevel, iRun, bIsLastRun, nLocalBit); else decodeInterVLCtableIndex (iIndex, iLevel, iRun, bIsLastRun, nLocalBit); //get level back iLevelPlusAbs = abs (*iLevel); iLevelAbs = iLevelPlusAbs + rgiLMAX [(*iRun & 0x0000003F) + (*bIsLastRun << 6)]; //hashing the table *iLevel = sign(*iLevel) * iLevelAbs; } else // vlc; Run+ { MP4V_RETSINGLEBIT (&nLocalBit); if (!nLocalBit) { iIndex = decodeSymbol(pHD); MP4V_RETSINGLEBIT (&nLocalBit); // sign bit if (bIntra) decodeIntraVLCtableIndex (iIndex, iLevel, iRun, bIsLastRun, nLocalBit); else decodeInterVLCtableIndex (iIndex, iLevel, iRun, bIsLastRun, nLocalBit); *iRun = *iRun + rgiRMAX [(abs(*iLevel) & 0x0000001F) + (*bIsLastRun << 5)]; //get run back; RMAX tabl incl. + 1 already } else // flc { Int iMaxAC; MP4V_RETSINGLEBIT (bIsLastRun); *iRun = (Int) getBits (NUMBITS_ESC_RUN);#ifndef NO_ASSERTS assert (*iRun < BLOCK_SQUARE_SIZE);#endif iLevelBits = 12; // = m_volmd.nBits; MP4V_RETSINGLEBIT (&iMarker);#ifndef NO_ASSERTS assert(iMarker == 1);#endif *iLevel = (Int) getBits (iLevelBits); MP4V_RETSINGLEBIT (&iMarker);#ifndef NO_ASSERTS assert(iMarker == 1);#endif iMaxAC = (1<<(iLevelBits-1)) - 1;#ifndef NO_ASSERTS assert(*iLevel!=iMaxAC+1);#endif if (*iLevel > iMaxAC) *iLevel -= (1<<iLevelBits);#ifndef NO_ASSERTS assert(*iLevel != 0);#endif } } } // Escape coding short headers. Added by KPN else { MP4V_RETSINGLEBIT (bIsLastRun); *iRun = (Int) getBits (6); iLevelIndex = (Int) getBits(8); if (iLevelIndex == 0 || iLevelIndex == 128) { fprintf(stderr,"Short header mode. Levels 0 and 128 are not allowed\n"); exit(2); } if (iLevelIndex >= 0 && iLevelIndex < 128) *iLevel = iLevelIndex; else *iLevel = iLevelIndex-256; }}#ifdef USE_BSFASTINLINE Void decodeEscape_WithFastBS (Int *iLevel, Int *iRun, Int *bIsLastRun, Int* rgiLMAX, Int* rgiRMAX, PPHUFFMAN_DEC_STRUCT pHD, Bool bIntra, UInt cbits, UInt *pBitsUsed){ Int iIndex, iLevelPlusAbs, iLevelAbs, iLevelBits, iMarker, iLevelIndex; UInt uNextBit; UInt iBitsUsed=0; *pBitsUsed=0; if (!main_short_video_header) // Added bij KPN [FDS] { _BSFastGetBits2(cbits,1,*pBitsUsed, uNextBit); if (!uNextBit) // vlc; Level+ { iIndex = decodeSymbol_WithFastBS(pHD,cbits,&iBitsUsed); (*pBitsUsed)+=iBitsUsed; cbits<<=iBitsUsed;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -