h263dec.c

来自「著名的 helix realplayer 基于手机 symbian 系统的 播放」· C语言 代码 · 共 744 行 · 第 1/2 页

C
744
字号
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

#include "dllindex.h"
#include "h261defs.h"
#include "vldstate.h"
#include "vldtabs.h"
#include "h261func.h"
#include "vldecode.h"       /* set the proper pragmas for VLDecode          */
#include "h263plus.h"

//#include <stdio.h>
//#include <stdlib.h>
//#define BS_ERR_MSG(a)   a   // Generate messages on bitstream error (i.e., illegal 
                            // bitstream syntax) to simplify debugging
#define BS_ERR_MSG(a)       // Suppress error messages 

//#define CHECKSYM(a)     a     // Check symbol types to verify decoder state tables
#define CHECKSYM(a)             // Don't check symbol types

////////////  Static function declarations  ////////////
//  initPBtabs - Initialize tables for Bquant and mvB/mvF
static void initPBtabs( PICTURE_DESCR * pic );
//  decMvd - Decode "num" motion vectors
static int  decMvd( BS_PTR * bs,    // Bitstream pointer; updated by this routine
                    int * maxBits,  // max bits to decode; updated by this routine
                    int num,        // number of motion vectors to decode
                    S8  x[],        // hor. components decoded by this routine
                    S8  y[]         // vert. components decoded by this routine
                    );
// getMvComp - Compute mv component in H.263 decoder
static int getMvComp( int pred, S8 diff, int unrestrictedMv );
//  dec263blocks - Decode block layer for a macroblock
static int  dec263blocks(   BS_PTR * bs,    // Bitstream pointer; updated by this routine
                            int * maxBits,  // max bits to decode; updated by this routine
                            int cbp,        // Coded Block Pattern
                            int intraFlag,  // 0: INTER block, otherwise INTRA
                            int advancedIntraMode, // 0: off else on
                            BLOCK_DESCR block[6],   // block descriptors generated by this routine
                            SYMBOL sym[],   // array for symbols generated by this routine
                            int maxsym      // size of sym[] array
                            );
//  parseSymbols - Create block descriptor and merge ESC-RUN and ESC-LEVEL symbols
//  Return number of symbols
static int parseSymbols( SYMBOL insym[],        // Input symbols
                        int nsym,               // # input symbols
                        SYMBOL outsym[]         // output symbols
                        );



//  DecPicLayer263 - Decode H.263 Picture Layer information
extern int  DecPicLayer263( BS_PTR * bs, int nbits, PICTURE_DESCR * pic,
                            GOB_DESCR * gob, int * decPtype )
{
    int     gn, tr, ptype, quant, pei, pspare, cpm;
#ifdef DO_H263_PLUS
    int eptype=0;
#endif
    // Decode GN
    if (FLDecSymbol( bs, 5, &nbits, &gn )  !=  OK)  return( OUT_OF_BITS );
    if (gn != 0)  return( H261_ERROR );     // GN=0 for Picture Start Code
    // Decode TR
    if (FLDecSymbol( bs, 8, &nbits, &tr )  !=  OK)  return( OUT_OF_BITS );
    pic->tr = tr;
    // Decode PTYPE
    if (FLDecSymbol( bs, 13, &nbits, &ptype )  !=  OK)  return( OUT_OF_BITS );

#ifdef DO_H263_PLUS
    if ((ptype & 0xe0) == PTYPE263_EPTYPE) {
        if(FLDecSymbol( bs, 14, &nbits, &eptype )  !=  OK)  return( OUT_OF_BITS );
        // the picture type is in bits 1-3 of EPTYPE, put those bits into bits 6-8 of PTYPE
        ptype &= 0xFFFFFF1F; // clear bits 6-8
        ptype |= (0x3800 & eptype) >> 6; 
    }
#endif

    pic->ptype = ptype;
    *decPtype = ptype;
    pic->splitscreen = ptype & PTYPE263_SPLITSCREEN;
    pic->doccamera = ptype & PTYPE263_DOCCAMERA;
    pic->fp_release = ptype & PTYPE263_FP_RELEASE;
    switch (ptype & 0xe0)
    {
    case PTYPE263_SQCIF:
        pic->format = SQCIF;
        break;
    case PTYPE263_QCIF:
        pic->format = QCIF;
        break;
    case PTYPE263_CIF:
        pic->format = CIF;
        break;
    case PTYPE263_4CIF:
        pic->format = CIF4;
        break;
    case PTYPE263_16CIF:
        pic->format = CIF16;
        break;
    case PTYPE263_RESERVED:
        pic->format = ANYSIZE;
        break;
    default:
        return( H261_ERROR );
        break;
    }
    if ((ptype & 0x800) != 0  || (ptype & 0x1000) == 0) return( H261_ERROR );
    pic->interFrame = ptype & PTYPE263_INTER;
    pic->unrestrictedMv = ptype & PTYPE263_UNRESTRICTED_MV;
    pic->advancedPred = ptype & PTYPE263_ADVANCED_PRED;
    pic->syntax_basedAC = ptype & PTYPE263_SYNTAX_BASED_AC;
    if (pic->syntax_basedAC) {
        BS_ERR_MSG( H261ErrMsg("Syntax-based AC not yet supported"); )
        return( H261_ERROR );
    }
    pic->PBframeMode = (ptype & PTYPE263_PB_FRAME) != 0;

#ifdef DO_H263_PLUS
    // Do PB frame - either orignal or improved mode
    pic->PBframeMode = (ptype & PTYPE263_PB_FRAME) ? 1 : 0;
    if(pic->PBframeMode) {
        if( eptype & EPTYPE263PLUS_IMPROVED_PBFRAME_MODE) {
            pic->PBframeMode = H263PLUS_IMPROVED_PBFRAME_MODE;
        }
    } else {
        if( eptype & EPTYPE263PLUS_IMPROVED_PBFRAME_MODE) {
            return ( H261_ERROR );
        }
    }
    // Are deblocking filters on?
    pic->deblockingFilterMode = eptype & EPTYPE263PLUS_DEBLOCKING_FILTER_MODE;
    // Use advanced intra mode?
    pic->advancedIntraMode = eptype & EPTYPE263PLUS_ADVANCED_INTRA_MODE;
    // Using Reduced-resolution Update mode?
    pic->reducedResUpdate = eptype & EPTYPE263PLUS_REDUCED_RES_UPDATE;
    //if (pic->reducedResUpdate && (!pic->interFrame || pic->PBframeMode)) return( H261_ERROR );
#else
    pic->reducedResUpdate = 0;
#endif

    if(pic->interFrame == 0 && pic->PBframeMode != 0) return( H261_ERROR );
    // Decode PQUANT
    if (FLDecSymbol( bs, 5, &nbits, &quant )  !=  OK)  return( OUT_OF_BITS );
    if (quant < QUANT_MIN  ||  quant > QUANT_MAX)  return( H261_ERROR );
    gob->gquant = quant;
     // Decode CPM (continuous presence multipoint). For now, flag error if not zero.
    if (FLDecSymbol( bs, 1, &nbits, &cpm )  !=  OK)  return( OUT_OF_BITS );
    // if (cpm != 0)  return( H261_ERROR );
    pic->cpm = cpm;     // Save (we may need it?)
    if (pic->PBframeMode) {
        // Decode TRB
        if (FLDecSymbol( bs, 3, &nbits, &tr )  !=  OK)  return( OUT_OF_BITS );
        pic->tempRefBframe = tr;
        // Decode DBQUANT
        if (FLDecSymbol( bs, 2, &nbits, &quant )  !=  OK)  return( OUT_OF_BITS );
        pic->dbQuant = quant;
        initPBtabs( pic );  // Generate lookup tables for Bquant and mvB/mvF
    }
    pic->trPrev = pic->tr;  // Hold on to TR for decoding of next picture
    // Decode PEI
    if (FLDecSymbol( bs, 1, &nbits, &pei )  !=  OK)  return( OUT_OF_BITS );
    pic->peiCount = 0;
    // Decode PSPARE
    while (pei) {   // Loop until PEI=0
        if (pic->peiCount < MAX_PEI_COUNT) {
            FLDecSymbol( bs, 8, &nbits, &pspare );
            pic->pSpare[pic->peiCount] = pspare;
        } else {
            ++bs->byteptr;  // Drop PSPARE on the floor
        }
        ++pic->peiCount;
        if (FLDecSymbol( bs, 1, &nbits, &pei )  !=  OK)  return( OUT_OF_BITS );
    }
    // Indicate that GOB header has no "spares"
    gob->gei = 0;
    gob->num_gspare = 0;
    return( OK );
}


