📄 vopsedec.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 Simon Winder (swinder@microsoft.com), Microsoft Corporation (date: March, 1996)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 David B. Shu (dbshu@hrl.com), Hughes Electronics/HRL Laboratoriesand also edited by Dick van Smirren (D.vanSmirren@research.kpn.com), KPN Research Cor Quist (C.P.Quist@research.kpn.com), KPN Research Mathias Wien (wien@ient.rwth-aachen.de) RWTH Aachen / Robert BOSCH GmbHand also edited by Yoshinori Suzuki (Hitachi, Ltd.)and also edited by Hideaki Kimata (NTT)and also edited by Fujitsu Laboratories Ltd. (contact: Eishi Morimatsu)and also edited by Massimo Ravasi (Massimo.Ravasi@epfl.ch), Swiss Federal Institute of Technology, Lausanne (EPFL)and also edited by Takefumi Nagumo (nagumo@av.crl.sony.co.jp), Sony Corporation Sehoon Son (shson@unitel.co.kr) Samsung AITin 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: vopsedec.cAbstract: Decoder for one Video Object.Revision History: Dec 20, 1997: Interlaced tools added by NextLevel Systems X. Chen (xchen@nlvl.com) B. Eifrig (beifrig@nlvl.com) Feb.16, 1999: (use of rgiDefaultInterQMatrixAlpha) Mathias Wien (wien@ient.rwth-aachen.de) Feb.24, 1999: GMC added by Yoshinori Suzuki (Hitachi, Ltd.) Aug.24, 1999: NEWPRED added by Hideaki Kimata (NTT) Sep.06 1999 : RRV added by Eishi Morimatsu (Fujitsu Laboratories Ltd.) Nov.11 1999 : Fixed Complexity Estimation syntax support, version 2 (Massimo Ravasi, EPFL) Feb.01 2000 : Bug fixed OBSS by Takefumi Nagumo (Sony)*************************************************************************/#include <stdio.h>#ifdef __GNUC__//#include <strstream.h>#else//#include <strstrea.h>#endif#include <math.h>#include "typeapi.h"#include "codehead.h"#ifdef UNDER_CE#include "bitstrm.h"#include "huffman.h"#else#include "entropy/bitstrm.h"#include "entropy/huffman.h"#endif#include "global.h"#include "mode.h"#include "vopses.h"#include "vopsedec.h"#ifdef USE_MAI#include "mai_component.h"#include "mai_compbase.h" /* for NewFrame() */extern MAICompHandle_t g_hComp;extern MAISpeed_e g_NextSpeed;extern m_u32 g_uiWaitForIFrame;#endifInt g_MP4VDecodeMode = DECODE_NORMAL;#ifdef MP4_STANDALONE// File handling related#include <fcntl.h>#define O_STREAMING 0x400000#endif#define _FOR_GSSP_#define MAXHEADING_ERR 3#define MAXMIDDLE_ERR 10#define MAXTRAILING_ERR 2void MP4V_ResetBitStream();UInt video_plane_with_short_header();Int findStartCode();// visual sequence, visual object layersInt decodeVSHead ();// VO and VOL routinesVoid decodeVOHead (CVideoObjectDecoder *);int decodeVOLHead (CVideoObjectDecoder *, VOLMode *, VOPMode *);#ifdef ENABLE_MULTIPLE_VOL_SUPPORTint decodeVOHead_Stripped (CVideoObjectDecoder *);int decodeVOLHead_Stripped (CVideoObjectDecoder *, VOLMode *, VOPMode *);#endif// VOP routinesBool decodeVOPHead ();#ifndef NEW_MAE_DRIVERVoid updateAllRefVOPs ();#endif// Globals for basic.hCSite g_CAddVect, g_CSubVect, g_CMulVect, g_CDivVect;Bool main_short_video_header;VOLtype TmpVOLType;unsigned int g_bSequenceStarted=0; /* was the stream headers found yet */unsigned int g_iClipType = CLIP_MPEG4;unsigned long g_tVopIncr = 0;int nFrames = 0, g_iTNum = 0, g_iCorrectionFactor = 0;#ifdef NO_ASSERTS#define MP4V_SEARCHVOPSTARTCODE(uiVopStartCode)\{\ if (uiVopStartCode != VOP_START_CODE)\ {\ /* For all streams, once we detect a NULL VOP, we will continue to read thru the stream & look for the next VOP header*/\ /* In case we hit End-Of-Stream before that, findStartCode( ) will handle that as well */\ while (uiVopStartCode != VOP_START_CODE)\ {\ if (findStartCode())\ break;\ uiVopStartCode = getBits (NUMBITS_VOP_START_CODE);\ }\ }\ g_pVOP->vopPredType = (VOPpredType) getBits (NUMBITS_VOP_PRED_TYPE);\}#else /* ASSERT enabled */#define MP4V_SEARCHVOPSTARTCODE(uiVopStartCode)\{\ if (uiVopStartCode != VOP_START_CODE)\ {\ /* For all streams, once we detect a NULL VOP, we will continue to read thru the stream & look for the next VOP header*/\ /* In case we hit End-Of-Stream before that, findStartCode( ) will handle that as well */\ while (uiVopStartCode != VOP_START_CODE)\ {\ if (findStartCode())\ break;\ uiVopStartCode = getBits (NUMBITS_VOP_START_CODE);\ }\ }\ else\ assert(uiVopStartCode == VOP_START_CODE);\\ g_pVOP->vopPredType = (VOPpredType) getBits (NUMBITS_VOP_PRED_TYPE);\}#endif#define MP4V_PERFROMROUNDING(nRet, nVal, bHigher)\{\ int nQuotient;\\ if (!(nVal%16))\ {\ *nRet = nVal;\ }\ else\ {\ nQuotient = (nVal/16);\ if (bHigher) /* Round Up */\ *nRet = (++nQuotient * 16);\ else /* Round down */\ *nRet = (nQuotient * 16);\ }\}int MP4V_Decoder_Init (Char* pchStrFile, Int *iDisplayWidth, Int *iDisplayHeight){ Int iDisplayWidthRound = 0, iDisplayHeightRound = 0, iOrigWidth, iOrigHeight, iShift_By = 1; g_bSequenceStarted=0; nFrames = 0; g_iCorrectionFactor = 0; // Initialize the sizes iOrigWidth = iPicWidth = *iDisplayWidth; iOrigHeight = iPicHeight = *iDisplayHeight;#ifdef USE_MAI // Flush the driver (let it get rid of all its residual frames, if any) request_mae_flush ();#endif // Initialize the global CVideoObject MP4V_VideoObject_Init (); // Initialize the global CVideoObjectDecoder pointer g_pDecoder = &(g_pVO->MP4_VideoObjectDecoder); // Reset bitstream MP4V_ResetBitStream(); // Setup some frequently used global pointers g_pVOL = &(g_pVO->m_volmd); // vol mode g_pVOP = &(g_pVO->m_vopmd); // vop mode#ifdef MP4_STANDALONE { int n_FileId; // Open the mae driver open_mae_driver(); // Use fdopen instead of fopen to address the file caching issue n_FileId=open(pchStrFile, O_RDONLY | O_STREAMING, 0); if (n_FileId<0) // open failed { g_InFile=NULL; printf("\nERROR: FAILED TO OPEN THE INPUT FILE!!\n"); exit (0); } else g_InFile=fdopen(n_FileId, "rb"); // Seek to the beginning of the file fseek (g_InFile, 0, SEEK_SET); }#endif #ifdef ENABLE_PRINTS printf("Input file successfully opened!!\n");#endif CEntropyDecoderSet (); g_pVO->m_t = g_pVO->m_tPastRef = g_pVO->m_tFutureRef = 0; g_pVO->m_iBCount = 0; g_pVOP->iVopConstantAlphaValue = 255; main_short_video_header=FALSE; // Added by KPN for short headers if (peekBits(NUMBITS_SHORT_HEADER_START_CODE) == SHORT_VIDEO_START_MARKER) { #ifdef ENABLE_PRINTS printf("**** Bitstream with short header format detected ****\n"); #endif main_short_video_header=TRUE; getBits(22); g_pVO->m_t = video_plane_with_short_header(); } else {#ifdef ENABLE_PRINTS printf("**** Bitstream without short headers detected ****\n");#endif decodeVOHead (g_pDecoder); // also decodes vss, vso headers if present if(decodeVOLHead (g_pDecoder, g_pVOL, g_pVOP) != 0) {#ifdef ENABLE_PRINTS printf("DecodeVOLHead returned an error\n");#endif return -1; } } g_bSequenceStarted=1; g_pVO->m_bLinkisBroken = FALSE; g_pVO->m_bUseGOV = FALSE; g_iMaxHeading = MAXHEADING_ERR; g_iMaxMiddle = MAXMIDDLE_ERR; g_iMaxTrailing = MAXTRAILING_ERR; setClipTab(g_pVO, g_pVOL); // NBIT if (g_pVOL->fAUsage == RECTANGLE) { if (iOrigWidth != g_pVO->m_ivolWidth || iOrigHeight != g_pVO->m_ivolHeight) { iOrigWidth = g_pVO->m_ivolWidth; iOrigHeight = g_pVO->m_ivolHeight; } } // Changing the decoded size causes the player to crash (play-stop-play). I think this is due // to the fact that we will be doing lesser reads from the bitstream when the spatial size is // reduced and that in turn will have an impact on all bits (that the decoder will interpret) // So, lets just keep the decoded size same as the display size (there will be a gray band // at the bottom which we have to intelligently discard in the driver when passing on the // decoded size from MAE-FE to MAE-BE) MP4V_PERFROMROUNDING(&iPicWidth, iOrigWidth, TRUE); MP4V_PERFROMROUNDING(&iPicHeight,iOrigHeight, TRUE);#ifdef ENABLE_PRINTS printf("iOrigWidth = %d iOrigHeight = %d\n", iOrigWidth, iOrigHeight); printf("iPicWidth = %d iPicHeight = %d\n", iPicWidth, iPicHeight);#endif // Round up (lower) the display sizes & pass it up MP4V_PERFROMROUNDING(iDisplayWidth, iOrigWidth, FALSE); MP4V_PERFROMROUNDING(iDisplayHeight,iOrigHeight, FALSE); // Set the display size if we are in StandAlone mode UpdateDisplaySizes (iDisplayWidth, iDisplayHeight);#ifdef ENABLE_PRINTS printf("*iDisplayWidth = %d *iDisplayHeight = %d\n", *iDisplayWidth, *iDisplayHeight);#endif // Now, initialize the display height that MAE-BE will use // (will be chopped in case there is garbage at the bottom) if (*iDisplayHeight != iPicHeight) iChoppedHeight = *iDisplayHeight; CRCT_Init2 ((&g_pVO->m_rctDisplayWindow), 0, 0, iPicWidth, iPicHeight); //same as m_rctOrg? will fixe later #ifdef DUAL_MODE if (g_pVO->m_uiSprite == 1) // change iDisplay size in order to get the first sprite piece { iPicWidth = (Int) g_pVO->m_rctSpt.width; iPicHeight = (Int) RCT_HEIGHT((&g_pVO->m_rctSpt)); }#endif iDisplayWidthRound = ((iPicWidth + MB_SIZE - 1)>>4)<<4; iDisplayHeightRound = ((iPicHeight + MB_SIZE - 1)>>4)<<4; CRCT_Init2 ((&g_pVO->m_rctRefFrameY), -EXPANDY_REF_FRAME, -EXPANDY_REF_FRAME, EXPANDY_REF_FRAME + iDisplayWidthRound, EXPANDY_REF_FRAME + iDisplayHeightRound); CRCT_Init2 ((&g_pVO->m_rctRefFrameY), 0, 0, iPicWidth, iPicHeight); DOWNSAMPLEBY2((&g_pVO->m_rctRefFrameUV), (&g_pVO->m_rctRefFrameY)); allocateVOLMembers (g_pVO, g_pVOL, iPicWidth, iPicHeight); if (g_pVOL->fAUsage == RECTANGLE) {#ifdef DUAL_MODE // GMC if (g_pVO->m_uiSprite == 0 || g_pVO->m_uiSprite == 2) #endif { CRCT_Init2 ((&m_rctCurrVOPY), 0, 0, iDisplayWidthRound, iDisplayHeightRound); }#ifdef DUAL_MODE else m_rctCurrVOPY = g_pVO->m_rctSpt;#endif DOWNSAMPLEBY2((&g_pVO->m_rctCurrVOPUV), (&m_rctCurrVOPY)); m_rctRefVOPY0 = m_rctCurrVOPY; RCT_EXPAND((&m_rctRefVOPY0), EXPANDY_REFVOP); DOWNSAMPLEBY2((&m_rctRefVOPUV0), (&m_rctRefVOPY0)); m_rctRefVOPY1 = m_rctRefVOPY0; m_rctRefVOPUV1 = m_rctRefVOPUV0; computeVOLConstMembers (g_pVO, g_pVOL); // these VOP members are the same for all frames } // buffers for Temporal Scalabe Decoding End Sharp(1998-02-10) g_pDecoder->m_iClockRateScale = 1; // added by Sharp (98/6/26) // Set sprite_transmit_mode to STOP for the duration of VOL if (fSptUsage () == 0), // and later set to PIECE by decode_init_sprite () if (fSptUsage () == 1) g_pVOP->SpriteXmitMode = STOP; // Pulled up from decodeVOP () m_iTemporalNumber = 0;#ifdef INLINE_MV_CLIPPING // Pre-compute some frequently used params iPicWidth_1 = iPicWidth - 1; iPicHeight_1 = iPicHeight - 1; // Setup QPEL values (if needed) if (g_pVOL->bQuarterSample) {#ifdef ENABLE_PRINTS printf("QPEL MotionComp\n");#endif // Re-initialize for QPEL precision iShift_By = 2; // Re-setup all the arrays for QPEL precision for (iBlk=0; iBlk<8; iBlk++) { LumaAdjX1[iBlk] <<= 1; LumaAdjY1[iBlk] <<= 1; LumaAdjX3[iBlk] = -32 - LumaAdjX1[iBlk]; LumaAdjY3[iBlk] = -32 - LumaAdjY1[iBlk]; LumaAdjX4 [iBlk] = (iPicWidth_1 - LumaAdjX2[iBlk]) << iShift_By; LumaAdjY4 [iBlk] = (iPicHeight_1 - LumaAdjY2[iBlk]) << iShift_By; } } // Just setup the last array for HPEL precision else {#ifdef ENABLE_PRINTS printf("HPEL MotionComp\n");#endif for (iBlk=0; iBlk<8; iBlk++) { LumaAdjX4 [iBlk] = (iPicWidth_1 - LumaAdjX2[iBlk]) << iShift_By; LumaAdjY4 [iBlk] = (iPicHeight_1 - LumaAdjY2[iBlk]) << iShift_By; } } // Pre-compute some more frequently used params iPicWidth_2 = iPicWidth_1 << iShift_By; iPicHeight_2 = iPicHeight_1 << iShift_By; iPicWidth_3 = iPicWidth_2 * 2; iPicHeight_3 = iPicHeight_2 * 2; iPicWidthUV_1 = iPicWidth/2 - 1; iPicHeightUV_1 = iPicHeight/2 - 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -