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 + -
显示快捷键?