| Line | Branch | Exec | Source |
|---|---|---|---|
| 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.h" | ||
| 20 | #include "libavutil/mem_internal.h" | ||
| 21 | #include "libavutil/tx.h" | ||
| 22 | #include "libavutil/error.h" | ||
| 23 | |||
| 24 | #include "checkasm.h" | ||
| 25 | |||
| 26 | #include <stdlib.h> | ||
| 27 | |||
| 28 | #define EPS 0.0005 | ||
| 29 | |||
| 30 | #define SCALE_NOOP(x) (x) | ||
| 31 | #define SCALE_INT20(x) (av_clip64(lrintf((x) * 2147483648.0), INT32_MIN, INT32_MAX) >> 12) | ||
| 32 | |||
| 33 | #define randomize_complex(BUF, LEN, TYPE, SCALE) \ | ||
| 34 | do { \ | ||
| 35 | TYPE *buf = (TYPE *)BUF; \ | ||
| 36 | for (int i = 0; i < LEN; i++) { \ | ||
| 37 | double fre = (double)rnd() / UINT_MAX; \ | ||
| 38 | double fim = (double)rnd() / UINT_MAX; \ | ||
| 39 | buf[i] = (TYPE){ SCALE(fre), SCALE(fim) }; \ | ||
| 40 | } \ | ||
| 41 | } while (0) | ||
| 42 | |||
| 43 | static const int check_lens[] = { | ||
| 44 | 2, 4, 8, 16, 32, 64, 120, 960, 1024, 1920, 16384, | ||
| 45 | }; | ||
| 46 | |||
| 47 | static AVTXContext *tx_refs[AV_TX_NB][2 /* Direction */][FF_ARRAY_ELEMS(check_lens)] = { 0 }; | ||
| 48 | static int init = 0; | ||
| 49 | |||
| 50 | 1 | static void free_tx_refs(void) | |
| 51 | { | ||
| 52 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1 times.
|
19 | for (int i = 0; i < FF_ARRAY_ELEMS(tx_refs); i++) |
| 53 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 18 times.
|
54 | for (int j = 0; j < FF_ARRAY_ELEMS(*tx_refs); j++) |
| 54 |
2/2✓ Branch 0 taken 396 times.
✓ Branch 1 taken 36 times.
|
432 | for (int k = 0; k < FF_ARRAY_ELEMS(**tx_refs); k++) |
| 55 | 396 | av_tx_uninit(&tx_refs[i][j][k]); | |
| 56 | 1 | } | |
| 57 | |||
| 58 | #define CHECK_TEMPLATE(PREFIX, TYPE, DIR, DATA_TYPE, SCALE_TYPE, LENGTHS, CHECK_EXPRESSION) \ | ||
| 59 | do { \ | ||
| 60 | int err; \ | ||
| 61 | AVTXContext *tx; \ | ||
| 62 | av_tx_fn fn; \ | ||
| 63 | int num_checks = 0; \ | ||
| 64 | int last_check = 0; \ | ||
| 65 | \ | ||
| 66 | for (int i = 0; i < FF_ARRAY_ELEMS(LENGTHS); i++) { \ | ||
| 67 | int len = LENGTHS[i]; \ | ||
| 68 | const SCALE_TYPE scale = 1.0 / len; \ | ||
| 69 | \ | ||
| 70 | if ((err = av_tx_init(&tx, &fn, TYPE, DIR, len, &scale, 0x0)) < 0) { \ | ||
| 71 | fprintf(stderr, "av_tx: %s\n", av_err2str(err)); \ | ||
| 72 | return; \ | ||
| 73 | } \ | ||
| 74 | \ | ||
| 75 | if (check_func(fn, PREFIX "_%i", len)) { \ | ||
| 76 | AVTXContext *tx_ref = tx_refs[TYPE][DIR][i]; \ | ||
| 77 | if (!tx_ref) \ | ||
| 78 | tx_ref = tx; \ | ||
| 79 | num_checks++; \ | ||
| 80 | last_check = len; \ | ||
| 81 | call_ref(tx_ref, out_ref, in, sizeof(DATA_TYPE)); \ | ||
| 82 | call_new(tx, out_new, in, sizeof(DATA_TYPE)); \ | ||
| 83 | if (CHECK_EXPRESSION) { \ | ||
| 84 | fail(); \ | ||
| 85 | av_tx_uninit(&tx); \ | ||
| 86 | break; \ | ||
| 87 | } \ | ||
| 88 | bench_new(tx, out_new, in, sizeof(DATA_TYPE)); \ | ||
| 89 | av_tx_uninit(&tx_refs[TYPE][DIR][i]); \ | ||
| 90 | tx_refs[TYPE][DIR][i] = tx; \ | ||
| 91 | } else { \ | ||
| 92 | av_tx_uninit(&tx); \ | ||
| 93 | } \ | ||
| 94 | } \ | ||
| 95 | \ | ||
| 96 | if (num_checks == 1) \ | ||
| 97 | report(PREFIX "_%i", last_check); \ | ||
| 98 | else if (num_checks) \ | ||
| 99 | report(PREFIX); \ | ||
| 100 | } while (0) | ||
| 101 | |||
| 102 | 13 | void checkasm_check_av_tx(void) | |
| 103 | { | ||
| 104 | 13 | declare_func(void, AVTXContext *tx, void *out, void *in, ptrdiff_t stride); | |
| 105 | |||
| 106 | 13 | void *in = av_malloc(16384*2*8); | |
| 107 | 13 | void *out_ref = av_malloc(16384*2*8); | |
| 108 | 13 | void *out_new = av_malloc(16384*2*8); | |
| 109 | |||
| 110 |
2/2✓ Branch 2 taken 212992 times.
✓ Branch 3 taken 13 times.
|
213005 | randomize_complex(in, 16384, AVComplexFloat, SCALE_NOOP); |
| 111 |
13/22✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
✓ Branch 8 taken 31 times.
✓ Branch 9 taken 112 times.
✓ Branch 10 taken 11 times.
✓ Branch 11 taken 20 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 31 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 31 times.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✓ Branch 74 taken 143 times.
✓ Branch 75 taken 13 times.
✓ Branch 76 taken 1 times.
✓ Branch 77 taken 12 times.
✓ Branch 79 taken 5 times.
✓ Branch 80 taken 7 times.
|
156 | CHECK_TEMPLATE("float_fft", AV_TX_FLOAT_FFT, 0, AVComplexFloat, float, check_lens, |
| 112 | !float_near_abs_eps_array(out_ref, out_new, EPS, len*2)); | ||
| 113 | |||
| 114 |
12/22✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
✓ Branch 8 taken 19 times.
✓ Branch 9 taken 124 times.
✓ Branch 10 taken 11 times.
✓ Branch 11 taken 8 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 19 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 19 times.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✓ Branch 74 taken 143 times.
✓ Branch 75 taken 13 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 13 times.
✓ Branch 79 taken 2 times.
✓ Branch 80 taken 11 times.
|
156 | CHECK_TEMPLATE("float_imdct", AV_TX_FLOAT_MDCT, 1, float, float, check_lens, |
| 115 | !float_near_abs_eps_array(out_ref, out_new, EPS, len)); | ||
| 116 | |||
| 117 |
2/2✓ Branch 2 taken 212992 times.
✓ Branch 3 taken 13 times.
|
213005 | randomize_complex(in, 16384, AVComplexDouble, SCALE_NOOP); |
| 118 |
11/22✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
✓ Branch 8 taken 11 times.
✓ Branch 9 taken 132 times.
✓ Branch 10 taken 11 times.
✗ Branch 11 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 11 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 11 times.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✓ Branch 74 taken 143 times.
✓ Branch 75 taken 13 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 13 times.
✓ Branch 79 taken 1 times.
✓ Branch 80 taken 12 times.
|
156 | CHECK_TEMPLATE("double_fft", AV_TX_DOUBLE_FFT, 0, AVComplexDouble, double, check_lens, |
| 119 | !double_near_abs_eps_array(out_ref, out_new, EPS, len*2)); | ||
| 120 | |||
| 121 | 13 | av_free(in); | |
| 122 | 13 | av_free(out_ref); | |
| 123 | 13 | av_free(out_new); | |
| 124 | |||
| 125 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
|
13 | if (!init) { |
| 126 | 1 | init = 1; | |
| 127 | 1 | atexit(free_tx_refs); | |
| 128 | } | ||
| 129 | } | ||
| 130 |