//  InitMvTabs - Initialize tables for mvB/mvF
extern void InitMvTabs( int trD, int trB,
                        int tabMvF[], int tabMvB[]  // [UMV_MIN:UMV_MAX]
                        )
{
    int i;

    // Generate tables for B-picture motion vectors
    trD &= H263_TR_MASK;
    if (trD == 0)  trD = 2; // Avoid divide by 0
    if (trB >= trD)  trB = 0;   // Ensure trB < trD
    for (i = UMV_MIN; i <= UMV_MAX; ++i) {
        tabMvF[i] = (trB * i) / trD;          // Mv using prev. picture
        tabMvB[i] = ((trB - trD) * i) / trD;  // Mv using new P-picture
    }
}


// Tables for B-picture: Bquant and mvF/mvB
static U8   tabBquant[QUANT_MAX-QUANT_MIN+1];
static int  decMvF[UMV_MAX-UMV_MIN+1],  // Mv using prev. picture
            decMvB[UMV_MAX-UMV_MIN+1];  // Mv using new P-picture

//  initPBtabs - Initialize tables for Bquant and mvB/mvF
static void initPBtabs( PICTURE_DESCR * pic )
{
    int i, n;

    // Generate tables for B-picture motion vectors
    InitMvTabs( (pic->tr - pic->trPrev) & H263_TR_MASK, 
                pic->tempRefBframe,
                &decMvF[-UMV_MIN], &decMvB[-UMV_MIN] );
    // Generate table for Bquant
    n = pic->dbQuant + 5;
    for (i = QUANT_MIN; i <= QUANT_MAX; ++i) {
        tabBquant[i - QUANT_MIN] = min( (n*i) >> 2, QUANT_MAX );
    }
}


//  DecGobLayer263 - Decode H.263 GOB Layer information
extern int  DecGobLayer263( BS_PTR * bs, int nbits, GOB_DESCR * gob, int * gfid )
{
    int     gn, quant;

    // Decode GN
    if (FLDecSymbol( bs, 5, &nbits, &gn )  !=  OK)  return( OUT_OF_BITS );
    // Decode GFID
    if (FLDecSymbol( bs, 2, &nbits, gfid )  !=  OK)  return( OUT_OF_BITS );
    // Decode GQUANT
    if (FLDecSymbol( bs, 5, &nbits, &quant )  !=  OK)  return( OUT_OF_BITS );
    if (quant < QUANT_MIN  ||  quant > QUANT_MAX)  return( H261_ERROR );
    gob->gquant = quant;
    // Indicate that GOB header has no "spares"
    gob->gei = 0;
    gob->num_gspare = 0;
    return( OK );
}

//#define DB_DUMP_BLOCK_SYMBOLS
#ifdef DB_DUMP_BLOCK_SYMBOLS
FILE * pDecFile=0;
int bDecOpen=0;
int bDecClose=0;
#endif

