PR #22792 opened by i-Amogh URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22792 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22792.patch
Adds FATE test coverage for softfloat_ieee754.h that validates all public API functions using av_assert0() for fail fast behaviour, matching the pattern established by fate-integer. Tests added: - Integer conversion - roundtrip for ±1 through ±100, plus fractional exponents - IEEE 754 bit roundtrip - 9 representative bit patterns (1.0, -1.0, 0.5, 2.0, 0.0, -0.0, 3.0, 4.0, -2.0) - Multiplication - including large exponents (2¹⁰ × 2⁵ = 32768), large values (100 × 100), and negative - sign handling - Division - exact quotients and negative operands - Comparison - equality for same/different representations, inequality, negatives - Normalization - including FLOAT_0 and FLOAT_1 constant validation - Arithmetic consistency - 50 × 50 matrix of multiplication and power of 2 division results Coverage: 0% -> 100% Line, 100% Function for libavutil/softfloat_ieee754.h. From 849882e327eefaa2ee3909e0e3341dbcf4c82ddd Mon Sep 17 00:00:00 2001 From: i-Amogh <[email protected]> Date: Sun, 12 Apr 2026 01:42:19 +0530 Subject: [PATCH] lavu/tests: Add FATE tests for libavutil/softfloat_ieee754.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested all public functions softfloat_ieee754, which are used by the ALS decoder for floating point sample data processing. The test validates: - av_int2sf_ieee754 integer roundtrip conversion - av_int2sf_ieee754 with fractional exponents - av_bits2sf_ieee754 IEEE 754 bit pattern roundtrip - av_mul_sf_ieee754 including negative operands - av_div_sf_ieee754 for exact quotients - av_cmp_sf_ieee754 equality - av_normalize_sf_ieee754 - Arithmetic consistency over a 50×50 multiplication/division matrix Signed-off-by: i-Amogh <[email protected]> --- libavutil/Makefile | 1 + libavutil/tests/softfloat_ieee754.c | 167 ++++++++++++++++++++++++++++ tests/fate/libavutil.mak | 5 + 3 files changed, 173 insertions(+) create mode 100644 libavutil/tests/softfloat_ieee754.c diff --git a/libavutil/Makefile b/libavutil/Makefile index ff166cc81a..c6eb8786ba 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -301,6 +301,7 @@ TESTPROGS = adler32 \ sha512 \ side_data_array \ softfloat \ + softfloat_ieee754 \ stereo3d \ tree \ twofish \ diff --git a/libavutil/tests/softfloat_ieee754.c b/libavutil/tests/softfloat_ieee754.c new file mode 100644 index 0000000000..f0823ae007 --- /dev/null +++ b/libavutil/tests/softfloat_ieee754.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2026 Amogh Kumar Sinha + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdint.h> + +#include "libavutil/avassert.h" +#include "libavutil/softfloat_ieee754.h" + +static uint64_t full_mantissa(SoftFloat_IEEE754 sf) +{ + if (sf.mant == 0 && sf.exp == -126) + return 0; + return sf.mant | 0x00800000UL; +} + +static int sf_to_int(SoftFloat_IEEE754 sf) +{ + if (sf.mant == 0 && sf.exp == -126) + return 0; + + uint64_t mant = full_mantissa(sf); + int exp = sf.exp - 23; + + if (exp >= 0) + return sf.sign ? -(int)(mant << exp) : (int)(mant << exp); + else + return sf.sign ? -(int)(mant >> (-exp)) : (int)(mant >> (-exp)); +} + +static uint32_t sf_to_bits(SoftFloat_IEEE754 sf) +{ + return ((uint32_t)sf.sign << 31) | + (((uint32_t)(uint8_t)sf.exp) << 23) | + ((uint32_t)sf.mant & 0x7FFFFFUL); +} + +int main(void) +{ + SoftFloat_IEEE754 sf; + int i, j; + + for (i = 1; i <= 100; i++) { + sf = av_int2sf_ieee754(i, 0); + av_assert0(sf_to_int(sf) == i); + } + + for (i = 1; i <= 100; i++) { + sf = av_int2sf_ieee754(-i, 0); + av_assert0(sf_to_int(sf) == -i); + } + + sf = av_int2sf_ieee754(1, 10); + av_assert0(sf_to_int(sf) == 1024); + + sf = av_int2sf_ieee754(3, 8); + av_assert0(sf_to_int(sf) == 768); + + sf = av_int2sf_ieee754(5, -1); + av_assert0(sf_to_int(sf) == 2); + + { + uint32_t test_values[] = { + 0x3F800000UL, + 0xBF800000UL, + 0x3F000000UL, + 0x40000000UL, + 0x00000000UL, + 0x80000000UL, + 0x40400000UL, + 0x40800000UL, + 0xC0000000UL, + }; + size_t k; + for (k = 0; k < sizeof(test_values) / sizeof(test_values[0]); k++) { + sf = av_bits2sf_ieee754(test_values[k]); + av_assert0(sf_to_bits(sf) == test_values[k]); + } + } + + sf = av_mul_sf_ieee754(av_int2sf_ieee754(5, 0), av_int2sf_ieee754(3, 0)); + av_assert0(sf_to_int(sf) == 15); + + sf = av_mul_sf_ieee754(av_int2sf_ieee754(1, 10), av_int2sf_ieee754(1, 5)); + av_assert0(sf_to_int(sf) == 32768); + + sf = av_mul_sf_ieee754(av_int2sf_ieee754(100, 0), av_int2sf_ieee754(100, 0)); + av_assert0(sf_to_int(sf) == 10000); + + sf = av_mul_sf_ieee754(av_int2sf_ieee754(-5, 0), av_int2sf_ieee754(3, 0)); + av_assert0(sf_to_int(sf) == -15); + + sf = av_mul_sf_ieee754(av_int2sf_ieee754(-5, 0), av_int2sf_ieee754(-3, 0)); + av_assert0(sf_to_int(sf) == 15); + + sf = av_div_sf_ieee754(av_int2sf_ieee754(6, 0), av_int2sf_ieee754(2, 0)); + av_assert0(sf_to_int(sf) == 3); + + sf = av_div_sf_ieee754(av_int2sf_ieee754(100, 0), av_int2sf_ieee754(4, 0)); + av_assert0(sf_to_int(sf) == 25); + + sf = av_div_sf_ieee754(av_int2sf_ieee754(-15, 0), av_int2sf_ieee754(3, 0)); + av_assert0(sf_to_int(sf) == -5); + + sf = av_div_sf_ieee754(av_int2sf_ieee754(1, 0), av_int2sf_ieee754(1, 0)); + av_assert0(sf_to_int(sf) == 1); + + sf = av_int2sf_ieee754(42, 0); + av_assert0(av_cmp_sf_ieee754(sf, av_int2sf_ieee754(42, 0))); + + sf = av_int2sf_ieee754(2, 0); + av_assert0(!av_cmp_sf_ieee754(sf, av_int2sf_ieee754(3, 0))); + + av_assert0(av_cmp_sf_ieee754(av_int2sf_ieee754(1, 0), av_int2sf_ieee754(2, -1))); + + sf = av_int2sf_ieee754(-5, 0); + av_assert0(av_cmp_sf_ieee754(sf, av_int2sf_ieee754(-5, 0))); + + av_assert0(FLOAT_0.mant == 0); + av_assert0(FLOAT_0.exp == -126); + av_assert0(FLOAT_0.sign == 0); + + av_assert0(FLOAT_1.mant == 0); + av_assert0(FLOAT_1.exp == 0); + av_assert0(FLOAT_1.sign == 0); + + sf = av_normalize_sf_ieee754(av_int2sf_ieee754(42, 0)); + av_assert0(sf_to_int(sf) == 42); + + sf = av_normalize_sf_ieee754(FLOAT_0); + av_assert0(sf_to_int(sf) == 0); + + for (i = 1; i <= 50; i++) { + for (j = 1; j <= 50; j++) { + SoftFloat_IEEE754 a = av_int2sf_ieee754(i, 0); + SoftFloat_IEEE754 b = av_int2sf_ieee754(j, 0); + SoftFloat_IEEE754 mul_result = av_mul_sf_ieee754(a, b); + av_assert0(sf_to_int(mul_result) == i * j); + + if ((i % j) == 0) { + int expected = i / j; + if ((expected & (expected - 1)) == 0) { + SoftFloat_IEEE754 div_result = av_div_sf_ieee754(a, b); + av_assert0(sf_to_int(div_result) == expected); + } + } + } + } + + return 0; +} diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak index d69a4de863..0c4a47aa64 100644 --- a/tests/fate/libavutil.mak +++ b/tests/fate/libavutil.mak @@ -152,6 +152,11 @@ FATE_LIBAVUTIL += fate-sha512 fate-sha512: libavutil/tests/sha512$(EXESUF) fate-sha512: CMD = run libavutil/tests/sha512$(EXESUF) +FATE_LIBAVUTIL += fate-softfloat_ieee754 +fate-softfloat_ieee754: libavutil/tests/softfloat_ieee754$(EXESUF) +fate-softfloat_ieee754: CMD = run libavutil/tests/softfloat_ieee754$(EXESUF) +fate-softfloat_ieee754: CMP = null + FATE_LIBAVUTIL += fate-side_data_array fate-side_data_array: libavutil/tests/side_data_array$(EXESUF) fate-side_data_array: CMD = run libavutil/tests/side_data_array$(EXESUF) -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
