[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