--- mbcoding.c 2002/09/04 03:23:28 1.25 +++ mbcoding.c 2002/12/20 05:49:55 1.25.2.7 @@ -41,6 +41,7 @@ * * * Revision history: * * * + * 28.10.2002 GMC support - gruel * * 28.06.2002 added check_resync_marker() * * 14.04.2002 bframe encoding * * 08.03.2002 initial version; isibaar * @@ -61,12 +62,41 @@ #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 +213,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 +399,7 @@ static void -CodeBlockInter(const FRAMEINFO * frame, +CodeBlockInter(const FRAMEINFO * const frame, const MACROBLOCK * pMB, int16_t qcoeff[6 * 64], Bitstream * bs, @@ -353,6 +408,7 @@ int32_t i; uint32_t bits, mcbpc, cbpy; + int mcsel=0; mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3); cbpy = 15 - (pMB->cbp >> 2); @@ -361,6 +417,18 @@ 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) ) + { + if (frame->quarterpel) { + if ( (pMB->qmvs[0].x == frame->GMC_MV.x) && (pMB->qmvs[0].y == frame->GMC_MV.y) ) + mcsel=1; + } else { + if ( (pMB->mvs[0].x == frame->GMC_MV.x) && (pMB->mvs[0].y == frame->GMC_MV.y) ) + mcsel=1; + } + BitstreamPutBit(bs, mcsel); // mcsel: '0'=local motion, '1'=GMC + } + // write cbpy BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len); @@ -372,13 +440,13 @@ if (frame->global_flags & XVID_INTERLACING) { if (pMB->cbp) { BitstreamPutBit(bs, pMB->field_dct); - DEBUG1("codep: field_dct: ", 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) { @@ -387,37 +455,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 (mcsel==0) + 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) { - 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 @@ -425,14 +497,14 @@ } - +/* +// moved to mbcoding.h so that in can be 'static __inline' void MBSkip(Bitstream * bs) { BitstreamPutBit(bs, 1); // not coded - return; } - +*/ /*************************************************************** * bframe encoding start @@ -446,37 +518,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; } - } /* @@ -486,7 +543,7 @@ +2 11b */ -void +static __inline void put_bvop_dbquant(Bitstream * bs, int value) { @@ -517,9 +574,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) @@ -549,24 +608,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); } } } @@ -649,7 +709,7 @@ } -int +static __inline int get_mv_data(Bitstream * bs) { @@ -766,14 +826,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,7 +841,7 @@ //DPRINTF(DPRINTF_COEFF,"block[%i] %i %08x", scan[coeff], level, BitstreamShowBits(bs, 32)); if (level < -127 || level > 127) { - DEBUG1("warning: intra_overflow", level); + DPRINTF(DPRINTF_ERROR,"warning: intra_overflow %i", level); } coeff++; } while (!last); @@ -792,10 +850,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; @@ -805,7 +864,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,7 +875,7 @@ // DPRINTF(DPRINTF_COEFF,"block[%i] %i %08x", scan[p], level, BitstreamShowBits(bs, 32)); if (level < -127 || level > 127) { - DEBUG1("warning: inter_overflow", level); + DPRINTF(DPRINTF_ERROR,"warning: inter overflow %i", level); } p++; } while (!last);