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