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