[FFmpeg-devel] [PATCH] Fast half-float to float conversion

Jimmy Christensen jimmy
Tue Jun 30 15:09:33 CEST 2009


On 2009-06-30 11:18, Reimar D?ffinger wrote:
> On Tue, Jun 30, 2009 at 07:33:43AM +0200, Jimmy Christensen wrote:
>> I'm almost done with my OpenEXR decoder, but since it can work in a
>> half-float format I wanted a fast half-float to float conversion. I
>> found one in the FOX toolkit which uses a table lookup. I didn't want
>> the table lookup in the OpenEXR decoder only, since a few other formats
>> can use half-floats aswell. So instead I submit the half-float to float
>> first as a libavutil header.
>
> Shared tables certainly don't belong into headers, either it wastes
> space or in this case it just won't compile when the header is used more
> than once.
>

I was unsure on how to implement this. Will fiddle around with it abit 
more...

>> +/*
>> + * This is for fast half float to float conversion. This is derivative work from the
>> + * FOX Toolkit authored by Jeroen van der Zijp<jeroen at fox-toolkit.org>. It is based on a
>> + * paper also written by Jeroen van der Zijp, which can be found here :
>> + * http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
>> + */
>> +
>> +#ifndef AVUTIL_HALF_H
>> +#define AVUTIL_HALF_H
>> +
>> +// Half to float mantissa table
>> +const unsigned int half_float_mantissa[2048] = {
>
> With a 8kB table I very much doubt this is fast, at least not on any
> system with a small cache.
>

I think it's cache size vs. speed. Do you have any alternative way of 
doing the conversion?

>> +float half2float(unsigned int v) {
>> +    union {
>> +        unsigned int u;
>> +        float f;
>> +    } r;
>> +    r.u = half_float_mantissa[half_float_switch[v>>10]+(v&0x3ff)]+half_float_exponent[v>>10];
>
> This definitely would have to be documented. I also suspect it doesn't
> handle denormals correctly at all.
> Of course hard to tell without a specification for that "half float"
> format.

The half-float I'm aiming at is the one used in the OpenEXR format. From 
this document : http://www.openexr.com/openexrfilelayout.pdf

> Binary floating-point numbers with 16, 32 or 64 bits are stored as 2, 4 or 8 bytes. The representation of 32-
> bit and 64-bit floating-point numbers conforms to the IEEE 754 standard. The representation of 16-bit
> floating-point numbers is analogous to IEEE 754, but with 5 exponent bits and 10 bits for the fraction. The
> exponent bias is 15. Floating-point numbers are little-endian: the least significant bits of the fraction are in
> the byte closest to the beginning of the file, while the sign bit and the most significant bits of the exponent
> are in the byte closest to the end of the file.


> In addition this code will crash if v is too large, or did you mean v to
> be uint16_t?

Need to do more testing. This was more an effort to get some ideas on 
which direction to go in.

> Lastly it seems to me that this code would belong into
> libavutil/intfloat_readwrite.*

You are probably right.

-- 
Best Regards
Jimmy Christensen
Developer
Ghost A/S



More information about the ffmpeg-devel mailing list