[FFmpeg-devel] [PATCH] Fast half-float to float conversion
Reimar Döffinger
Reimar.Doeffinger
Wed Jul 1 09:23:44 CEST 2009
On Wed, Jul 01, 2009 at 09:05:36AM +0200, Jimmy Christensen wrote:
> Looks more correct now, but still a very dark image. I multiplied with 2
> and it seems to match the table lookup method. Is this correct?
Maybe, though adding a *2 is the wrong way.
> float av_int2halflt(int16_t v){
> uint16_t nosign = v+v;
> if (nosign>= 0xfc00) {
> if (nosign == 0xfc00) return v>>15 ? -1.0/0.0 : 1.0/0.0;
> else return 0.0/0.0;
> }
> if (nosign< 0x0400) return 0; // denormal or 0
> return ldexp((v&0x3ff) + (1<<10) * (v>>15|1), (v>>10&0x1f)-26)*2;
You forgot a (), this will be wrong for negative values.
And instead of *2 the -26 should be -25 (this is related to the 11 -> 10
change, the value is 0x1f/2+10, rounded down).
The denormal or 0 case probably should instead of "return 0" use
"return ldexp((v&0x3ff)*(v>>15|1), 1-25);" to handle denormals.
> I would love to do such optimizations if I was able to. Right now I'm
> just looking for some reference code which can be used to do the job
> which is simple and not too bloated coding wise. Implementing the table
> based is not a good solution for smaller systems, but never had these
> systems in mind when proposing the code for half-float > float.
Even the paper you linked to has the code to do it without table:
f = ((h&0x8000)<<16) | (((h&0x7c00)+0x1C000)<<13) | ((h&0x03FF)<<13)
you'd only have to add handling of 0, denormals, NaN and Inf as far as
you need.
More information about the ffmpeg-devel
mailing list