FFmpeg
sbrdsp.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 "libavcodec/sbrdsp.h"
20 #include <float.h>
21 
22 #include "checkasm.h"
23 
24 #define randomize(buf, len) do { \
25  int i; \
26  for (i = 0; i < len; i++) { \
27  const INTFLOAT f = (INTFLOAT)rnd() / UINT_MAX; \
28  (buf)[i] = f; \
29  } \
30 } while (0)
31 
32 #define EPS 0.0001
33 
34 static void test_sum64x5(void)
35 {
36  LOCAL_ALIGNED_16(INTFLOAT, dst0, [64 + 256]);
37  LOCAL_ALIGNED_16(INTFLOAT, dst1, [64 + 256]);
38 
39  declare_func(void, INTFLOAT *z);
40 
41  randomize((INTFLOAT *)dst0, 64 + 256);
42  memcpy(dst1, dst0, (64 + 256) * sizeof(INTFLOAT));
43  call_ref(dst0);
44  call_new(dst1);
45  if (!float_near_abs_eps_array(dst0, dst1, EPS, 64 + 256))
46  fail();
47  bench_new(dst1);
48 }
49 
50 static void test_sum_square(void)
51 {
52  INTFLOAT res0;
53  INTFLOAT res1;
54  LOCAL_ALIGNED_16(INTFLOAT, src, [256], [2]);
55  double t = 4 * 256;
56 
57  declare_func_float(INTFLOAT, INTFLOAT (*x)[2], int n);
58 
59  randomize((INTFLOAT *)src, 256 * 2);
60  res0 = call_ref(src, 256);
61  res1 = call_new(src, 256);
62  if (!float_near_abs_eps(res0, res1, t * 2 * FLT_EPSILON))
63  fail();
64  bench_new(src, 256);
65 }
66 
67 static void test_neg_odd_64(void)
68 {
69  LOCAL_ALIGNED_16(INTFLOAT, dst0, [64]);
70  LOCAL_ALIGNED_16(INTFLOAT, dst1, [64]);
71 
72  declare_func(void, INTFLOAT *x);
73 
74  randomize((INTFLOAT *)dst0, 64);
75  memcpy(dst1, dst0, (64) * sizeof(INTFLOAT));
76  call_ref(dst0);
77  call_new(dst1);
78  if (!float_near_abs_eps_array(dst0, dst1, EPS, 64))
79  fail();
80  bench_new(dst1);
81 }
82 
83 static void test_qmf_pre_shuffle(void)
84 {
85  LOCAL_ALIGNED_16(INTFLOAT, dst0, [128]);
86  LOCAL_ALIGNED_16(INTFLOAT, dst1, [128]);
87 
88  declare_func(void, INTFLOAT *z);
89 
90  randomize((INTFLOAT *)dst0, 128);
91  memcpy(dst1, dst0, (128) * sizeof(INTFLOAT));
92  call_ref(dst0);
93  call_new(dst1);
94  if (!float_near_abs_eps_array(dst0, dst1, EPS, 128))
95  fail();
96  bench_new(dst1);
97 }
98 
99 static void test_qmf_post_shuffle(void)
100 {
101  LOCAL_ALIGNED_16(INTFLOAT, src, [64]);
102  LOCAL_ALIGNED_16(INTFLOAT, dst0, [32], [2]);
103  LOCAL_ALIGNED_16(INTFLOAT, dst1, [32], [2]);
104 
105  declare_func(void, INTFLOAT W[32][2], const INTFLOAT *z);
106 
107  randomize((INTFLOAT *)src, 64);
108  call_ref(dst0, src);
109  call_new(dst1, src);
110  if (!float_near_abs_eps_array((INTFLOAT *)dst0, (INTFLOAT *)dst1, EPS, 64))
111  fail();
112  bench_new(dst1, src);
113 }
114 
115 static void test_qmf_deint_neg(void)
116 {
117  LOCAL_ALIGNED_16(INTFLOAT, src, [64]);
118  LOCAL_ALIGNED_16(INTFLOAT, dst0, [64]);
119  LOCAL_ALIGNED_16(INTFLOAT, dst1, [64]);
120 
121  declare_func(void, INTFLOAT *v, const INTFLOAT *src);
122 
123  randomize((INTFLOAT *)src, 64);
124  call_ref(dst0, src);
125  call_new(dst1, src);
126  if (!float_near_abs_eps_array(dst0, dst1, EPS, 64))
127  fail();
128  bench_new(dst1, src);
129 }
130 
131 static void test_qmf_deint_bfly(void)
132 {
135  LOCAL_ALIGNED_16(INTFLOAT, dst0, [128]);
136  LOCAL_ALIGNED_16(INTFLOAT, dst1, [128]);
137 
138  declare_func(void, INTFLOAT *v, const INTFLOAT *src0, const INTFLOAT *src1);
139 
140  memset(dst0, 0, 128 * sizeof(INTFLOAT));
141  memset(dst1, 0, 128 * sizeof(INTFLOAT));
142 
143  randomize((INTFLOAT *)src0, 64);
144  randomize((INTFLOAT *)src1, 64);
145  call_ref(dst0, src0, src1);
146  call_new(dst1, src0, src1);
147  if (!float_near_abs_eps_array(dst0, dst1, EPS, 128))
148  fail();
149  bench_new(dst1, src0, src1);
150 }
151 
152 static void test_autocorrelate(void)
153 {
154  LOCAL_ALIGNED_16(INTFLOAT, src, [40], [2]);
155  LOCAL_ALIGNED_16(INTFLOAT, dst0, [3], [2][2]);
156  LOCAL_ALIGNED_16(INTFLOAT, dst1, [3], [2][2]);
157 
158  declare_func(void, const INTFLOAT x[40][2], INTFLOAT phi[3][2][2]);
159 
160  memset(dst0, 0, 3 * 2 * 2 * sizeof(INTFLOAT));
161  memset(dst1, 0, 3 * 2 * 2 * sizeof(INTFLOAT));
162 
163  randomize((INTFLOAT *)src, 80);
164  call_ref(src, dst0);
165  call_new(src, dst1);
166  if (!float_near_abs_eps_array((INTFLOAT *)dst0, (INTFLOAT *)dst1, EPS, 3 * 2 * 2))
167  fail();
168  bench_new(src, dst1);
169 }
170 
171 static void test_hf_gen(void)
172 {
173  LOCAL_ALIGNED_16(INTFLOAT, low, [128], [2]);
174  LOCAL_ALIGNED_16(INTFLOAT, alpha0, [2]);
175  LOCAL_ALIGNED_16(INTFLOAT, alpha1, [2]);
176  LOCAL_ALIGNED_16(INTFLOAT, dst0, [128], [2]);
177  LOCAL_ALIGNED_16(INTFLOAT, dst1, [128], [2]);
178  INTFLOAT bw = (INTFLOAT)rnd() / UINT_MAX;
179  int i;
180 
181  declare_func(void, INTFLOAT (*X_high)[2], const INTFLOAT (*X_low)[2],
182  const INTFLOAT alpha0[2], const INTFLOAT alpha1[2],
183  INTFLOAT bw, int start, int end);
184 
185  randomize((INTFLOAT *)low, 128 * 2);
186  randomize((INTFLOAT *)alpha0, 2);
187  randomize((INTFLOAT *)alpha1, 2);
188  for (i = 2; i < 64; i += 2) {
189  memset(dst0, 0, 128 * 2 * sizeof(INTFLOAT));
190  memset(dst1, 0, 128 * 2 * sizeof(INTFLOAT));
191  call_ref(dst0, low, alpha0, alpha1, 0.0, i, 128);
192  call_new(dst1, low, alpha0, alpha1, 0.0, i, 128);
193  if (!float_near_abs_eps_array((INTFLOAT *)dst0, (INTFLOAT *)dst1, EPS, 128 * 2))
194  fail();
195  bench_new(dst1, low, alpha0, alpha1, bw, i, 128);
196  }
197 }
198 
199 static void test_hf_g_filt(void)
200 {
201  LOCAL_ALIGNED_16(INTFLOAT, high, [128], [40][2]);
202  LOCAL_ALIGNED_16(INTFLOAT, g_filt, [128]);
203  LOCAL_ALIGNED_16(INTFLOAT, dst0, [128], [2]);
204  LOCAL_ALIGNED_16(INTFLOAT, dst1, [128], [2]);
205 
206  declare_func(void, INTFLOAT (*Y)[2], const INTFLOAT (*X_high)[40][2],
207  const INTFLOAT *g_filt, int m_max, intptr_t ixh);
208 
209  randomize((INTFLOAT *)high, 128 * 40 * 2);
210  randomize((INTFLOAT *)g_filt, 128);
211 
212  call_ref(dst0, high, g_filt, 128, 20);
213  call_new(dst1, high, g_filt, 128, 20);
214  if (!float_near_abs_eps_array((INTFLOAT *)dst0, (INTFLOAT *)dst1, EPS, 128 * 2))
215  fail();
216  bench_new(dst1, high, g_filt, 128, 20);
217 }
218 
219 static void test_hf_apply_noise(const SBRDSPContext *sbrdsp)
220 {
221  LOCAL_ALIGNED_16(AAC_FLOAT, s_m, [128]);
222  LOCAL_ALIGNED_16(AAC_FLOAT, q_filt, [128]);
223  LOCAL_ALIGNED_16(INTFLOAT, ref, [128], [2]);
224  LOCAL_ALIGNED_16(INTFLOAT, dst0, [128], [2]);
225  LOCAL_ALIGNED_16(INTFLOAT, dst1, [128], [2]);
226  int noise = 0x2a;
227  int i, j;
228 
229  declare_func(void, INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
230  const AAC_FLOAT *q_filt, int noise,
231  int kx, int m_max);
232 
233  randomize((INTFLOAT *)ref, 128 * 2);
234  randomize((INTFLOAT *)s_m, 128);
235  randomize((INTFLOAT *)q_filt, 128);
236 
237  for (i = 0; i < 4; i++) {
238  if (check_func(sbrdsp->hf_apply_noise[i], "hf_apply_noise_%d", i)) {
239  for (j = 0; j < 2; j++) {
240  memcpy(dst0, ref, 128 * 2 * sizeof(INTFLOAT));
241  memcpy(dst1, ref, 128 * 2 * sizeof(INTFLOAT));
242  call_ref(dst0, s_m, q_filt, noise, j, 128);
243  call_new(dst1, s_m, q_filt, noise, j, 128);
244  if (!float_near_abs_eps_array((INTFLOAT *)dst0, (INTFLOAT *)dst1, EPS, 128 * 2))
245  fail();
246  bench_new(dst1, s_m, q_filt, noise, j, 128);
247  }
248  }
249  }
250 }
251 
253 {
254  SBRDSPContext sbrdsp;
255 
256  ff_sbrdsp_init(&sbrdsp);
257 
258  if (check_func(sbrdsp.sum64x5, "sum64x5"))
259  test_sum64x5();
260  report("sum64x5");
261 
262  if (check_func(sbrdsp.sum_square, "sum_square"))
263  test_sum_square();
264  report("sum_square");
265 
266  if (check_func(sbrdsp.neg_odd_64, "neg_odd_64"))
267  test_neg_odd_64();
268  report("neg_odd_64");
269 
270  if (check_func(sbrdsp.qmf_pre_shuffle, "qmf_pre_shuffle"))
272  report("qmf_pre_shuffle");
273 
274  if (check_func(sbrdsp.qmf_post_shuffle, "qmf_post_shuffle"))
276  report("qmf_post_shuffle");
277 
278  if (check_func(sbrdsp.qmf_deint_neg, "qmf_deint_neg"))
280  report("qmf_deint_neg");
281 
282  if (check_func(sbrdsp.qmf_deint_bfly, "qmf_deint_bfly"))
284  report("qmf_deint_bfly");
285 
286  if (check_func(sbrdsp.autocorrelate, "autocorrelate"))
288  report("autocorrelate");
289 
290  if (check_func(sbrdsp.hf_gen, "hf_gen"))
291  test_hf_gen();
292  report("hf_gen");
293 
294  if (check_func(sbrdsp.hf_g_filt, "hf_g_filt"))
295  test_hf_g_filt();
296  report("hf_g_filt");
297 
298  test_hf_apply_noise(&sbrdsp);
299  report("hf_apply_noise");
300 }
void AAC_RENAME() ff_sbrdsp_init(SBRDSPContext *s)
int float_near_abs_eps_array(const float *a, const float *b, float eps, unsigned len)
Definition: checkasm.c:328
static void test_sum64x5(void)
Definition: sbrdsp.c:34
void(* sum64x5)(INTFLOAT *z)
Definition: sbrdsp.h:29
#define report
Definition: checkasm.h:126
static void test_hf_gen(void)
Definition: sbrdsp.c:171
int float_near_abs_eps(float a, float b, float eps)
Definition: checkasm.c:317
void(* neg_odd_64)(INTFLOAT *x)
Definition: sbrdsp.h:31
float INTFLOAT
Definition: aac_defines.h:86
#define randomize(buf, len)
Definition: sbrdsp.c:24
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
void(* hf_gen)(INTFLOAT(*X_high)[2], const INTFLOAT(*X_low)[2], const INTFLOAT alpha0[2], const INTFLOAT alpha1[2], INTFLOAT bw, int start, int end)
Definition: sbrdsp.h:37
static void test_neg_odd_64(void)
Definition: sbrdsp.c:67
#define src
Definition: vp8dsp.c:254
#define declare_func(ret,...)
Definition: checkasm.h:118
void checkasm_check_sbrdsp(void)
Definition: sbrdsp.c:252
static void test_qmf_deint_neg(void)
Definition: sbrdsp.c:115
#define fail()
Definition: checkasm.h:123
AAC_FLOAT(* sum_square)(INTFLOAT(*x)[2], int n)
Definition: sbrdsp.h:30
static void test_hf_g_filt(void)
Definition: sbrdsp.c:199
void(* qmf_post_shuffle)(INTFLOAT W[32][2], const INTFLOAT *z)
Definition: sbrdsp.h:33
#define Y
Definition: boxblur.h:38
float AAC_FLOAT
Definition: aac_defines.h:90
static void test_sum_square(void)
Definition: sbrdsp.c:50
#define INTFLOAT
#define call_ref(...)
Definition: checkasm.h:129
#define src1
Definition: h264pred.c:139
#define declare_func_float(ret,...)
Definition: checkasm.h:119
static void test_hf_apply_noise(const SBRDSPContext *sbrdsp)
Definition: sbrdsp.c:219
static void test_qmf_deint_bfly(void)
Definition: sbrdsp.c:131
#define check_func(func,...)
Definition: checkasm.h:114
#define src0
Definition: h264pred.c:138
#define EPS
Definition: sbrdsp.c:32
static int noise(AVBSFContext *ctx, AVPacket *pkt)
Definition: noise_bsf.c:36
void(* autocorrelate)(const INTFLOAT x[40][2], AAC_FLOAT phi[3][2][2])
Definition: sbrdsp.h:36
static void test_autocorrelate(void)
Definition: sbrdsp.c:152
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
#define rnd()
Definition: checkasm.h:107
void(* qmf_deint_neg)(INTFLOAT *v, const INTFLOAT *src)
Definition: sbrdsp.h:34
#define bench_new(...)
Definition: checkasm.h:261
void(* hf_apply_noise[4])(INTFLOAT(*Y)[2], const AAC_FLOAT *s_m, const AAC_FLOAT *q_filt, int noise, int kx, int m_max)
Definition: sbrdsp.h:42
void(* hf_g_filt)(INTFLOAT(*Y)[2], const INTFLOAT(*X_high)[40][2], const AAC_FLOAT *g_filt, int m_max, intptr_t ixh)
Definition: sbrdsp.h:40
static void test_qmf_post_shuffle(void)
Definition: sbrdsp.c:99
void(* qmf_pre_shuffle)(INTFLOAT *z)
Definition: sbrdsp.h:32
#define LOCAL_ALIGNED_16(t, v,...)
Definition: internal.h:131
#define call_new(...)
Definition: checkasm.h:201
Definition: vf_addroi.c:26
static void test_qmf_pre_shuffle(void)
Definition: sbrdsp.c:83
int i
Definition: input.c:407
void(* qmf_deint_bfly)(INTFLOAT *v, const INTFLOAT *src0, const INTFLOAT *src1)
Definition: sbrdsp.h:35