📄 h261dec.c
字号:
} isym += status; // We expect MBA, MBA Stuffing, or Startcode while (sym[nextsym].type == SYM_MBA_STUFFING) { ++nextsym; // Remove MBA stuffing } } for (i = mbnum + 1; i <= gob->num_mb; i++) { mb[i-1].mtype = MTYPE_SKIP; } return (OK);}// insym[*nextsym] contains MTYPE when we enterstatic int decode_mb( SYMBOL insym[], int * nextsym, int * quant, GOB_DESCR * gob, MACROBLOCK_DESCR mb[], int mbnum, SYMBOL outsym[]){ int isym, blk, status, mask; CHECKSYM ( char msg[120] ); /* Flawfinder: ignore */ //printf("decode_mb: "); printsym( insym[*nextsym] ); printf("\n"); isym = 0; CHECKSYM( if (checksym( insym[*nextsym], SYM_MTYPE, "decode_mb") != OK) exit(0); ) mb[mbnum].mtype = insym[(*nextsym)++].value; switch ( mb[mbnum].mtype ) { case MTYPE_INTER_MQUANT: CHECKSYM( if (checksym( insym[*nextsym], SYM_QUANT_TR, "decode_mb") != OK) exit(0); ) *quant = insym[(*nextsym)++].value; if (*quant < QUANT_MIN || *quant > QUANT_MAX) { BS_ERR_MSG( sprintf( msg, "decode_mb: quant = %d", *quant); /* Flawfinder: ignore */ H261ErrMsg( msg ); ) return (H261_ERROR); } // FALLTHROUGH case MTYPE_INTER: CHECKSYM( if (checksym( insym[*nextsym], SYM_CBP, "decode_mb") != OK) exit(0); ) mb[mbnum].cbp = insym[(*nextsym)++].value; mask = 0x20; // Bitmask for first block for (blk = 0; blk < 6; blk++) { mb[mbnum].block[blk].nsym = 0; if ((mb[mbnum].cbp & mask) != 0) { status = decode_block( insym, nextsym, &(mb[mbnum].block[blk]), &outsym[isym] ); if (status == H261_ERROR) { BS_ERR_MSG( sprintf( msg, "decode_mb: Bitstream error, block #%d", blk); /* Flawfinder: ignore */ H261ErrMsg( msg ); ) return (H261_ERROR); } isym += status; } mask >>= 1; } break; case MTYPE_MCFILT_MQUANT: case MTYPE_MC_MQUANT: CHECKSYM( if (checksym( insym[*nextsym], SYM_QUANT_TR, "decode_mb") != OK) exit(0); ) *quant = insym[(*nextsym)++].value; if (*quant < QUANT_MIN || *quant > QUANT_MAX) { BS_ERR_MSG( sprintf( msg, "decode_mb: quant = %d", *quant); /* Flawfinder: ignore */ H261ErrMsg( msg ); ) return (H261_ERROR); } // FALLTHROUGH case MTYPE_MCFILT_CBP: case MTYPE_MC_CBP: CHECKSYM( if (checksym( insym[*nextsym], SYM_MVD, "decode_mb") != OK) exit(0); ) mb[mbnum].mvd_x = insym[(*nextsym)++].value; CHECKSYM( if (checksym( insym[*nextsym], SYM_MVD, "decode_mb") != OK) exit(0); ) mb[mbnum].mvd_y = insym[(*nextsym)++].value; if (mbnum % gob->mb_width > 0 && mb[mbnum-1].mtype >= MTYPE_MC_NOCBP) { mb[mbnum].mv_x = mb[mbnum-1].mv_x + mb[mbnum].mvd_x; mb[mbnum].mv_y = mb[mbnum-1].mv_y + mb[mbnum].mvd_y; } else { mb[mbnum].mv_x = mb[mbnum].mvd_x; mb[mbnum].mv_y = mb[mbnum].mvd_y; } CHECKSYM( if (checksym( insym[*nextsym], SYM_CBP, "decode_mb") != OK) exit(0); ) mb[mbnum].cbp = insym[(*nextsym)++].value; mask = 0x20; // Bitmask for first block for (blk = 0; blk < 6; blk++) { mb[mbnum].block[blk].nsym = 0; if ((mb[mbnum].cbp & mask) != 0) { status = decode_block( insym, nextsym, &(mb[mbnum].block[blk]), &outsym[isym] ); if (status == H261_ERROR) { BS_ERR_MSG( sprintf( msg, "decode_mb: Bitstream error, block #%d", blk); /* Flawfinder: ignore */ H261ErrMsg( msg ); ) return (H261_ERROR); } isym += status; } mask >>= 1; } break; case MTYPE_MCFILT_NOCBP: case MTYPE_MC_NOCBP: CHECKSYM( if (checksym( insym[*nextsym], SYM_MVD, "decode_mb") != OK) exit(0); ) mb[mbnum].mvd_x = insym[(*nextsym)++].value; CHECKSYM( if (checksym( insym[*nextsym], SYM_MVD, "decode_mb") != OK) exit(0); ) mb[mbnum].mvd_y = insym[(*nextsym)++].value; if (mbnum % gob->mb_width > 0 && mb[mbnum-1].mtype >= MTYPE_MC_NOCBP) { mb[mbnum].mv_x = mb[mbnum-1].mv_x + mb[mbnum].mvd_x; mb[mbnum].mv_y = mb[mbnum-1].mv_y + mb[mbnum].mvd_y; } else { mb[mbnum].mv_x = mb[mbnum].mvd_x; mb[mbnum].mv_y = mb[mbnum].mvd_y; } break; case MTYPE_INTRA_MQUANT: CHECKSYM( if (checksym( insym[*nextsym], SYM_QUANT_TR, "decode_mb") != OK) exit(0); ) *quant = insym[(*nextsym)++].value; if (*quant < QUANT_MIN || *quant > QUANT_MAX) { BS_ERR_MSG( sprintf( msg, "decode_mb: quant = %d", *quant); /* Flawfinder: ignore */ H261ErrMsg( msg ); ) return (H261_ERROR); } // FALLTHROUGH case MTYPE_INTRA: for (blk = 0; blk < 6; blk++) { status = decode_intra_block( insym, nextsym, &(mb[mbnum].block[blk]), &outsym[isym] ); if (status == H261_ERROR) { BS_ERR_MSG( sprintf( msg, "decode_mb: Bitstream error, block #%d", blk); /* Flawfinder: ignore */ H261ErrMsg( msg ); ) return (H261_ERROR); } isym += status; } break; default: // Illegal MTYPE is due to program error; not from bit errors CHECKSYM( sprintf( msg, "decode_mb: MTYPE = %d", mb[mbnum].mtype); /* Flawfinder: ignore */ H261ErrMsg( msg ); ) return (H261_ERROR); break; } mb[mbnum].quant = *quant; return (isym);}static int decode_intra_block( SYMBOL insym[], int * nextsym, BLOCK_DESCR * block, SYMBOL outsym[]){ int isym, zzpos, run; CHECKSYM ( char msg[120] ); /* Flawfinder: ignore */ /* DC coefficient */ //printf("decode_intra_block DC: "); printsym( insym[*nextsym] ); printf("\n"); CHECKSYM( if (checksym( insym[*nextsym], SYM_INTRA_DC, "decode_intra") != OK) exit(0); ) outsym[0].type = 0; outsym[0].value = insym[(*nextsym)++].value; /* AC coefficients */ isym = 1; zzpos = 1; //printf("decode_intra_block AC: "); printsym( insym[*nextsym] ); printf("\n"); while (insym[*nextsym].type != SYM_EOB) { if (insym[*nextsym].type == SYM_ESC_RUN) { run = insym[(*nextsym)++].value; outsym[isym].type = run; CHECKSYM( if (checksym( insym[*nextsym], SYM_ESC_LEVEL, "decode_intra") != OK) exit(0); ) outsym[isym++].value = insym[(*nextsym)++].value; } else { run = insym[*nextsym].type; CHECKSYM( if (run < 0) { sprintf( msg, "PROGRAM ERROR: run = %d in decode_intra", run); /* Flawfinder: ignore */ H261ErrMsg( msg ); return( H261_ERROR ); } ) outsym[isym++] = insym[(*nextsym)++]; } zzpos += run + 1;// printf("decode_intra_block AC: "); printsym( insym[*nextsym] );// printf(" zzpos = %d\n", zzpos); if (zzpos > 64) { // If we decoded coeff. 63, we will now have zzpos=64 BS_ERR_MSG( sprintf( msg, "decode_intra_block: Bitstream error, zzpos=%d", zzpos); /* Flawfinder: ignore */ H261ErrMsg( msg ); ) return (H261_ERROR); } } (*nextsym)++; /* Advance pointer to symbol after EOB */ block->sym = outsym; block->nsym = isym; return (isym);}/* Compute # bits in segment bs1 - bs2 */extern int BsDiff( BS_PTR bs1, BS_PTR bs2 ){ int bits; bits = 8 * (bs1.byteptr - bs2.byteptr) + bs1.bitptr - bs2.bitptr; return (bits);}static int find_startcodes( BS_PTR * bs, // Points to beginning of bitstream int numbits, // length of bitstream in bits BS_PTR start[], // Returns positions for startcodes; size "max_start" int gobnum[], // Returns 4 bits after startcode (5 bits for H.263); size "max_start" int max_start, // Max number of start codes to be returned int codingMethod ) // Indicate H.261 or H.263 syntax{ int i, bits_left, startZeros, gnBits; BS_PTR bs_next; if (codingMethod == H263_CODING) { startZeros = H263_START_ZEROS; gnBits = H263_GN_BITS; } else { // H.261 startZeros = H261_START_ZEROS; gnBits = H261_GN_BITS; } i = 0; bs_next = *bs; while (i < max_start) { bits_left = numbits - BsDiff( bs_next, *bs); if (find_sc( &bs_next, bits_left, startZeros, &start[i] ) != YES) { return (i); } gobnum[i] = Get8Bits( start[i] ) >> (8 - gnBits); bs_next = start[i]; i++; } return (max_start);}static U8 leading[256];static U8 trailing[256];extern void InitFindSC( void ){ int i, j, bitmask; for (i = 0; i < 256; i++) { leading[i] = 0; bitmask = 0x80; for (j = 0; j < 8; j++) { if ((i & bitmask) != 0) { break; } bitmask >>= 1; ++leading[i]; } trailing[i] = 0; bitmask = 0x1; for (j = 0; j < 8; j++) { if ((i & bitmask) != 0) { break; } bitmask <<= 1; ++trailing[i]; } //printf("%3x: Leading = %d Trailing = %d\n", i, leading[i], trailing[i]); } return;}// find_sc - Find startcode consisting of startZeros zeros followed by 1// Returns YES if startcode found, otherwise NO// Operates on byte boundaries; might not look at last 8 bits in bitstreamstatic int find_sc( BS_PTR * bs, // Points to beginning of bitstream int numbits, // length of bitstream in bits int startZeros, // number of zeros in startcode BS_PTR * start ) // Returns position for bit after startcode{ int zeros, nbytes, i, validBitsInLastByte; U8 b; /* Read first byte from bitstream; set "irrelevant bits" to 1 */ b = *bs->byteptr | (0xff & (0xff << (8 - bs->bitptr))); zeros = trailing[b];// nbytes = (numbits + bs->bitptr - 8 - max(H263_GN_BITS, H261_GN_BITS) ) >> 3; nbytes = (numbits + bs->bitptr - 1 ) >> 3; validBitsInLastByte = (numbits + bs->bitptr) &07; if (validBitsInLastByte == 0) validBitsInLastByte = 8; start->byteptr = bs->byteptr + 1; for (i = 0; i < nbytes; i++) { b = *start->byteptr; zeros += leading[b]; if (zeros < startZeros && b != 0) { zeros = trailing[b]; } else if (b != 0) { /* Found startcode */ start->bitptr = leading[b] + 1; if (i == nbytes - 1 && start->bitptr + H263_GN_BITS > validBitsInLastByte || i == nbytes - 2 && start->bitptr + H263_GN_BITS > 8 + validBitsInLastByte) return(NO); if (start->bitptr > 7) { ++(start->byteptr); start->bitptr -= 8; } return (YES); } /* else: b=0; continue until 1 is found */ ++(start->byteptr); } return (NO);}#ifdef TESTING/////////// Routines for debugging //////////////extern int checksym( SYMBOL sym, int type, char routine[] ){ char msg[120], csym[80], ctype[80]; /* Flawfinder: ignore */ if (sym.type == type) { return (OK); } else { // Not expected type sprintsym( sym , csym, 80); sprinttype( type, ctype, 80); SafeSprintf(msg, 120, "%s: Encountered %s Expected %s", routine, csym, ctype); H261ErrMsg( msg );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -