--- trunk/xvidcore/src/bitstream/mbcoding.c 2002/09/08 14:43:04 451 +++ trunk/xvidcore/src/bitstream/mbcoding.c 2002/09/21 02:26:12 497 @@ -1,7 +1,7 @@ /***************************************************************************** * * XVID MPEG-4 VIDEO CODEC - * - Vector Length Coding tables - + * - Macro Block coding functions - * * Copyright(C) 2002 Michael Militzer * @@ -29,7 +29,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: mbcoding.c,v 1.26 2002-09-08 14:43:04 edgomez Exp $ + * $Id: mbcoding.c,v 1.31 2002-09-21 02:26:12 suxen_drol Exp $ * ****************************************************************************/ @@ -49,14 +49,15 @@ * Local data ****************************************************************************/ -static VLC intra_table[524032]; -static VLC inter_table[524032]; +/* msvc sp5+pp gets confused if they globals are made static */ +VLC intra_table[524032]; +VLC inter_table[524032]; static VLC DCT3Dintra[4096]; static VLC DCT3Dinter[4096]; /***************************************************************************** - * Functions + * Vector Length Coding Initialization ****************************************************************************/ void @@ -65,7 +66,7 @@ int32_t k, l, i, intra, last; VLC *vlc[2]; - VLC **coeff_ptr; + VLC const **coeff_ptr; VLC *vlc1, *vlc2; vlc1 = DCT3Dintra; @@ -86,8 +87,8 @@ coeff_ptr = coeff_vlc[last + 2 * intra]; for (k = -2047; k < 2048; k++) { // level - int8_t *max_level_ptr = max_level[last + 2 * intra]; - int8_t *max_run_ptr = max_run[last + 2 * intra]; + int8_t const *max_level_ptr = max_level[last + 2 * intra]; + int8_t const *max_run_ptr = max_run[last + 2 * intra]; for (l = 0; l < 64; l++) { // run int32_t level = k; @@ -180,6 +181,10 @@ } +/***************************************************************************** + * Local inlined functions for MB coding + ****************************************************************************/ + static __inline void CodeVector(Bitstream * bs, int32_t value, @@ -235,7 +240,6 @@ } - static __inline void CodeCoeff(Bitstream * bs, const int16_t qcoeff[64], @@ -274,6 +278,9 @@ } +/***************************************************************************** + * Local functions + ****************************************************************************/ static void CodeBlockIntra(const FRAMEINFO * frame, @@ -400,6 +407,9 @@ } +/***************************************************************************** + * Macro Block bitstream encoding functions + ****************************************************************************/ void MBCoding(const FRAMEINFO * frame, @@ -428,155 +438,17 @@ return; } - -/*************************************************************** - * bframe encoding start - ***************************************************************/ - -/* - mbtype - 0 1b direct(h263) mvdb - 1 01b interpolate mc+q dbquant, mvdf, mvdb - 2 001b backward mc+q dbquant, mvdb - 3 0001b forward mc+q dbquant, mvdf -*/ - -void -put_bvop_mbtype(Bitstream * bs, - int value) -{ - switch (value) { - case 0: - BitstreamPutBit(bs, 1); - return; - - case 1: - BitstreamPutBit(bs, 0); - BitstreamPutBit(bs, 1); - return; - - case 2: - BitstreamPutBit(bs, 0); - BitstreamPutBit(bs, 0); - BitstreamPutBit(bs, 1); - return; - - case 3: - BitstreamPutBit(bs, 0); - BitstreamPutBit(bs, 0); - BitstreamPutBit(bs, 0); - BitstreamPutBit(bs, 1); - return; - - default:; // invalid! - - } - -} +/***************************************************************************** + * decoding stuff starts here + ****************************************************************************/ /* - dbquant - -2 10b - 0 0b - +2 11b -*/ - -void -put_bvop_dbquant(Bitstream * bs, - int value) -{ - switch (value) { - case 0: - BitstreamPutBit(bs, 0); - return; - - case -2: - BitstreamPutBit(bs, 1); - BitstreamPutBit(bs, 0); - return; - - case 2: - BitstreamPutBit(bs, 1); - BitstreamPutBit(bs, 1); - return; - - default:; // invalid - } -} - - - -void -MBCodingBVOP(const MACROBLOCK * mb, - const int16_t qcoeff[6 * 64], - const int32_t fcode, - const int32_t bcode, - Bitstream * bs, - Statistics * pStat) -{ - int i; - -/* ------------------------------------------------------------------ - when a block is skipped it is decoded DIRECT(0,0) - hence is interpolated from forward & backward frames - ------------------------------------------------------------------ */ - - if (mb->mode == MODE_DIRECT_NONE_MV) { - BitstreamPutBit(bs, 1); // skipped - return; - } - - BitstreamPutBit(bs, 0); // not skipped - - if (mb->cbp == 0) { - BitstreamPutBit(bs, 1); // cbp == 0 - } else { - BitstreamPutBit(bs, 0); // cbp == xxx - } - - put_bvop_mbtype(bs, mb->mode); - - if (mb->cbp) { - BitstreamPutBits(bs, mb->cbp, 6); - } - - if (mb->mode != MODE_DIRECT && mb->cbp != 0) { - put_bvop_dbquant(bs, 0); // todo: mb->dquant = 0 - } - - if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_FORWARD) { - CodeVector(bs, mb->pmvs[0].x, fcode, pStat); - CodeVector(bs, mb->pmvs[0].y, fcode, pStat); - } + * For IVOP addbits == 0 + * For PVOP addbits == fcode - 1 + * For BVOP addbits == max(fcode,bcode) - 1 + * returns true or false + */ - if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_BACKWARD) { - CodeVector(bs, mb->b_pmvs[0].x, bcode, pStat); - CodeVector(bs, mb->b_pmvs[0].y, bcode, pStat); - } - - if (mb->mode == MODE_DIRECT) { - CodeVector(bs, mb->deltamv.x, 1, pStat); /* fcode is always 1 for delta vector */ - CodeVector(bs, mb->deltamv.y, 1, pStat); /* prediction is always (0,0) */ - } - - for (i = 0; i < 6; i++) { - if (mb->cbp & (1 << (5 - i))) { - CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_tables[0], 0); - } - } -} - - - -/*************************************************************** - * decoding stuff starts here * - ***************************************************************/ - - -// for IVOP addbits == 0 -// for PVOP addbits == fcode - 1 -// for BVOP addbits == max(fcode,bcode) - 1 -// returns true or false int check_resync_marker(Bitstream * bs, int addbits) { @@ -753,6 +625,105 @@ } +/***************************************************************************** + * Local inlined function to "decode" written vlc codes + ****************************************************************************/ + +static __inline int +get_coeff(Bitstream * bs, + int *run, + int *last, + int intra, + int short_video_header) +{ + + uint32_t mode; + const VLC *tab; + int32_t level; + + if (short_video_header) // inter-VLCs will be used for both intra and inter blocks + intra = 0; + + tab = &DCT3D[intra][BitstreamShowBits(bs, 12)]; + + if (tab->code == -1) + goto error; + + BitstreamSkip(bs, tab->len); + + if (tab->code != ESCAPE) { + if (!intra) { + *run = (tab->code >> 4) & 255; + level = tab->code & 15; + *last = (tab->code >> 12) & 1; + } else { + *run = (tab->code >> 8) & 255; + level = tab->code & 255; + *last = (tab->code >> 16) & 1; + } + return BitstreamGetBit(bs) ? -level : level; + } + + if (short_video_header) { + // escape mode 4 - H.263 type, only used if short_video_header = 1 + *last = BitstreamGetBit(bs); + *run = BitstreamGetBits(bs, 6); + level = BitstreamGetBits(bs, 8); + + if (level == 0 || level == 128) + DEBUG1("Illegal LEVEL for ESCAPE mode 4:", level); + + return (level >= 128 ? -(256 - level) : level); + } + + mode = BitstreamShowBits(bs, 2); + + if (mode < 3) { + BitstreamSkip(bs, (mode == 2) ? 2 : 1); + + tab = &DCT3D[intra][BitstreamShowBits(bs, 12)]; + if (tab->code == -1) + goto error; + + BitstreamSkip(bs, tab->len); + + if (!intra) { + *run = (tab->code >> 4) & 255; + level = tab->code & 15; + *last = (tab->code >> 12) & 1; + } else { + *run = (tab->code >> 8) & 255; + level = tab->code & 255; + *last = (tab->code >> 16) & 1; + } + + if (mode < 2) // first escape mode, level is offset + level += max_level[*last + (!intra << 1)][*run]; // need to add back the max level + else if (mode == 2) // second escape mode, run is offset + *run += max_run[*last + (!intra << 1)][level] + 1; + + return BitstreamGetBit(bs) ? -level : level; + } + // third escape mode - fixed length codes + BitstreamSkip(bs, 2); + *last = BitstreamGetBits(bs, 1); + *run = BitstreamGetBits(bs, 6); + BitstreamSkip(bs, 1); // marker + level = BitstreamGetBits(bs, 12); + BitstreamSkip(bs, 1); // marker + + return (level & 0x800) ? (level | (-1 ^ 0xfff)) : level; + + error: + *run = VLC_ERROR; + return 0; + +} + +/***************************************************************************** + * MB reading functions + ****************************************************************************/ + void get_intra_block(Bitstream * bs, int16_t * block,