2 * Copyright (c) 2023 Institue of Software Chinese Academy of Sciences (ISCAS).
3 * Copyright (c) 2024 Geoff Hill <geoff@geoffhill.org>
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "libavutil/mem.h"
26 #include "libavutil/mem_internal.h"
28 #include "libavcodec/ac3dsp.h"
32 #define randomize_exp(buf, len) \
35 for (i = 0; i < len; i++) { \
36 buf[i] = (uint8_t)rnd(); \
40 #define randomize_i24(buf, len) \
43 for (i = 0; i < len; i++) { \
44 int32_t v = (int32_t)rnd(); \
45 int32_t u = (v & 0xFFFFFF); \
46 buf[i] = (v < 0) ? -u : u; \
50 #define randomize_float(buf, len) \
53 for (i = 0; i < len; i++) { \
54 float f = (float)rnd() / (UINT_MAX >> 5) - 16.0f; \
59 static void check_ac3_exponent_min(AC3DSPContext
*c
) {
62 #define EXP_SIZE (MAX_CTXT * MAX_COEFS)
64 LOCAL_ALIGNED_16(uint8_t, src
, [EXP_SIZE
]);
65 LOCAL_ALIGNED_16(uint8_t, v1
, [EXP_SIZE
]);
66 LOCAL_ALIGNED_16(uint8_t, v2
, [EXP_SIZE
]);
69 declare_func(void, uint8_t *, int, int);
71 for (n
= 0; n
< MAX_CTXT
; ++n
) {
72 if (check_func(c
->ac3_exponent_min
, "ac3_exponent_min_reuse%d", n
)) {
73 randomize_exp(src
, EXP_SIZE
);
75 memcpy(v1
, src
, EXP_SIZE
);
76 memcpy(v2
, src
, EXP_SIZE
);
78 call_ref(v1
, n
, MAX_COEFS
);
79 call_new(v2
, n
, MAX_COEFS
);
81 if (memcmp(v1
, v2
, EXP_SIZE
) != 0)
84 bench_new(v2
, n
, MAX_COEFS
);
88 report("ac3_exponent_min");
91 static void check_ac3_extract_exponents(AC3DSPContext
*c
) {
93 LOCAL_ALIGNED_16(int32_t, src
, [MAX_EXPS
]);
94 LOCAL_ALIGNED_16(uint8_t, v1
, [MAX_EXPS
]);
95 LOCAL_ALIGNED_16(uint8_t, v2
, [MAX_EXPS
]);
98 declare_func(void, uint8_t *, int32_t *, int);
100 for (n
= 512; n
<= MAX_EXPS
; n
+= 256) {
101 if (check_func(c
->extract_exponents
, "ac3_extract_exponents_n%d", n
)) {
102 randomize_i24(src
, n
);
104 call_ref(v1
, src
, n
);
105 call_new(v2
, src
, n
);
107 if (memcmp(v1
, v2
, n
) != 0)
110 bench_new(v1
, src
, n
);
114 report("ac3_extract_exponents");
117 static void check_float_to_fixed24(AC3DSPContext
*c
) {
118 #define BUF_SIZE 1024
119 LOCAL_ALIGNED_32(float, src
, [BUF_SIZE
]);
121 declare_func(void, int32_t *, const float *, size_t);
123 randomize_float(src
, BUF_SIZE
);
125 if (check_func(c
->float_to_fixed24
, "float_to_fixed24")) {
126 LOCAL_ALIGNED_32(int32_t, dst
, [BUF_SIZE
]);
127 LOCAL_ALIGNED_32(int32_t, dst2
, [BUF_SIZE
]);
129 call_ref(dst
, src
, BUF_SIZE
);
130 call_new(dst2
, src
, BUF_SIZE
);
132 if (memcmp(dst
, dst2
, BUF_SIZE
) != 0)
135 bench_new(dst
, src
, BUF_SIZE
);
139 report("float_to_fixed24");
142 static void check_ac3_sum_square_butterfly_int32(AC3DSPContext
*c
) {
144 LOCAL_ALIGNED_16(int32_t, lt
, [ELEMS
]);
145 LOCAL_ALIGNED_16(int32_t, rt
, [ELEMS
]);
146 LOCAL_ALIGNED_16(uint64_t, v1
, [4]);
147 LOCAL_ALIGNED_16(uint64_t, v2
, [4]);
149 declare_func(void, int64_t[4], const int32_t *, const int32_t *, int);
151 randomize_i24(lt
, ELEMS
);
152 randomize_i24(rt
, ELEMS
);
154 if (check_func(c
->sum_square_butterfly_int32
,
155 "ac3_sum_square_bufferfly_int32")) {
156 call_ref(v1
, lt
, rt
, ELEMS
);
157 call_new(v2
, lt
, rt
, ELEMS
);
159 if (memcmp(v1
, v2
, sizeof(int64_t[4])) != 0)
162 bench_new(v2
, lt
, rt
, ELEMS
);
165 report("ac3_sum_square_butterfly_int32");
168 static void check_ac3_sum_square_butterfly_float(AC3DSPContext
*c
) {
169 LOCAL_ALIGNED_32(float, lt
, [ELEMS
]);
170 LOCAL_ALIGNED_32(float, rt
, [ELEMS
]);
171 LOCAL_ALIGNED_16(float, v1
, [4]);
172 LOCAL_ALIGNED_16(float, v2
, [4]);
174 declare_func(void, float[4], const float *, const float *, int);
176 randomize_float(lt
, ELEMS
);
177 randomize_float(rt
, ELEMS
);
179 if (check_func(c
->sum_square_butterfly_float
,
180 "ac3_sum_square_bufferfly_float")) {
181 call_ref(v1
, lt
, rt
, ELEMS
);
182 call_new(v2
, lt
, rt
, ELEMS
);
184 if (!float_near_ulp_array(v1
, v2
, 11, 4))
187 bench_new(v2
, lt
, rt
, ELEMS
);
190 report("ac3_sum_square_butterfly_float");
193 void checkasm_check_ac3dsp(void)
198 check_ac3_exponent_min(&c
);
199 check_ac3_extract_exponents(&c
);
200 check_float_to_fixed24(&c
);
201 check_ac3_sum_square_butterfly_int32(&c
);
202 check_ac3_sum_square_butterfly_float(&c
);