[XviD-devel] image interpolation question

Michael Militzer xvid-devel@xvid.org
Wed, 27 Nov 2002 14:52:09 +0100


Hi,

----- Original Message -----
From: "Radek 'sysKin' Czyz" <radoslaw@syskin.cjb.net>
To: <xvid-devel@xvid.org>
Sent: Friday, November 22, 2002 4:09 PM
Subject: [XviD-devel] image interpolation question


> Hi,
>
> I was browsing the code a bit. I discovered a rather strange thing in
> image.c, in function image_interpolate(). The function prepares refh,
> refv and refhv.
> In it's qpel-part, we have two almost identical loops - one makes refh
> and refv, second makes refhv using existing refh. Cool. Now, there is
> one difference in the loops - when moving to next row of blocks, first
> loop does something like
>      refn += stride_add + EDGE_SIZE; file://which I understand (half edge
to the
> end of the line, then another 7 lines down, then half of the edge
> again).
> But second loop does
>     refn += stride_add + EDGE_SIZE2; // where EDGE_SIZE2 is half of
> edge size. This seems wrong, and as a result not entire image
> gets interpolated. Am I wrong here, or this is a typo?
>
> I changed it to what I think it's supposed to be, and got a slightly
> smaller filesize at fixed quant.
> Please tell me if I'm right, I can't be sure.

hm, I'm stunned. It shouldn't make any difference in compression efficiency
to change EDGE_SIZE2 to EDGE_SIZE, but this change will make qpel mode crash
(at least on certain pc's with certain resolutions).

Our qpel lowpass filter accesses 6 pixels (-2, +3 around center iirc), if
you interpolate the whole edged image, 2 pixels (left) and 3 pixels (right)
are read from outside the allocated buffer (the same is true for top and
bottom), which makes XVID crash with an access violation. My fix for this
problem was to double the edge size of our internal image buffer and only
interpolate (and access) half the edged size. So when I commited this fix,
encoding behaviour did not change at all (this was intended) and the
problems with crashes had been fixed (was also intended)...

I'm surprised that in normal halfpel mode, the full edged buffer is
interpolated (EDGE_SIZE). I'm pretty sure that I had set this originally to
EDGE_SIZE2, too. Normal bilinear interpolation also reads +/-1 pixel from
outside the allocated image buffer, so only interpolating EDGE_SIZE2 is the
correct (safe) solution.

I'm a bit worried that filesize changed at fixed quant when you changed
EDGE_SIZE to EDGE_SIZE2, this would mean that we could have a problem with
ME (and motion vectors pointing outside the interpolated buffer). Originally
I've changed the edged_width calculation in encoder.c to consider EDGE_SIZE2
instead of EDGE_SIZE and this should be still the case - but who knows?

bye,
Michael