//  DecMbLayer263 - Decode macroblock layer and block layer for a Group Of Blocks
//  This routine is very picky when determining whether bitstream is valid.
//  It returns OK only if a startcode ends the bitstream; otherwise, it
//  returns H261_ERROR.
extern int  DecMbLayer263(  BS_PTR * bs,    // Bitstream pointer
                            int nbits,      // Bits to decode (incl. trailing startcode)
                            GOB_DESCR * gob,        // GOB descriptor
                            MACROBLOCK_DESCR mb[],  // Packed array of "gob->num_mb" MB descr.
                            int interFrame, // 0: ptype=INTRA, otherwise ptype=INTER
                            int PBframe,    // 0: not PB frame, otherwise PB frame
                            int unrestrictedMv, // 0: -16/+15.5 motion, otherwise +/- 31.5
                            int advancedIntraMode, // 0: off else on
                            SYMBOL sym[],   // symbol array
                            int maxsym      // size of symbol array
                            )
{
    int     quant, isym, mcbpcTab, i, j, status, cbpyTab, intraFlag, horPredOnly, mvX, mvY;
    SYMBOL  s;
    int     mcbpc, modB, cbpB;
    BS_ERR_MSG ( char msg[120] ); /* Flawfinder: ignore */
    
    isym = 0;
    quant = gob->gquant;
    if (interFrame) {
        mcbpcTab = TAB263_MCBPC_INTER;
    } else {
        mcbpcTab = TAB263_MCBPC_INTRA;
    }
    for (i = 0; i < gob->num_mb; ++i) {
        // Decode MCBPC
        do {
            status = VLDecSymbol( bs, mcbpcTab, &nbits, &s );
			if (status != OK)  
                if (s.type != SYM_STARTCODE) {
					status = BITSTREAM_ERROR;
					goto error_exit;
				} else {
					return(OK);
				}
        } while( s.type == SYM_MCBPC_STUFFING );
        mcbpc = s.value;
        mb[i].mtype = mcbpc & 0xfc; // Mask off cbpC (two LSBs)

#ifdef DO_H263_PLUS
        if(advancedIntraMode && 
            (mb[i].mtype == MTYPE263_INTRA || mb[i].mtype == MTYPE263_INTRA_Q)) {
            // Decode INTRA_MODE
            status = VLDecSymbol( bs, TAB263PLUS_INTRA_MODE, &nbits, &s );
			if (status != OK)  goto error_exit;
            mb[i].intra_mode = s.value;
        } else {
            mb[i].intra_mode = ADV_INTRA_PRED_NONE;
        }
#endif
        //printf("DecMbLayer:  x = %d   y = %d   type = %d\n", mb[i].x, mb[i].y, mb[i].mtype );
        if (mb[i].mtype == MTYPE_SKIP) {
            mb[i].mv_x = 0;
            mb[i].mv_y = 0;
        } else {
            if (PBframe) {
                // Decode MODB
#ifdef DO_H263_PLUS
				if(PBframe==H263PLUS_IMPROVED_PBFRAME_MODE) {
					status = VLDecSymbol( bs, TAB263PLUS_MODB, &nbits, &s );
				} else {
					status = VLDecSymbol( bs, TAB263_MODB, &nbits, &s );
				}
#else
				status = VLDecSymbol( bs, TAB263_MODB, &nbits, &s );
#endif
				if (status != OK)  
					goto error_exit;
                modB = s.value;
                mb[i].modB = modB;
                if (BFRAME_HAS_CBP(&mb[i])) {    // Decode cbpB
                    status = FLDecSymbol( bs, 6, &nbits, &cbpB );
                    if (status != OK)  goto error_exit;
                    mb[i].cbpB = cbpB;
                } else {
                    mb[i].cbpB = 0;
                }
            } else {
                mb[i].modB = modB = 0;
            }
            // Decode cbpY
            if (mb[i].mtype == MTYPE263_INTRA  ||  mb[i].mtype == MTYPE263_INTRA_Q) {
                cbpyTab = TAB263_CBPY_INTRA;
            } else {
                cbpyTab = TAB263_CBPY;
            }
            status = VLDecSymbol( bs, cbpyTab, &nbits, &s );
            if (status != OK)  goto error_exit;
            mb[i].cbp = (s.value << 2) | (mcbpc & 0x3);
            // Decode DQUANT

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?