FFmpeg
Loading...
Searching...
No Matches
aacpsdsp.c
Go to the documentation of this file.
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 <string.h>
20
21#include "libavcodec/aacpsdsp.h"
22#include "libavutil/intfloat.h"
24
25#include "checkasm.h"
26
27#define N 32
28#define STRIDE 128
29#define BUF_SIZE (N * STRIDE)
30
31#define randomize(buf, len) do { \
32 int i; \
33 for (i = 0; i < len; i++) { \
34 const INTFLOAT f = (INTFLOAT)rnd() / UINT_MAX; \
35 (buf)[i] = f; \
36 } \
37} while (0)
38
39#define EPS 0.005
40
41static void clear_less_significant_bits(INTFLOAT *buf, int len, int bits)
42{
43 int i;
44 for (i = 0; i < len; i++) {
45 union av_intfloat32 u = { .f = buf[i] };
46 u.i &= (0xffffffff << bits);
47 buf[i] = u.f;
48 }
49}
50
51static void test_add_squares(void)
52{
56
58 const INTFLOAT (*src)[2], int n);
59
61 randomize(dst0, BUF_SIZE);
62 memcpy(dst1, dst0, BUF_SIZE * sizeof(INTFLOAT));
63 call_ref(dst0, src, BUF_SIZE);
64 call_new(dst1, src, BUF_SIZE);
65 if (!float_near_abs_eps_array(dst0, dst1, EPS, BUF_SIZE))
66 fail();
67 bench_new(dst1, src, BUF_SIZE);
68}
69
70static void test_mul_pair_single(void)
71{
72 LOCAL_ALIGNED_16(INTFLOAT, dst0, [BUF_SIZE], [2]);
73 LOCAL_ALIGNED_16(INTFLOAT, dst1, [BUF_SIZE], [2]);
76
77 declare_func(void, INTFLOAT (*dst)[2],
78 INTFLOAT (*src0)[2], INTFLOAT *src1, int n);
79
82 call_ref(dst0, src0, src1, BUF_SIZE);
83 call_new(dst1, src0, src1, BUF_SIZE);
84 if (!float_near_abs_eps_array((float *)dst0, (float *)dst1, EPS, BUF_SIZE * 2))
85 fail();
86 bench_new(dst1, src0, src1, BUF_SIZE);
87}
88
89static void test_hybrid_analysis(void)
90{
91 LOCAL_ALIGNED_16(INTFLOAT, dst0, [BUF_SIZE], [2]);
92 LOCAL_ALIGNED_16(INTFLOAT, dst1, [BUF_SIZE], [2]);
93 LOCAL_ALIGNED_16(INTFLOAT, in, [13], [2]);
94 LOCAL_ALIGNED_16(INTFLOAT, filter, [N], [8][2]);
95
96 declare_func(void, INTFLOAT (*out)[2], INTFLOAT (*in)[2],
97 const INTFLOAT (*filter)[8][2],
98 ptrdiff_t stride, int n);
99
100 randomize((INTFLOAT *)in, 13 * 2);
101 randomize((INTFLOAT *)filter, N * 8 * 2);
102
103 randomize((INTFLOAT *)dst0, BUF_SIZE * 2);
104 memcpy(dst1, dst0, BUF_SIZE * 2 * sizeof(INTFLOAT));
105
106 call_ref(dst0, in, filter, STRIDE, N);
107 call_new(dst1, in, filter, STRIDE, N);
108
109 if (!float_near_abs_eps_array((float *)dst0, (float *)dst1, EPS, BUF_SIZE * 2))
110 fail();
111 bench_new(dst1, in, filter, STRIDE, N);
112}
113
115{
116 LOCAL_ALIGNED_16(INTFLOAT, in, [2], [38][64]);
117 LOCAL_ALIGNED_16(INTFLOAT, out0, [91], [32][2]);
118 LOCAL_ALIGNED_16(INTFLOAT, out1, [91], [32][2]);
119
120 declare_func(void, INTFLOAT (*out)[32][2], INTFLOAT L[2][38][64],
121 int i, int len);
122
123 randomize((INTFLOAT *)out0, 91 * 32 * 2);
124 randomize((INTFLOAT *)in, 2 * 38 * 64);
125 memcpy(out1, out0, 91 * 32 * 2 * sizeof(INTFLOAT));
126
127 /* len is hardcoded to 32 as that's the only value used in
128 libavcodec. asm functions are likely to be optimized
129 hardcoding this value in their loops and could fail with
130 anything else.
131 i is hardcoded to the two values currently used by the
132 aac decoder because the arm neon implementation is
133 micro-optimized for them and will fail for almost every
134 other value. */
135 call_ref(out0, in, 3, 32);
136 call_new(out1, in, 3, 32);
137
138 /* the function just moves data around, so memcmp is enough */
139 if (memcmp(out0, out1, 91 * 32 * 2 * sizeof(INTFLOAT)))
140 fail();
141
142 call_ref(out0, in, 5, 32);
143 call_new(out1, in, 5, 32);
144
145 if (memcmp(out0, out1, 91 * 32 * 2 * sizeof(INTFLOAT)))
146 fail();
147
148 bench_new(out1, in, 3, 32);
149}
150
152{
153 LOCAL_ALIGNED_16(INTFLOAT, out0, [2], [38][64]);
154 LOCAL_ALIGNED_16(INTFLOAT, out1, [2], [38][64]);
155 LOCAL_ALIGNED_16(INTFLOAT, in, [91], [32][2]);
156
157 declare_func(void, INTFLOAT out[2][38][64], INTFLOAT (*in)[32][2],
158 int i, int len);
159
160 randomize((INTFLOAT *)in, 91 * 32 * 2);
161 randomize((INTFLOAT *)out0, 2 * 38 * 64);
162 memcpy(out1, out0, 2 * 38 * 64 * sizeof(INTFLOAT));
163
164 /* len is hardcoded to 32 as that's the only value used in
165 libavcodec. asm functions are likely to be optimized
166 hardcoding this value in their loops and could fail with
167 anything else.
168 i is hardcoded to the two values currently used by the
169 aac decoder because the arm neon implementation is
170 micro-optimized for them and will fail for almost every
171 other value. */
172 call_ref(out0, in, 3, 32);
173 call_new(out1, in, 3, 32);
174
175 /* the function just moves data around, so memcmp is enough */
176 if (memcmp(out0, out1, 2 * 38 * 64 * sizeof(INTFLOAT)))
177 fail();
178
179 call_ref(out0, in, 5, 32);
180 call_new(out1, in, 5, 32);
181
182 if (memcmp(out0, out1, 2 * 38 * 64 * sizeof(INTFLOAT)))
183 fail();
184
185 bench_new(out1, in, 3, 32);
186}
187
189{
190 int i;
197 LOCAL_ALIGNED_16(INTFLOAT, h, [2], [4]);
198 LOCAL_ALIGNED_16(INTFLOAT, h_step, [2], [4]);
199
200 declare_func(void, INTFLOAT (*l)[2], INTFLOAT (*r)[2],
201 INTFLOAT h[2][4], INTFLOAT h_step[2][4], int len);
202
203 randomize((INTFLOAT *)l, BUF_SIZE * 2);
204 randomize((INTFLOAT *)r, BUF_SIZE * 2);
205
206 for (i = 0; i < 2; i++) {
207 if (check_func(psdsp->stereo_interpolate[i], "ps_stereo_interpolate%s", i ? "_ipdopd" : "")) {
208 memcpy(l0, l, BUF_SIZE * 2 * sizeof(INTFLOAT));
209 memcpy(l1, l, BUF_SIZE * 2 * sizeof(INTFLOAT));
210 memcpy(r0, r, BUF_SIZE * 2 * sizeof(INTFLOAT));
211 memcpy(r1, r, BUF_SIZE * 2 * sizeof(INTFLOAT));
212
213 randomize((INTFLOAT *)h, 2 * 4);
214 randomize((INTFLOAT *)h_step, 2 * 4);
215 // Clear the least significant 14 bits of h_step, to avoid
216 // divergence when accumulating h_step BUF_SIZE times into
217 // a float variable which may or may not have extra intermediate
218 // precision. Therefore clear roughly log2(BUF_SIZE) less
219 // significant bits, to get the same result regardless of any
220 // extra precision in the accumulator.
221 clear_less_significant_bits((INTFLOAT *)h_step, 2 * 4, 14);
222
223 call_ref(l0, r0, h, h_step, BUF_SIZE);
224 call_new(l1, r1, h, h_step, BUF_SIZE);
225 if (!float_near_abs_eps_array((float *)l0, (float *)l1, EPS, BUF_SIZE * 2) ||
226 !float_near_abs_eps_array((float *)r0, (float *)r1, EPS, BUF_SIZE * 2))
227 fail();
228
229 memcpy(l1, l, BUF_SIZE * 2 * sizeof(INTFLOAT));
230 memcpy(r1, r, BUF_SIZE * 2 * sizeof(INTFLOAT));
231 bench_new(l1, r1, h, h_step, BUF_SIZE);
232 }
233 }
234}
235
237{
238 PSDSPContext psdsp;
239
240 ff_psdsp_init(&psdsp);
241
242 if (check_func(psdsp.add_squares, "ps_add_squares"))
244 report("add_squares");
245
246 if (check_func(psdsp.mul_pair_single, "ps_mul_pair_single"))
248 report("mul_pair_single");
249
250 if (check_func(psdsp.hybrid_analysis, "ps_hybrid_analysis"))
252 report("hybrid_analysis");
253
254 if (check_func(psdsp.hybrid_analysis_ileave, "ps_hybrid_analysis_ileave"))
256 report("hybrid_analysis_ileave");
257
258 if (check_func(psdsp.hybrid_synthesis_deint, "ps_hybrid_synthesis_deint"))
260 report("hybrid_synthesis_deint");
261
263 report("stereo_interpolate");
264}
#define randomize(buf, len)
Definition aacpsdsp.c:31
static void test_hybrid_analysis_ileave(void)
Definition aacpsdsp.c:114
#define STRIDE
Definition aacpsdsp.c:28
static void test_add_squares(void)
Definition aacpsdsp.c:51
static void test_stereo_interpolate(PSDSPContext *psdsp)
Definition aacpsdsp.c:188
static void test_hybrid_synthesis_deint(void)
Definition aacpsdsp.c:151
#define EPS
Definition aacpsdsp.c:39
static void clear_less_significant_bits(INTFLOAT *buf, int len, int bits)
Definition aacpsdsp.c:41
static void test_hybrid_analysis(void)
Definition aacpsdsp.c:89
void checkasm_check_aacpsdsp(void)
Definition aacpsdsp.c:236
static void test_mul_pair_single(void)
Definition aacpsdsp.c:70
void AAC_RENAME ff_psdsp_init(PSDSPContext *s)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
#define N
Definition af_mcompand.c:54
static FILE * out
#define L(x)
Definition vpx_arith.h:36
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define INTFLOAT
static const uint8_t bits[8]
Definition fastaudio.c:100
#define declare_func
Definition test.h:489
#define fail
Definition test.h:479
#define bench_new
Definition test.h:487
#define float_near_abs_eps_array
Definition utils.h:452
#define check_func
Definition test.h:481
#define call_new
Definition test.h:486
#define call_ref
Definition test.h:485
#define report
Definition test.h:480
#define r
Definition input.c:42
#define u(width, name, range_min, range_max)
Definition cbs_apv.c:68
#define LOCAL_ALIGNED_16(t, v,...)
#define BUF_SIZE
Definition setpts.c:159
void(* hybrid_analysis_ileave)(INTFLOAT(*restrict out)[32][2], INTFLOAT L[2][38][64], int i, int len)
Definition aacpsdsp.h:39
void(* hybrid_analysis)(INTFLOAT(*restrict out)[2], INTFLOAT(*in)[2], const INTFLOAT(*filter)[8][2], ptrdiff_t stride, int n)
Definition aacpsdsp.h:36
void(* stereo_interpolate[2])(INTFLOAT(*l)[2], INTFLOAT(*r)[2], INTFLOAT h[2][4], INTFLOAT h_step[2][4], int len)
Definition aacpsdsp.h:49
void(* mul_pair_single)(INTFLOAT(*restrict dst)[2], INTFLOAT(*src0)[2], INTFLOAT *src1, int n)
Definition aacpsdsp.h:34
void(* hybrid_synthesis_deint)(INTFLOAT out[2][38][64], INTFLOAT(*restrict in)[32][2], int i, int len)
Definition aacpsdsp.h:41
void(* add_squares)(INTFLOAT *restrict dst, const INTFLOAT(*src)[2], int n)
Definition aacpsdsp.h:33
#define stride
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition h263dsp.c:29
#define src1
Definition h264pred.c:141
#define src0
Definition h264pred.c:140
#define src
Definition vp8dsp.c:248
int len