h263dec.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:31k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: h263dec.c,v 1.3.34.1 2004/07/09 01:56:22 hubbe Exp $
- *
- * Portions Copyright (c) 1995-2004 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 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (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.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * 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 = %dn", 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
- if (mb[i].mtype == MTYPE263_INTER_Q || mb[i].mtype == MTYPE263_INTRA_Q) {
- status = VLDecSymbol( bs, TAB263_DQUANT, &nbits, &s );
- if (status != OK) goto error_exit;
- mb[i].dquant = s.value;
- quant += mb[i].dquant;
- if (quant < QUANT_MIN)
- quant = QUANT_MIN;
- if (quant > QUANT_MAX)
- quant = QUANT_MAX;
- }
- mb[i].quant = quant;
- // Decode motion vectors and block layer
- if (i < gob->mb_width) {
- horPredOnly = YES; // First row of macroblocks; don't use prev. row
- } else {
- horPredOnly = NO;
- }
- switch( mb[i].mtype ) {
-
- case MTYPE263_INTRA:
- case MTYPE263_INTRA_Q:
- if (PBframe) { // Decode MVD
- status = decMvd( bs, &nbits, 1, &mb[i].mvd_x, &mb[i].mvd_y );
- if (status != OK) goto error_exit;
- MvPred( &mb[i], WHOLE_MACROBLOCK, gob->mb_offset, horPredOnly, &mvX, &mvY );
- mb[i].mv_x = getMvComp( mvX, mb[i].mvd_x, unrestrictedMv );
- mb[i].mv_y = getMvComp( mvY, mb[i].mvd_y, unrestrictedMv );
- if (BFRAME_HAS_MOTION_VECTOR(&mb[i])) { // Decode MVDB
- status = decMvd( bs, &nbits, 1, &mb[i].mvdB_x, &mb[i].mvdB_y );
- if (status != OK) goto error_exit;
- }
- } else {
- mb[i].mv_x = 0;
- mb[i].mv_y = 0;
- }
- intraFlag = YES;
- #ifdef DO_H263_PLUS
- status = dec263blocks( bs, &nbits, mb[i].cbp, intraFlag, advancedIntraMode,
- mb[i].block, &sym[isym], maxsym - isym );
- #else
- status = dec263blocks( bs, &nbits, mb[i].cbp, intraFlag, 0,
- mb[i].block, &sym[isym], maxsym - isym );
- #endif
- #ifdef DB_DUMP_BLOCK_SYMBOLS
- if(bDecClose) {
- fclose(pDecFile);
- pDecFile = NULL;
- }
- if(bDecOpen) {
- pDecFile = fopen("C:\temp\dec_out.dmp", "wt");
- }
- if(pDecFile) {
- int b,s;
- fprintf(pDecFile, "n n Macroblock %d n n", i);
- for(b=0; b<6; b++) {
- fprintf(pDecFile, "n Block %d n", b);
- for(s=0; s<mb[i].block[b].nsym; s++) {
- fprintf(pDecFile, "lev = %d run = %dn", mb[i].block[b].sym[s].value, mb[i].block[b].sym[s].type);
- }
- }
- }
- #endif
- if (status == H261_ERROR) {
- status = BITSTREAM_ERROR;
- goto error_exit;
- }
- isym += status;
- break;
-
- case MTYPE263_INTER:
- case MTYPE263_INTER_Q:
- // Decode MVD
- status = decMvd( bs, &nbits, 1, &mb[i].mvd_x, &mb[i].mvd_y );
- if (status != OK) goto error_exit;
- MvPred( &mb[i], WHOLE_MACROBLOCK, gob->mb_offset, horPredOnly, &mvX, &mvY );
- mb[i].mv_x = getMvComp( mvX, mb[i].mvd_x, unrestrictedMv );
- mb[i].mv_y = getMvComp( mvY, mb[i].mvd_y, unrestrictedMv );
- if (BFRAME_HAS_MOTION_VECTOR(&mb[i])) { // Decode MVDB
- status = decMvd( bs, &nbits, 1, &mb[i].mvdB_x, &mb[i].mvdB_y );
- if (status != OK) goto error_exit;
- }
- intraFlag = 0;
- status = dec263blocks( bs, &nbits, mb[i].cbp, intraFlag, 0,
- mb[i].block, &sym[isym], maxsym - isym );
- if (status == H261_ERROR) {
- status = BITSTREAM_ERROR;
- goto error_exit;
- }
- isym += status;
- break;
-
- case MTYPE263_INTER4V:
- // Decode MVD1-4
- status = decMvd( bs, &nbits, 4, mb[i].blkDiffX, mb[i].blkDiffY );
- if (status != OK) goto error_exit;
- for (j = 0; j < 4; ++j) {
- MvPred( &mb[i], j, gob->mb_offset, horPredOnly, &mvX, &mvY );
- mb[i].blkMvX[j] = getMvComp( mvX, mb[i].blkDiffX[j], unrestrictedMv );
- mb[i].blkMvY[j] = getMvComp( mvY, mb[i].blkDiffY[j], unrestrictedMv );
- }
- if (BFRAME_HAS_MOTION_VECTOR(&mb[i])) { // Decode MVDB
- status = decMvd( bs, &nbits, 1, &mb[i].mvdB_x, &mb[i].mvdB_y );
- if (status != OK) goto error_exit;
- }
- intraFlag = 0;
- status = dec263blocks( bs, &nbits, mb[i].cbp, intraFlag, 0,
- mb[i].block, &sym[isym], maxsym - isym );
- if (status == H261_ERROR) {
- status = BITSTREAM_ERROR;
- goto error_exit;
- }
- isym += status;
- break;
-
- default:
- status = UNKNOWN_MTYPE;
- goto error_exit;
- break;
- }
-
- if (PBframe) {
- // Reconstruct forward and backward mv for B-frame
- GetMvBframe( &mb[i], unrestrictedMv, &decMvF[-UMV_MIN], &decMvB[-UMV_MIN] );
- mb[i].Bquant = tabBquant[quant - QUANT_MIN];
- if (BFRAME_HAS_CBP(&mb[i])) { // Decode B blocks
- intraFlag = 0;
- status = dec263blocks( bs, &nbits, mb[i].cbpB, intraFlag, 0,
- mb[i].Bblock, &sym[isym], maxsym - isym );
- if (status == H261_ERROR) {
- status = BITSTREAM_ERROR;
- goto error_exit;
- }
- isym += status;
- }
- }
- }
- }
- //printf("DecMbLayer: Remove stuffing, then find startcode; nbits = %dn", nbits);
-
- do {
- status = VLDecSymbol( bs, mcbpcTab, &nbits, &s );
- if (status != OK)
- return(OK);
- // goto error_exit;
- // sometimes the end of stream is not that clean.. -gneel
- } while( s.type == SYM_MCBPC_STUFFING);
- // if (s.type != SYM_STARTCODE || nbits != 0) {
- // status = BITSTREAM_ERROR;
- // goto error_exit;
- // }
- // After all the mbs are over there may not be a start code.
-
- return( OK );
- error_exit:
- BS_ERR_MSG( sprintf( msg, "DecMbLayer263: error %d occurred in block #%d", status, i); /* Flawfinder: ignore */
- H261ErrMsg( msg ); )
- return( H261_ERROR );
- }
- // 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
- )
- {
- int i, status;
- SYMBOL s;
-
- for (i = 0; i < num; ++i) {
- // Decode horizontal component
- status = VLDecSymbol( bs, TAB263_MVD, maxBits, &s );
- if (status != OK) return( status );
- x[i] = s.value;
- // Decode vertical component
- status = VLDecSymbol( bs, TAB263_MVD, maxBits, &s );
- if (status != OK) return( status );
- y[i] = s.value;
- }
- return( OK );
- }
- // getMvComp - Compute mv component in H.263 decoder
- static int getMvComp( int pred, S8 diff, int unrestrictedMv )
- {
- int output;
-
- output = pred + diff;
- if (unrestrictedMv == 0) {
- while (output < MVD263_MIN) {
- output += MV263_WRAP;
- }
- while (output > MVD263_MAX) {
- output -= MV263_WRAP;
- }
- } else if (pred < UMV_NEG_THRESH) {
- // UMV pred < -15.5: -31.5 <= output <= 0
- if (output < UMV_MIN) {
- output += MV263_WRAP; // Need only check negative limit, since diff <= 15.5
- }
- } else if (pred > UMV_POS_THRESH && output > UMV_MAX) {
- // UMV pred > 16: 0 <= output <= 31.5
- output -= MV263_WRAP; // Need only check positive limit, since diff >= -16
- } // else: Don't need to check for -15.5 <= pred <= 16
- return( output );
- }
- // GetMvBframe - Reconstruct forward and backward motion vectors for B-frame
- extern void GetMvBframe( MACROBLOCK_DESCR *mb, int unrestrictedMv,
- int tabMvF[], int tabMvB[] // [UMV_MIN:UMV_MAX]
- )
- {
- int j;
- if (mb->mtype == MTYPE263_INTER4V) {
- for (j = 0; j < 4; ++j) {
- // Forward prediction (using prev. frame)
- mb->blkMvFx[j] = tabMvF[ mb->blkMvX[j] ];
- mb->blkMvFy[j] = tabMvF[ mb->blkMvY[j] ];
- if (BFRAME_HAS_MOTION_VECTOR(mb)) {
- mb->blkMvFx[j] = getMvComp( mb->blkMvFx[j], mb->mvdB_x, unrestrictedMv );
- mb->blkMvFy[j] = getMvComp( mb->blkMvFy[j], mb->mvdB_y, unrestrictedMv );
- // Backward prediction (using next P-frame)
- mb->blkMvBx[j] = mb->blkMvFx[j] - mb->blkMvX[j];
- mb->blkMvBy[j] = mb->blkMvFy[j] - mb->blkMvY[j];
- } else {
- mb->blkMvBx[j] = tabMvB[ mb->blkMvX[j] ];
- mb->blkMvBy[j] = tabMvB[ mb->blkMvY[j] ];
- }
- }
- } else { // Same motion vector for the whole macroblock
- // Forward prediction (using prev. frame)
- mb->blkMvFx[0] = tabMvF[ mb->mv_x ];
- mb->blkMvFy[0] = tabMvF[ mb->mv_y ];
- if (BFRAME_HAS_MOTION_VECTOR(mb)) {
- mb->blkMvFx[0] = getMvComp( mb->blkMvFx[0], mb->mvdB_x, unrestrictedMv );
- mb->blkMvFy[0] = getMvComp( mb->blkMvFy[0], mb->mvdB_y, unrestrictedMv );
- // Backward prediction (using next P-frame)
- mb->blkMvBx[0] = mb->blkMvFx[0] - mb->mv_x;
- mb->blkMvBy[0] = mb->blkMvFy[0] - mb->mv_y;
- } else {
- mb->blkMvBx[0] = tabMvB[ mb->mv_x ];
- mb->blkMvBy[0] = tabMvB[ mb->mv_y ];
- }
- }
- }
- // 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
- )
- {
- int startState, isym, mask, blk, state, status, parsed_bits, nsym;
-
- if (intraFlag) {
- #ifdef DO_H263_PLUS
- if(advancedIntraMode) {
- startState = ST263PLUS_BLK_6;
- } else {
- startState = ST263_INTRA_DC_AC;
- }
- #else
- startState = ST263_INTRA_DC_AC; // Decode DC and AC coeffs
- #endif
- } else {
- startState = ST263_BLK_6; // Decode one INTER block
- }
- isym = 0;
- mask = 0x20; // Bit 5 indicates whether first block is coded
- for (blk = 0; blk < 6; ++blk) {
- if (cbp & mask) {
- state = startState;
- status = VLDECODE( *bs, *maxBits, &state, &parsed_bits,
- &nsym, &sym[isym], maxsym - isym );
- if (status != FINISHED_LAST_BLOCK) return( H261_ERROR );
- IncBsPtr( bs, parsed_bits );
- *maxBits -= parsed_bits;
- status = parseSymbols( &sym[isym], nsym, &sym[isym] );
- if (status == H261_ERROR) return( H261_ERROR );
- block[blk].sym = &sym[isym];
- block[blk].nsym = status;
- isym += status;
- } else if (intraFlag && !advancedIntraMode) { // Decode INTRA-DC
- if (VLDecSymbol( bs, TAB263_INTRA_DC, maxBits, &sym[isym] ) != OK) {
- return( H261_ERROR );
- }
- block[blk].sym = &sym[isym];
- block[blk].nsym = 1;
- ++isym;
- } else { // No coeffs
- block[blk].nsym = 0;
- }
- mask >>= 1; // Check next block
- }
- return( isym );
- }
- // parseSymbols - 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
- )
- {
- int iIn, iOut, zzpos, last, run;
- BS_ERR_MSG ( char msg[120] ); /* Flawfinder: ignore */
-
- iIn = 0, iOut = 0, zzpos = 0;
- while (iIn < nsym) {
- if (insym[iIn].type == SYM_ESC_RUN) { // Encountered ESCAPE-LAST-RUN-LEVEL symbol
- last = insym[iIn].value & 0x40; // LAST is found in bit 6
- run = insym[iIn++].value & 0x3f; // RUN in bits 0-5
- outsym[iOut].type = run;
- CHECKSYM( if (checksym( insym[iIn], SYM_ESC_LEVEL, "parseSymbols") != OK) return(H261_ERROR);)
- outsym[iOut++].value = insym[iIn++].value;
- } else {
- last = insym[iIn].type & 0x40; // LAST is found in bit 6
- run = insym[iIn].type & 0x3f; // RUN in bits 0-5
- outsym[iOut].type = run;
- outsym[iOut++].value = insym[iIn++].value;
- }
- zzpos += run + 1;
- //printf("parseSymbols: "); printsym(outsym[iOut-1 ); printf(" zzpos = %dn", zzpos);
- if (zzpos > 64) { // If we decoded coeff. 63, we will now have zzpos=64
- BS_ERR_MSG( sprintf( msg, "parseSymbols: Bitstream error, zzpos=%d", zzpos); /* Flawfinder: ignore */
- H261ErrMsg( msg ); )
- return (H261_ERROR);
- }
- if (last != 0 && iIn < nsym) {
- H261ErrMsg( "parseSymbols: Encountered LAST=1 prematurely" );
- return (H261_ERROR);
- }
- }
- /*{
- int i;
- static int iprint = YES;
- if (iprint) {
- printf("parseSymbols: Found %d symbolsn", iOut);
- for (i = 0; i < iOut; ++i) {
- printf("Symbol %d: ", i);
- printsym( outsym[i] );
- printf("n");
- }
- printf("parseSymbols: Continue printouts? [0/1]: ");
- scanf("%d", &iprint);
- }
- }*/
- if (last != LAST263_RUNVAL || iIn != nsym) {
- H261ErrMsg( "parseSymbols: Did not find LAST=1" );
- return (H261_ERROR);
- }
- return (iOut);
- }