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 36static 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 52static 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 69static 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 85static 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 101static 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 117static 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 133static void test_qmf_deint_bfly(void) 134{ 135 LOCAL_ALIGNED_16(INTFLOAT, src0, [64]); 136 LOCAL_ALIGNED_16(INTFLOAT, src1, [64]); 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 154static 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 173static 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 201static 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 221static 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 254void checkasm_check_sbrdsp(void) 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")) 273 test_qmf_pre_shuffle(); 274 report("qmf_pre_shuffle"); 275 276 if (check_func(sbrdsp.qmf_post_shuffle, "qmf_post_shuffle")) 277 test_qmf_post_shuffle(); 278 report("qmf_post_shuffle"); 279 280 if (check_func(sbrdsp.qmf_deint_neg, "qmf_deint_neg")) 281 test_qmf_deint_neg(); 282 report("qmf_deint_neg"); 283 284 if (check_func(sbrdsp.qmf_deint_bfly, "qmf_deint_bfly")) 285 test_qmf_deint_bfly(); 286 report("qmf_deint_bfly"); 287 288 if (check_func(sbrdsp.autocorrelate, "autocorrelate")) 289 test_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} 303