[XviD-devel] Rounding

Christoph Lampert xvid-devel@xvid.org
Tue, 29 Oct 2002 17:10:04 +0100 (CET)


On Tue, 29 Oct 2002, Michael Militzer wrote:

> Hi,
> 
> I have been looking into the qpel rounding issues again today because
> ms-fdam does not decode chroma of XVID qpel (as well as DivX5) correctly...
> 
> > here's the code I've been using for the Round  7-6 -> 7-9
> > tables during computation of chroma MV:

What do you mean be "7-6 -> 7-9" ? For me (and I think this is rather
clear in the standard), Table 7-6 is for rounding 16th-pel positions to
halfpel-positions (needed for inter4v chroma). 
Table 7-9 is needed for rounding 4th-pel position to halfpel-positions 
(needed for inter-mode chroma). 
There is also Table 7-8, which is rounding 8th-pel positions to halfpel
(needed for inter4v lumi). 
Table 7-7 is 12th-pel to halfpel, we don't need that at the moment. 

But in all cases, only 1 rounding operation is done! No 2-step
procedure. Did you interpret Table 7-6 as 16th-pel to quarterpel
because of the "2"s ? '2' simply stands for "next fullpel position", 
which is the right choice for the 16th-pel positions '14/16' and '15/16'. 


> >   // Table 7-6 (K=4)  (modified)
> > const int SKL_MB::Rnd_Tab_76[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
> 0, 0, 1, 1 };
> >   // Table 7-8 (K=2)  (modified)
> > const int SKL_MB::Rnd_Tab_78[ 8] = { 0, 0, 1, 1, 0, 0, 0, 1  };
> >   // Table 7-9 (K=1)  (modified)
> > const int SKL_MB::Rnd_Tab_79[ 4] = { 0, 1, 1, 1 };
> >
> > typedef SKL_INT16 SKL_MV[2];
> >
> > #define DIV2RND(x) ( ((x)>>1) | ((x)&1) )
> >
> > void SKL_MB::Derive_uv_MV_From_1MV(int Quarter, SKL_MV *MV)
> > {
> >   int x = MV[0][0];
> >   int y = MV[0][1];
> >   if (Quarter) { x = DIV2RND(x); y = DIV2RND(y); }
> >   uv_MV[0] = (x>>1) | Rnd_Tab_79[ x & 0x3];
> >   uv_MV[1] = (y>>1) | Rnd_Tab_79[ y & 0x3];
> > }
> 
> this is exactly how I've understood the standard and that's what we're
> currently already doing. 

Sorry, maybe I'm too stupid, but I don't see how this code has anything to
do with the standard. 

In my eyes the standard clear demands rounding as follows:

roundtab16[]={0,0,0,1,1,1,1,1,1,1,1,1,1,2,2};
roundtab8[]={0,0,0,1,1,1,1,1,1,1,2,2};
roundtab4[]={0,1,1,1};

round_16th_to_half(int pos)
{
  int fullpel = pos & 0xFFFFFFF0;   // might be negative (-3 -> -16)
  int pure_16th_pel = pos & 0x0000000F;  // always positive (-3 -> +13) 

  fullpel_to_halfpel = fullpel*2;
  16thpel_to_halfpel = roundtab16[pure_16th_pel]; 

  final_halfpel_position = fullpel_to_halfpel + 16thpel_to_halfpel;
 
  return final_halfpel_position;
}

and the analogue routines for 8th and quarterpel position. 

Maybe you can test if this simple way gives correct results in reference
decoder? I don't have a running version here...

gruel