📄 h263dec.c
字号:
} 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: 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 vectorsstatic 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 decoderstatic 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-frameextern 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 macroblockstatic 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 symbolsstatic 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -