--- mbcoding.c 2002/09/04 03:23:28 1.25 +++ mbcoding.c 2002/11/02 15:52:30 1.25.2.3 @@ -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 * @@ -67,6 +68,23 @@ VLC DCT3Dintra[4096]; VLC DCT3Dinter[4096]; +/* not really MB related, but VLCs are only available here */ +void inline 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); +} + + void init_vlc_tables(void) { @@ -183,6 +201,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 +387,7 @@ static void -CodeBlockInter(const FRAMEINFO * frame, +CodeBlockInter(const FRAMEINFO * const frame, const MACROBLOCK * pMB, int16_t qcoeff[6 * 64], Bitstream * bs, @@ -353,6 +396,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 +405,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); @@ -387,37 +443,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 +485,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 +506,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 +531,7 @@ +2 11b */ -void +static __inline void put_bvop_dbquant(Bitstream * bs, int value) { @@ -517,9 +562,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 +596,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 +697,7 @@ } -int +static __inline int get_mv_data(Bitstream * bs) { @@ -766,9 +814,7 @@ { 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); @@ -792,10 +838,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;