[FFmpeg-devel] [PATCH 06/11] avutil/half2float: adjust conversion of NaN
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Thu Aug 11 00:24:11 EEST 2022
Timo Rothenpieler:
> IEEE-754 differentiates two different kind of NaNs.
> Quiet and Signaling ones. They are differentiated by the MSB of the
> mantissa.
>
> For whatever reason, actual hardware conversion of half to single always
> sets the signaling bit to 1 if the mantissa is != 0, and to 0 if it's 0.
> So our code has to follow suite or fate-testing hardware float16 will be
> impossible.
What does the exr spec say about quiet and signaling nans?
> ---
> libavcodec/exr.c | 2 +-
> libavcodec/pnm.h | 2 +-
> libavutil/half2float.h | 5 +++++
> tests/ref/fate/exr-rgb-scanline-zip-half-0x0-0xFFFF | 2 +-
> 4 files changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/libavcodec/exr.c b/libavcodec/exr.c
> index 5c6ca9adbf..47f4786491 100644
> --- a/libavcodec/exr.c
> +++ b/libavcodec/exr.c
> @@ -191,7 +191,7 @@ typedef struct EXRContext {
> float gamma;
> union av_intfloat32 gamma_table[65536];
>
> - uint32_t mantissatable[2048];
> + uint32_t mantissatable[3072];
> uint32_t exponenttable[64];
> uint16_t offsettable[64];
> } EXRContext;
> diff --git a/libavcodec/pnm.h b/libavcodec/pnm.h
> index 5bf2eaa4d9..7e5445f529 100644
> --- a/libavcodec/pnm.h
> +++ b/libavcodec/pnm.h
> @@ -34,7 +34,7 @@ typedef struct PNMContext {
> int half;
> float scale;
>
> - uint32_t mantissatable[2048];
> + uint32_t mantissatable[3072];
> uint32_t exponenttable[64];
> uint16_t offsettable[64];
> } PNMContext;
> diff --git a/libavutil/half2float.h b/libavutil/half2float.h
> index 1f6deade07..5af4690cfe 100644
> --- a/libavutil/half2float.h
> +++ b/libavutil/half2float.h
> @@ -45,6 +45,9 @@ static void half2float_table(uint32_t *mantissatable, uint32_t *exponenttable,
> mantissatable[i] = convertmantissa(i);
> for (int i = 1024; i < 2048; i++)
> mantissatable[i] = 0x38000000UL + ((i - 1024) << 13UL);
> + for (int i = 2048; i < 3072; i++)
> + mantissatable[i] = mantissatable[i - 1024] | 0x400000UL;
> + mantissatable[2048] = mantissatable[1024];
>
> exponenttable[0] = 0;
> for (int i = 1; i < 31; i++)
> @@ -58,7 +61,9 @@ static void half2float_table(uint32_t *mantissatable, uint32_t *exponenttable,
> offsettable[0] = 0;
> for (int i = 1; i < 64; i++)
> offsettable[i] = 1024;
> + offsettable[31] = 2048;
> offsettable[32] = 0;
> + offsettable[63] = 2048;
> }
>
> static uint32_t half2float(uint16_t h, const uint32_t *mantissatable, const uint32_t *exponenttable,
> diff --git a/tests/ref/fate/exr-rgb-scanline-zip-half-0x0-0xFFFF b/tests/ref/fate/exr-rgb-scanline-zip-half-0x0-0xFFFF
> index b6201116fe..e45a40b498 100644
> --- a/tests/ref/fate/exr-rgb-scanline-zip-half-0x0-0xFFFF
> +++ b/tests/ref/fate/exr-rgb-scanline-zip-half-0x0-0xFFFF
> @@ -3,4 +3,4 @@
> #codec_id 0: rawvideo
> #dimensions 0: 256x256
> #sar 0: 1/1
> -0, 0, 0, 1, 786432, 0x1445e411
> +0, 0, 0, 1, 786432, 0xce9be2be
More information about the ffmpeg-devel
mailing list