On date Tuesday 2012-08-21 11:24:06 +0200, Nicolas George encoded:
> Le tridi 3 fructidor, an CCXX, Stefano Sabatini a écrit :
> > > Maybe store it as an integer? That would help making the filter bit-exact.
> > Please elaborate, also I'd like to keep compatibility with mp=decimate.
>> My suggestion would be to have "unsigned frac", with default value
> 1431655765 ((1<<32)/3) or 1417339208 ((1<<32)*0.33) and replace the
> following code
>> > + int t = (w/16)*(h/16)*decimate->frac;
>> by:
>> int t = av_rescale((w/16)*(h/16), decimate->frac, 0x100000000);
>> In other words: frac_as_a_float = frac_as_an_unsigned / (float)(1 << 32),
> but avoiding all floating-point arithmetic.
Help me to understand:
unsigned int frac_uint; // 32 bits, unsigned, maximum value (1<<32)-1, scaled by 1<<32
float frac;
frac_uint = 1417339208; // (1<<32)*0.33;
if (frac was defined)
decimate->frac_uint = decimate->frac * 0x100000000;
This operation depends on the FPU, so it may be different for
different implementations, but at least we don't need to perform it
with the default case (which will be platform independent).
But in case frac >= 1.0 this will be
frac * 0x100000000 >= (1<<32)
which cannot be expressed as a 32-bits unsigned int (on the other hand
in another mail you suggested to scale it by 1<<20).
> Since (w/16)*(h/16) should be way smaller than 1<<32 (if av_image_check_size
> did its work, (w/16)*(h/16) < 1<<20), it will be accurate enough. And
> without floating-point arithmetic, we can be sure the computation is
> bit-exact across architectures and add FATE tests.
> The /16 look very strange, though, as x and y are incremented by steps of 4.
Yeah, the maximum number of 8x8 blocks with x,y offsets of 4 should be
N = (H/4 -1)*(W/4 -1) if my computation is correct, so it would make sense
to compute t like:
t = N * frac;
or equivalently:
t = rescale(N, scaled_frac_uint, scale_factor);
--
FFmpeg = Fantastic Fanciful Mortal Peaceful Enlightened Guru