h263dec.c

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

C
758
字号
                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 = %d\n", 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 = %d\n", 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 symbols\n", 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);
}

⌨️ 快捷键说明

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