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, bw, i, 128);
194  call_new(dst1, low, alpha0, alpha1, bw, 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 
237  for (int i = 0; i < 128; i++)
238  s_m[i] = (rnd() & 1) ? ((INTFLOAT)rnd() / UINT_MAX) : (INTFLOAT)0;
239 
240  randomize((INTFLOAT *)q_filt, 128);
241 
242  for (i = 0; i < 4; i++) {
243  if (check_func(sbrdsp->hf_apply_noise[i], "hf_apply_noise_%d", i)) {
244  for (j = 0; j < 2; j++) {
245  memcpy(dst0, ref, 128 * 2 * sizeof(INTFLOAT));
246  memcpy(dst1, ref, 128 * 2 * sizeof(INTFLOAT));
247  call_ref(dst0, s_m, q_filt, noise, j, 128);
248  call_new(dst1, s_m, q_filt, noise, j, 128);
249  if (!float_near_abs_eps_array((INTFLOAT *)dst0, (INTFLOAT *)dst1, EPS, 128 * 2))
250  fail();
251  bench_new(dst1, s_m, q_filt, noise, j, 128);
252  }
253  }
254  }
255 }
256 
258 {
259  SBRDSPContext sbrdsp;
260 
261  ff_sbrdsp_init(&sbrdsp);
262 
263  if (check_func(sbrdsp.sum64x5, "sum64x5"))
264  test_sum64x5();
265  report("sum64x5");
266 
267  if (check_func(sbrdsp.sum_square, "sum_square"))
268  test_sum_square();
269  report("sum_square");
270 
271  if (check_func(sbrdsp.neg_odd_64, "neg_odd_64"))
272  test_neg_odd_64();
273  report("neg_odd_64");
274 
275  if (check_func(sbrdsp.qmf_pre_shuffle, "qmf_pre_shuffle"))
277  report("qmf_pre_shuffle");
278 
279  if (check_func(sbrdsp.qmf_post_shuffle, "qmf_post_shuffle"))
281  report("qmf_post_shuffle");
282 
283  if (check_func(sbrdsp.qmf_deint_neg, "qmf_deint_neg"))
285  report("qmf_deint_neg");
286 
287  if (check_func(sbrdsp.qmf_deint_bfly, "qmf_deint_bfly"))
289  report("qmf_deint_bfly");
290 
291  if (check_func(sbrdsp.autocorrelate, "autocorrelate"))
293  report("autocorrelate");
294 
295  if (check_func(sbrdsp.hf_gen, "hf_gen"))
296  test_hf_gen();
297  report("hf_gen");
298 
299  if (check_func(sbrdsp.hf_g_filt, "hf_g_filt"))
300  test_hf_g_filt();
301  report("hf_g_filt");
302 
303  test_hf_apply_noise(&sbrdsp);
304  report("hf_apply_noise");
305 }
SBRDSPContext::hf_gen
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:36
INTFLOAT
#define INTFLOAT
Definition: dct32_template.c:44
mem_internal.h
SBRDSPContext
Definition: sbrdsp.h:27
test_qmf_deint_bfly
static void test_qmf_deint_bfly(void)
Definition: sbrdsp.c:133
float_near_abs_eps_array
int float_near_abs_eps_array(const float *a, const float *b, float eps, unsigned len)
Definition: checkasm.c:399
src1
const pixel * src1
Definition: h264pred_template.c:421
float_near_abs_eps
int float_near_abs_eps(float a, float b, float eps)
Definition: checkasm.c:388
check_func
#define check_func(func,...)
Definition: checkasm.h:170
float.h
declare_func_float
#define declare_func_float(ret,...)
Definition: checkasm.h:175
call_ref
#define call_ref(...)
Definition: checkasm.h:185
fail
#define fail()
Definition: checkasm.h:179
test_hf_apply_noise
static void test_hf_apply_noise(const SBRDSPContext *sbrdsp)
Definition: sbrdsp.c:221
noise
static int noise(AVBSFContext *ctx, AVPacket *pkt)
Definition: noise.c:126
checkasm.h
test_qmf_post_shuffle
static void test_qmf_post_shuffle(void)
Definition: sbrdsp.c:101
rnd
#define rnd()
Definition: checkasm.h:163
test_hf_g_filt
static void test_hf_g_filt(void)
Definition: sbrdsp.c:201
EPS
#define EPS
Definition: sbrdsp.c:34
test_hf_gen
static void test_hf_gen(void)
Definition: sbrdsp.c:173
LOCAL_ALIGNED_16
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:150
test_autocorrelate
static void test_autocorrelate(void)
Definition: sbrdsp.c:154
test_sum_square
static void test_sum_square(void)
Definition: sbrdsp.c:52
SBRDSPContext::autocorrelate
void(* autocorrelate)(const INTFLOAT x[40][2], AAC_FLOAT phi[3][2][2])
Definition: sbrdsp.h:35
call_new
#define call_new(...)
Definition: checkasm.h:288
checkasm_check_sbrdsp
void checkasm_check_sbrdsp(void)
Definition: sbrdsp.c:257
test_sum64x5
static void test_sum64x5(void)
Definition: sbrdsp.c:36
SBRDSPContext::neg_odd_64
void(* neg_odd_64)(INTFLOAT *x)
Definition: sbrdsp.h:30
SBRDSPContext::hf_g_filt
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:39
SBRDSPContext::qmf_deint_bfly
void(* qmf_deint_bfly)(INTFLOAT *v, const INTFLOAT *src0, const INTFLOAT *src1)
Definition: sbrdsp.h:34
SBRDSPContext::sum64x5
void(* sum64x5)(INTFLOAT *z)
Definition: sbrdsp.h:28
SBRDSPContext::qmf_pre_shuffle
void(* qmf_pre_shuffle)(INTFLOAT *z)
Definition: sbrdsp.h:31
test_qmf_pre_shuffle
static void test_qmf_pre_shuffle(void)
Definition: sbrdsp.c:85
test_qmf_deint_neg
static void test_qmf_deint_neg(void)
Definition: sbrdsp.c:117
sbrdsp.h
SBRDSPContext::qmf_deint_neg
void(* qmf_deint_neg)(INTFLOAT *v, const INTFLOAT *src)
Definition: sbrdsp.h:33
SBRDSPContext::hf_apply_noise
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:41
Y
#define Y
Definition: boxblur.h:37
ff_sbrdsp_init
void AAC_RENAME() ff_sbrdsp_init(SBRDSPContext *s)
Definition: sbrdsp_template.c:80
W
@ W
Definition: vf_addroi.c:27
report
#define report
Definition: checkasm.h:182
bench_new
#define bench_new(...)
Definition: checkasm.h:358
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
test_neg_odd_64
static void test_neg_odd_64(void)
Definition: sbrdsp.c:69
SBRDSPContext::qmf_post_shuffle
void(* qmf_post_shuffle)(INTFLOAT W[32][2], const INTFLOAT *z)
Definition: sbrdsp.h:32
randomize
#define randomize(buf, len)
Definition: sbrdsp.c:26
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
src0
const pixel *const src0
Definition: h264pred_template.c:420
SBRDSPContext::sum_square
AAC_FLOAT(* sum_square)(INTFLOAT(*x)[2], int n)
Definition: sbrdsp.h:29
declare_func
#define declare_func(ret,...)
Definition: checkasm.h:174
AAC_FLOAT
float AAC_FLOAT
Definition: aac_defines.h:92
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
INTFLOAT
float INTFLOAT
Definition: aac_defines.h:88