--- trunk/xvidcore/src/bitstream/mbcoding.c 2002/07/24 23:07:45 338 +++ branches/dev-api-3/xvidcore/src/bitstream/mbcoding.c 2003/01/11 14:59:24 769 @@ -41,6 +41,7 @@ * * * Revision history: * * * + * 04.01.2003 GMC support - gruel * * 28.06.2002 added check_resync_marker() * * 14.04.2002 bframe encoding * * 08.03.2002 initial version; isibaar * @@ -48,9 +49,10 @@ ******************************************************************************/ - +#include #include #include "../portab.h" +#include "../global.h" #include "bitstream.h" #include "zigzag.h" #include "vlc_codes.h" @@ -58,15 +60,41 @@ #include "../utils/mbfunctions.h" -#define ABS(X) (((X)>0)?(X):-(X)) -#define CLIP(X,A) (X > A) ? (A) : (X) - -VLC intra_table[524032]; -VLC inter_table[524032]; +VLC intra_table[4*2048*64]; +VLC inter_table[4*2048*64]; VLC DCT3Dintra[4096]; VLC DCT3Dinter[4096]; +/* not really MB related, but VLCs are only available here */ +void bs_put_spritetrajectory(Bitstream * bs, const int val) +{ + const int code = sprite_trajectory_code[val+16384].code; + const int len = sprite_trajectory_code[val+16384].len; + const int code2 = sprite_trajectory_len[len].code; + const int len2 = sprite_trajectory_len[len].len; + +// printf("GMC=%d Code/Len = %d / %d ",val, code,len); +// printf("Code2 / Len2 = %d / %d \n",code2,len2); + + BitstreamPutBits(bs, code2, len2); + if (len) BitstreamPutBits(bs, code, len); +} + +int bs_get_spritetrajectory(Bitstream * bs) +{ + int i; + for (i = 0; i < 12; i++) + { + if (BitstreamShowBits(bs, sprite_trajectory_len[i].len) == sprite_trajectory_len[i].code) + { + BitstreamSkip(bs, sprite_trajectory_len[i].len); + return i; + } + } + return -1; +} + void init_vlc_tables(void) { @@ -183,6 +211,28 @@ DCT3D[0] = DCT3Dinter; DCT3D[1] = DCT3Dintra; + +/* init sprite_trajectory tables */ +/* even if GMC is not specified (it might be used later...) */ + + sprite_trajectory_code[0+16384].code = 0; + sprite_trajectory_code[0+16384].len = 0; + for (k=0;k<14;k++) + { + int limit = (1<cbp & (1 << (5 - i))) { + const uint16_t *scan_table = + frame->global_flags & XVID_ALTERNATESCAN ? + scan_tables[2] : scan_tables[pMB->acpred_directions[i]]; + bits = BitstreamPos(bs); - CodeCoeff(bs, &qcoeff[i * 64], intra_table, - scan_tables[pMB->acpred_directions[i]], 1); + CodeCoeff(bs, &qcoeff[i * 64], intra_table, scan_table, 1); bits = BitstreamPos(bs) - bits; pStat->iTextBits += bits; @@ -344,7 +397,7 @@ static void -CodeBlockInter(const FRAMEINFO * frame, +CodeBlockInter(const FRAMEINFO * const frame, const MACROBLOCK * pMB, int16_t qcoeff[6 * 64], Bitstream * bs, @@ -361,6 +414,12 @@ BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code, mcbpc_inter_tab[mcbpc].len); + if ( (frame->coding_type == S_VOP) && (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) ) + { + /* decision on GMC is done in encoder.c now */ + BitstreamPutBit(bs, pMB->mcsel); // mcsel: '0'=local motion, '1'=GMC + } + // write cbpy BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len); @@ -370,13 +429,15 @@ // interlacing if (frame->global_flags & XVID_INTERLACING) { - BitstreamPutBit(bs, pMB->field_dct); - DEBUG1("codep: field_dct: ", pMB->field_dct); + if (pMB->cbp) { + BitstreamPutBit(bs, pMB->field_dct); + DPRINTF(DPRINTF_MB,"codep: field_dct: %i", pMB->field_dct); + } // if inter block, write field ME flag if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) { BitstreamPutBit(bs, pMB->field_pred); - DEBUG1("codep: field_pred: ", pMB->field_pred); + DPRINTF(DPRINTF_MB,"codep: field_pred: %i", pMB->field_pred); // write field prediction references if (pMB->field_pred) { @@ -385,49 +446,41 @@ } } } - // code motion vector(s) - for (i = 0; i < (pMB->mode == MODE_INTER4V ? 4 : 1); i++) { - CodeVector(bs, pMB->pmvs[i].x, frame->fcode, pStat); - CodeVector(bs, pMB->pmvs[i].y, frame->fcode, pStat); - } + // code motion vector(s) if motion is local + if (!pMB->mcsel) + for (i = 0; i < (pMB->mode == MODE_INTER4V ? 4 : 1); i++) { + CodeVector(bs, pMB->pmvs[i].x, frame->fcode, pStat); + CodeVector(bs, pMB->pmvs[i].y, frame->fcode, pStat); + } bits = BitstreamPos(bs); // code block coeffs for (i = 0; i < 6; i++) if (pMB->cbp & (1 << (5 - i))) - CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_tables[0], 0); + { + const uint16_t *scan_table = + frame->global_flags & XVID_ALTERNATESCAN ? + scan_tables[2] : scan_tables[0]; + + CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_table, 0); + } bits = BitstreamPos(bs) - bits; pStat->iTextBits += bits; - } void -MBCoding(const FRAMEINFO * frame, +MBCoding(const FRAMEINFO * const frame, MACROBLOCK * pMB, int16_t qcoeff[6 * 64], Bitstream * bs, Statistics * pStat) { - - if (frame->coding_type == P_VOP) { - if (pMB->cbp == 0 && pMB->mode == MODE_INTER && pMB->mvs[0].x == 0 && - pMB->mvs[0].y == 0) { - -#ifdef _DISABLE_SKIP -/* disable SKIP when Bframes active until some workaround for the B-SKIP problem is found */ - BitstreamPutBit(bs, 0); // always coded! -#else - BitstreamPutBit(bs, 1); // not_coded - - return; -#endif - } else - BitstreamPutBit(bs, 0); // coded - } - + if (frame->coding_type != I_VOP) + BitstreamPutBit(bs, 0); // not_coded + if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q) CodeBlockIntra(frame, pMB, qcoeff, bs, pStat); else @@ -435,6 +488,15 @@ } +/* +// moved to mbcoding.h so that in can be 'static __inline' +void +MBSkip(Bitstream * bs) +{ + BitstreamPutBit(bs, 1); // not coded +} +*/ + /*************************************************************** * bframe encoding start ***************************************************************/ @@ -447,37 +509,22 @@ 3 0001b forward mc+q dbquant, mvdf */ -void +static __inline 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! - + case MODE_FORWARD: + BitstreamPutBit(bs, 0); + case MODE_BACKWARD: + BitstreamPutBit(bs, 0); + case MODE_INTERPOLATE: + BitstreamPutBit(bs, 0); + case MODE_DIRECT: + BitstreamPutBit(bs, 1); + default: + break; } - } /* @@ -487,7 +534,7 @@ +2 11b */ -void +static __inline void put_bvop_dbquant(Bitstream * bs, int value) { @@ -518,9 +565,11 @@ const int32_t fcode, const int32_t bcode, Bitstream * bs, - Statistics * pStat) + Statistics * pStat, + int direction) { - int i; + int vcode = fcode; + unsigned int i; /* ------------------------------------------------------------------ when a block is skipped it is decoded DIRECT(0,0) @@ -550,24 +599,25 @@ 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); - } - - 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) */ + switch (mb->mode) { + case MODE_INTERPOLATE: + CodeVector(bs, mb->pmvs[1].x, vcode, pStat); //forward vector of interpolate mode + CodeVector(bs, mb->pmvs[1].y, vcode, pStat); + case MODE_BACKWARD: + vcode = bcode; + case MODE_FORWARD: + CodeVector(bs, mb->pmvs[0].x, vcode, pStat); + CodeVector(bs, mb->pmvs[0].y, vcode, pStat); + break; + case MODE_DIRECT: + CodeVector(bs, mb->pmvs[3].x, 1, pStat); // fcode is always 1 for delta vector + CodeVector(bs, mb->pmvs[3].y, 1, pStat); // prediction is always (0,0) + default: break; } for (i = 0; i < 6; i++) { if (mb->cbp & (1 << (5 - i))) { - CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_tables[0], 0); + CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_tables[direction], 0); } } } @@ -624,7 +674,7 @@ uint32_t index; - index = CLIP(BitstreamShowBits(bs, 9), 256); + index = MIN(BitstreamShowBits(bs, 9), 256); BitstreamSkip(bs, mcbpc_inter_table[index].len); @@ -650,7 +700,7 @@ } -int +static __inline int get_mv_data(Bitstream * bs) { @@ -767,14 +817,12 @@ { const uint16_t *scan = scan_tables[direction]; - int level; - int run; - int last; + int level, run, last; do { level = get_coeff(bs, &run, &last, 1, 0); if (run == -1) { - DEBUG("fatal: invalid run"); + DPRINTF(DPRINTF_ERROR,"fatal: invalid run"); break; } coeff += run; @@ -783,8 +831,8 @@ DPRINTF(DPRINTF_COEFF,"block[%i] %i", scan[coeff], level); //DPRINTF(DPRINTF_COEFF,"block[%i] %i %08x", scan[coeff], level, BitstreamShowBits(bs, 32)); - if (level < -127 || level > 127) { - DEBUG1("warning: intra_overflow", level); + if (level < -2047 || level > 2047) { + DPRINTF(DPRINTF_ERROR,"warning: intra_overflow %i", level); } coeff++; } while (!last); @@ -793,10 +841,11 @@ void get_inter_block(Bitstream * bs, - int16_t * block) + int16_t * block, + int direction) { - const uint16_t *scan = scan_tables[0]; + const uint16_t *scan = scan_tables[direction]; int p; int level; int run; @@ -806,7 +855,7 @@ do { level = get_coeff(bs, &run, &last, 0, 0); if (run == -1) { - DEBUG("fatal: invalid run"); + DPRINTF(DPRINTF_ERROR,"fatal: invalid run"); break; } p += run; @@ -816,8 +865,8 @@ DPRINTF(DPRINTF_COEFF,"block[%i] %i", scan[p], level); // DPRINTF(DPRINTF_COEFF,"block[%i] %i %08x", scan[p], level, BitstreamShowBits(bs, 32)); - if (level < -127 || level > 127) { - DEBUG1("warning: inter_overflow", level); + if (level < -2047 || level > 2047) { + DPRINTF(DPRINTF_ERROR,"warning: inter overflow %i", level); } p++; } while (!last);