]> git.sesse.net Git - ffmpeg/blob - tests/checkasm/aacpsdsp.c
Merge commit '58d154922707bfeb873cb3a7476e0f94b17463dd'
[ffmpeg] / tests / checkasm / aacpsdsp.c
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include "libavcodec/aacpsdsp.h"
20
21 #include "checkasm.h"
22
23 #define N 32
24 #define STRIDE 128
25 #define BUF_SIZE (N * STRIDE)
26
27 #define randomize(buf, len) do {                                \
28     int i;                                                      \
29     for (i = 0; i < len; i++) {                                 \
30         const INTFLOAT f = (INTFLOAT)rnd() / UINT_MAX;          \
31         (buf)[i] = f;                                           \
32     }                                                           \
33 } while (0)
34
35 #define EPS 0.005
36
37 static void test_add_squares(void)
38 {
39     LOCAL_ALIGNED_16(INTFLOAT, dst0, [BUF_SIZE]);
40     LOCAL_ALIGNED_16(INTFLOAT, dst1, [BUF_SIZE]);
41     LOCAL_ALIGNED_16(INTFLOAT, src, [BUF_SIZE], [2]);
42
43     declare_func(void, INTFLOAT *dst,
44                  const INTFLOAT (*src)[2], int n);
45
46     randomize((INTFLOAT *)src, BUF_SIZE * 2);
47     randomize(dst0, BUF_SIZE);
48     memcpy(dst1, dst0, BUF_SIZE * sizeof(INTFLOAT));
49     call_ref(dst0, src, BUF_SIZE);
50     call_new(dst1, src, BUF_SIZE);
51     if (!float_near_abs_eps_array(dst0, dst1, EPS, BUF_SIZE))
52         fail();
53     bench_new(dst1, src, BUF_SIZE);
54 }
55
56 static void test_mul_pair_single(void)
57 {
58     LOCAL_ALIGNED_16(INTFLOAT, dst0, [BUF_SIZE], [2]);
59     LOCAL_ALIGNED_16(INTFLOAT, dst1, [BUF_SIZE], [2]);
60     LOCAL_ALIGNED_16(INTFLOAT, src0, [BUF_SIZE], [2]);
61     LOCAL_ALIGNED_16(INTFLOAT, src1, [BUF_SIZE]);
62
63     declare_func(void, INTFLOAT (*dst)[2],
64                        INTFLOAT (*src0)[2], INTFLOAT *src1, int n);
65
66     randomize((INTFLOAT *)src0, BUF_SIZE * 2);
67     randomize(src1, BUF_SIZE);
68     call_ref(dst0, src0, src1, BUF_SIZE);
69     call_new(dst1, src0, src1, BUF_SIZE);
70     if (!float_near_abs_eps_array((float *)dst0, (float *)dst1, EPS, BUF_SIZE * 2))
71         fail();
72     bench_new(dst1, src0, src1, BUF_SIZE);
73 }
74
75 static void test_hybrid_analysis(void)
76 {
77     LOCAL_ALIGNED_16(INTFLOAT, dst0, [BUF_SIZE], [2]);
78     LOCAL_ALIGNED_16(INTFLOAT, dst1, [BUF_SIZE], [2]);
79     LOCAL_ALIGNED_16(INTFLOAT, in, [13], [2]);
80     LOCAL_ALIGNED_16(INTFLOAT, filter, [N], [8][2]);
81
82     declare_func(void, INTFLOAT (*out)[2], INTFLOAT (*in)[2],
83                  const INTFLOAT (*filter)[8][2],
84                  ptrdiff_t stride, int n);
85
86     randomize((INTFLOAT *)in, 13 * 2);
87     randomize((INTFLOAT *)filter, N * 8 * 2);
88
89     randomize((INTFLOAT *)dst0, BUF_SIZE * 2);
90     memcpy(dst1, dst0, BUF_SIZE * 2 * sizeof(INTFLOAT));
91
92     call_ref(dst0, in, filter, STRIDE, N);
93     call_new(dst1, in, filter, STRIDE, N);
94
95     if (!float_near_abs_eps_array((float *)dst0, (float *)dst1, EPS, BUF_SIZE * 2))
96         fail();
97     bench_new(dst1, in, filter, STRIDE, N);
98 }
99
100 static void test_hybrid_analysis_ileave(void)
101 {
102     LOCAL_ALIGNED_16(INTFLOAT, in,   [2], [38][64]);
103     LOCAL_ALIGNED_16(INTFLOAT, out0, [91], [32][2]);
104     LOCAL_ALIGNED_16(INTFLOAT, out1, [91], [32][2]);
105
106     declare_func(void, INTFLOAT (*out)[32][2], INTFLOAT L[2][38][64],
107                        int i, int len);
108
109     randomize((INTFLOAT *)out0, 91 * 32 * 2);
110     randomize((INTFLOAT *)in,    2 * 38 * 64);
111     memcpy(out1, out0, 91 * 32 * 2 * sizeof(INTFLOAT));
112
113     /* len is hardcoded to 32 as that's the only value used in
114        libavcodec. asm functions are likely to be optimized
115        hardcoding this value in their loops and could fail with
116        anything else.
117        i is hardcoded to the two values currently used by the
118        aac decoder because the arm neon implementation is
119        micro-optimized for them and will fail for almost every
120        other value. */
121     call_ref(out0, in, 3, 32);
122     call_new(out1, in, 3, 32);
123
124     /* the function just moves data around, so memcmp is enough */
125     if (memcmp(out0, out1, 91 * 32 * 2 * sizeof(INTFLOAT)))
126         fail();
127
128     call_ref(out0, in, 5, 32);
129     call_new(out1, in, 5, 32);
130
131     if (memcmp(out0, out1, 91 * 32 * 2 * sizeof(INTFLOAT)))
132         fail();
133
134     bench_new(out1, in, 3, 32);
135 }
136
137 static void test_hybrid_synthesis_deint(void)
138 {
139     LOCAL_ALIGNED_16(INTFLOAT, out0, [2], [38][64]);
140     LOCAL_ALIGNED_16(INTFLOAT, out1, [2], [38][64]);
141     LOCAL_ALIGNED_16(INTFLOAT, in,  [91], [32][2]);
142
143     declare_func(void, INTFLOAT out[2][38][64], INTFLOAT (*in)[32][2],
144                        int i, int len);
145
146     randomize((INTFLOAT *)in,  91 * 32 * 2);
147     randomize((INTFLOAT *)out0, 2 * 38 * 64);
148     memcpy(out1, out0, 2 * 38 * 64 * sizeof(INTFLOAT));
149
150     /* len is hardcoded to 32 as that's the only value used in
151        libavcodec. asm functions are likely to be optimized
152        hardcoding this value in their loops and could fail with
153        anything else.
154        i is hardcoded to the two values currently used by the
155        aac decoder because the arm neon implementation is
156        micro-optimized for them and will fail for almost every
157        other value. */
158     call_ref(out0, in, 3, 32);
159     call_new(out1, in, 3, 32);
160
161     /* the function just moves data around, so memcmp is enough */
162     if (memcmp(out0, out1, 2 * 38 * 64 * sizeof(INTFLOAT)))
163         fail();
164
165     call_ref(out0, in, 5, 32);
166     call_new(out1, in, 5, 32);
167
168     if (memcmp(out0, out1, 2 * 38 * 64 * sizeof(INTFLOAT)))
169         fail();
170
171     bench_new(out1, in, 3, 32);
172 }
173
174 static void test_stereo_interpolate(PSDSPContext *psdsp)
175 {
176     int i;
177     LOCAL_ALIGNED_16(INTFLOAT, l,  [BUF_SIZE], [2]);
178     LOCAL_ALIGNED_16(INTFLOAT, r,  [BUF_SIZE], [2]);
179     LOCAL_ALIGNED_16(INTFLOAT, l0, [BUF_SIZE], [2]);
180     LOCAL_ALIGNED_16(INTFLOAT, r0, [BUF_SIZE], [2]);
181     LOCAL_ALIGNED_16(INTFLOAT, l1, [BUF_SIZE], [2]);
182     LOCAL_ALIGNED_16(INTFLOAT, r1, [BUF_SIZE], [2]);
183     LOCAL_ALIGNED_16(INTFLOAT, h, [2], [4]);
184     LOCAL_ALIGNED_16(INTFLOAT, h_step, [2], [4]);
185
186     declare_func(void, INTFLOAT (*l)[2], INTFLOAT (*r)[2],
187                        INTFLOAT h[2][4], INTFLOAT h_step[2][4], int len);
188
189     randomize((INTFLOAT *)l, BUF_SIZE * 2);
190     randomize((INTFLOAT *)r, BUF_SIZE * 2);
191
192     for (i = 0; i < 2; i++) {
193         if (check_func(psdsp->stereo_interpolate[i], "ps_stereo_interpolate%s", i ? "_ipdopd" : "")) {
194             memcpy(l0, l, BUF_SIZE * 2 * sizeof(INTFLOAT));
195             memcpy(l1, l, BUF_SIZE * 2 * sizeof(INTFLOAT));
196             memcpy(r0, r, BUF_SIZE * 2 * sizeof(INTFLOAT));
197             memcpy(r1, r, BUF_SIZE * 2 * sizeof(INTFLOAT));
198
199             randomize((INTFLOAT *)h, 2 * 4);
200             randomize((INTFLOAT *)h_step, 2 * 4);
201
202             call_ref(l0, r0, h, h_step, BUF_SIZE);
203             call_new(l1, r1, h, h_step, BUF_SIZE);
204             if (!float_near_abs_eps_array((float *)l0, (float *)l1, EPS, BUF_SIZE * 2) ||
205                 !float_near_abs_eps_array((float *)r0, (float *)r1, EPS, BUF_SIZE * 2))
206                 fail();
207
208             memcpy(l1, l, BUF_SIZE * 2 * sizeof(INTFLOAT));
209             memcpy(r1, r, BUF_SIZE * 2 * sizeof(INTFLOAT));
210             bench_new(l1, r1, h, h_step, BUF_SIZE);
211         }
212     }
213 }
214
215 void checkasm_check_aacpsdsp(void)
216 {
217     PSDSPContext psdsp;
218
219     ff_psdsp_init(&psdsp);
220
221     if (check_func(psdsp.add_squares, "ps_add_squares"))
222         test_add_squares();
223     report("add_squares");
224
225     if (check_func(psdsp.mul_pair_single, "ps_mul_pair_single"))
226         test_mul_pair_single();
227     report("mul_pair_single");
228
229     if (check_func(psdsp.hybrid_analysis, "ps_hybrid_analysis"))
230         test_hybrid_analysis();
231     report("hybrid_analysis");
232
233     if (check_func(psdsp.hybrid_analysis_ileave, "ps_hybrid_analysis_ileave"))
234         test_hybrid_analysis_ileave();
235     report("hybrid_analysis_ileave");
236
237     if (check_func(psdsp.hybrid_synthesis_deint, "ps_hybrid_synthesis_deint"))
238         test_hybrid_synthesis_deint();
239     report("hybrid_synthesis_deint");
240
241     test_stereo_interpolate(&psdsp);
242     report("stereo_interpolate");
243 }