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