h263dec.c

来自「symbian 下的helix player源代码」· C语言 代码 · 共 758 行 · 第 1/3 页

C
758
字号

    // 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
            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 = %d\n", 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:

⌨️ 快捷键说明

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