| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of FFmpeg. | ||
| 3 | * | ||
| 4 | * FFmpeg is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU Lesser General Public | ||
| 6 | * License as published by the Free Software Foundation; either | ||
| 7 | * version 2.1 of the License, or (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 GNU | ||
| 12 | * Lesser General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU Lesser General Public | ||
| 15 | * License along with FFmpeg; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include "avassert.h" | ||
| 20 | #include "intmath.h" | ||
| 21 | #include "cpu.h" | ||
| 22 | #include "mem.h" | ||
| 23 | #include "qsort.h" | ||
| 24 | #include "bprint.h" | ||
| 25 | |||
| 26 | #include "tx_priv.h" | ||
| 27 | |||
| 28 | #define TYPE_IS(type, x) \ | ||
| 29 | (((x) == AV_TX_FLOAT_ ## type) || \ | ||
| 30 | ((x) == AV_TX_DOUBLE_ ## type) || \ | ||
| 31 | ((x) == AV_TX_INT32_ ## type)) | ||
| 32 | |||
| 33 | /* Calculates the modular multiplicative inverse */ | ||
| 34 | 5036 | static av_always_inline int mulinv(int n, int m) | |
| 35 | { | ||
| 36 | 5036 | n = n % m; | |
| 37 |
1/2✓ Branch 0 taken 51195 times.
✗ Branch 1 not taken.
|
51195 | for (int x = 1; x < m; x++) |
| 38 |
2/2✓ Branch 0 taken 5036 times.
✓ Branch 1 taken 46159 times.
|
51195 | if (((n * x) % m) == 1) |
| 39 | 5036 | return x; | |
| 40 | ✗ | av_assert0(0); /* Never reached */ | |
| 41 | return 0; | ||
| 42 | } | ||
| 43 | |||
| 44 | 81 | int ff_tx_gen_pfa_input_map(AVTXContext *s, FFTXCodeletOptions *opts, | |
| 45 | int d1, int d2) | ||
| 46 | { | ||
| 47 | 81 | const int sl = d1*d2; | |
| 48 | |||
| 49 | 81 | s->map = av_malloc(s->len*sizeof(*s->map)); | |
| 50 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 81 times.
|
81 | if (!s->map) |
| 51 | ✗ | return AVERROR(ENOMEM); | |
| 52 | |||
| 53 |
2/2✓ Branch 0 taken 81 times.
✓ Branch 1 taken 81 times.
|
162 | for (int k = 0; k < s->len; k += sl) { |
| 54 |
3/6✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 81 times.
|
81 | if (s->inv || (opts && opts->map_dir == FF_TX_MAP_SCATTER)) { |
| 55 | ✗ | for (int m = 0; m < d2; m++) | |
| 56 | ✗ | for (int n = 0; n < d1; n++) | |
| 57 | ✗ | s->map[k + ((m*d1 + n*d2) % (sl))] = m*d1 + n; | |
| 58 | } else { | ||
| 59 |
2/2✓ Branch 0 taken 405 times.
✓ Branch 1 taken 81 times.
|
486 | for (int m = 0; m < d2; m++) |
| 60 |
2/2✓ Branch 0 taken 1215 times.
✓ Branch 1 taken 405 times.
|
1620 | for (int n = 0; n < d1; n++) |
| 61 | 1215 | s->map[k + m*d1 + n] = (m*d1 + n*d2) % (sl); | |
| 62 | } | ||
| 63 | |||
| 64 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 81 times.
|
81 | if (s->inv) |
| 65 | ✗ | for (int w = 1; w <= ((sl) >> 1); w++) | |
| 66 | ✗ | FFSWAP(int, s->map[k + w], s->map[k + sl - w]); | |
| 67 | } | ||
| 68 | |||
| 69 |
1/2✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
|
81 | s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER; |
| 70 | |||
| 71 | 81 | return 0; | |
| 72 | } | ||
| 73 | |||
| 74 | /* Guaranteed to work for any n, m where gcd(n, m) == 1 */ | ||
| 75 | 2518 | int ff_tx_gen_compound_mapping(AVTXContext *s, FFTXCodeletOptions *opts, | |
| 76 | int inv, int n, int m) | ||
| 77 | { | ||
| 78 | int *in_map, *out_map; | ||
| 79 | 2518 | const int len = n*m; /* Will not be equal to s->len for MDCTs */ | |
| 80 | int m_inv, n_inv; | ||
| 81 | |||
| 82 | /* Make sure the numbers are coprime */ | ||
| 83 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2518 times.
|
2518 | if (av_gcd(n, m) != 1) |
| 84 | ✗ | return AVERROR(EINVAL); | |
| 85 | |||
| 86 | 2518 | m_inv = mulinv(m, n); | |
| 87 | 2518 | n_inv = mulinv(n, m); | |
| 88 | |||
| 89 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2518 times.
|
2518 | if (!(s->map = av_malloc(2*len*sizeof(*s->map)))) |
| 90 | ✗ | return AVERROR(ENOMEM); | |
| 91 | |||
| 92 | 2518 | in_map = s->map; | |
| 93 | 2518 | out_map = s->map + len; | |
| 94 | |||
| 95 | /* Ruritanian map for input, CRT map for output, can be swapped */ | ||
| 96 |
3/4✓ Branch 0 taken 465 times.
✓ Branch 1 taken 2053 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 465 times.
|
2518 | if (opts && opts->map_dir == FF_TX_MAP_SCATTER) { |
| 97 | ✗ | for (int j = 0; j < m; j++) { | |
| 98 | ✗ | for (int i = 0; i < n; i++) { | |
| 99 | ✗ | in_map[(i*m + j*n) % len] = j*n + i; | |
| 100 | ✗ | out_map[(i*m*m_inv + j*n*n_inv) % len] = i*m + j; | |
| 101 | } | ||
| 102 | } | ||
| 103 | } else { | ||
| 104 |
2/2✓ Branch 0 taken 86588 times.
✓ Branch 1 taken 2518 times.
|
89106 | for (int j = 0; j < m; j++) { |
| 105 |
2/2✓ Branch 0 taken 671988 times.
✓ Branch 1 taken 86588 times.
|
758576 | for (int i = 0; i < n; i++) { |
| 106 | 671988 | in_map[j*n + i] = (i*m + j*n) % len; | |
| 107 | 671988 | out_map[(i*m*m_inv + j*n*n_inv) % len] = i*m + j; | |
| 108 | } | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 |
2/2✓ Branch 0 taken 2410 times.
✓ Branch 1 taken 108 times.
|
2518 | if (inv) { |
| 113 |
2/2✓ Branch 0 taken 80756 times.
✓ Branch 1 taken 2410 times.
|
83166 | for (int i = 0; i < m; i++) { |
| 114 | 80756 | int *in = &in_map[i*n + 1]; /* Skip the DC */ | |
| 115 |
2/2✓ Branch 0 taken 252204 times.
✓ Branch 1 taken 80756 times.
|
332960 | for (int j = 0; j < ((n - 1) >> 1); j++) |
| 116 | 252204 | FFSWAP(int, in[j], in[n - j - 2]); | |
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 |
2/2✓ Branch 0 taken 465 times.
✓ Branch 1 taken 2053 times.
|
2518 | s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER; |
| 121 | |||
| 122 | 2518 | return 0; | |
| 123 | } | ||
| 124 | |||
| 125 | 11724046 | static inline int split_radix_permutation(int i, int len, int inv) | |
| 126 | { | ||
| 127 | 11724046 | len >>= 1; | |
| 128 |
2/2✓ Branch 0 taken 1525678 times.
✓ Branch 1 taken 10198368 times.
|
11724046 | if (len <= 1) |
| 129 | 1525678 | return i & 1; | |
| 130 |
2/2✓ Branch 0 taken 5099184 times.
✓ Branch 1 taken 5099184 times.
|
10198368 | if (!(i & len)) |
| 131 | 5099184 | return split_radix_permutation(i, len, inv) * 2; | |
| 132 | 5099184 | len >>= 1; | |
| 133 | 5099184 | return split_radix_permutation(i, len, inv) * 4 + 1 - 2*(!(i & len) ^ inv); | |
| 134 | } | ||
| 135 | |||
| 136 | 4832 | int ff_tx_gen_ptwo_revtab(AVTXContext *s, FFTXCodeletOptions *opts) | |
| 137 | { | ||
| 138 | 4832 | int len = s->len; | |
| 139 | |||
| 140 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4832 times.
|
4832 | if (!(s->map = av_malloc(len*sizeof(*s->map)))) |
| 141 | ✗ | return AVERROR(ENOMEM); | |
| 142 | |||
| 143 |
3/4✓ Branch 0 taken 4832 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2217 times.
✓ Branch 3 taken 2615 times.
|
4832 | if (opts && opts->map_dir == FF_TX_MAP_SCATTER) { |
| 144 |
2/2✓ Branch 0 taken 232584 times.
✓ Branch 1 taken 2217 times.
|
234801 | for (int i = 0; i < s->len; i++) |
| 145 | 232584 | s->map[-split_radix_permutation(i, len, s->inv) & (len - 1)] = i; | |
| 146 | } else { | ||
| 147 |
2/2✓ Branch 0 taken 1056394 times.
✓ Branch 1 taken 2615 times.
|
1059009 | for (int i = 0; i < s->len; i++) |
| 148 | 1056394 | s->map[i] = -split_radix_permutation(i, len, s->inv) & (len - 1); | |
| 149 | } | ||
| 150 | |||
| 151 |
1/2✓ Branch 0 taken 4832 times.
✗ Branch 1 not taken.
|
4832 | s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER; |
| 152 | |||
| 153 | 4832 | return 0; | |
| 154 | } | ||
| 155 | |||
| 156 | ✗ | int ff_tx_gen_inplace_map(AVTXContext *s, int len) | |
| 157 | { | ||
| 158 | ✗ | int *src_map, out_map_idx = 0; | |
| 159 | |||
| 160 | ✗ | if (!s->sub || !s->sub->map) | |
| 161 | ✗ | return AVERROR(EINVAL); | |
| 162 | |||
| 163 | ✗ | if (!(s->map = av_mallocz(len*sizeof(*s->map)))) | |
| 164 | ✗ | return AVERROR(ENOMEM); | |
| 165 | |||
| 166 | ✗ | src_map = s->sub->map; | |
| 167 | |||
| 168 | /* The first coefficient is always already in-place */ | ||
| 169 | ✗ | for (int src = 1; src < s->len; src++) { | |
| 170 | ✗ | int dst = src_map[src]; | |
| 171 | ✗ | int found = 0; | |
| 172 | |||
| 173 | ✗ | if (dst <= src) | |
| 174 | ✗ | continue; | |
| 175 | |||
| 176 | /* This just checks if a closed loop has been encountered before, | ||
| 177 | * and if so, skips it, since to fully permute a loop we must only | ||
| 178 | * enter it once. */ | ||
| 179 | do { | ||
| 180 | ✗ | for (int j = 0; j < out_map_idx; j++) { | |
| 181 | ✗ | if (dst == s->map[j]) { | |
| 182 | ✗ | found = 1; | |
| 183 | ✗ | break; | |
| 184 | } | ||
| 185 | } | ||
| 186 | ✗ | dst = src_map[dst]; | |
| 187 | ✗ | } while (dst != src && !found); | |
| 188 | |||
| 189 | ✗ | if (!found) | |
| 190 | ✗ | s->map[out_map_idx++] = src; | |
| 191 | } | ||
| 192 | |||
| 193 | ✗ | s->map[out_map_idx++] = 0; | |
| 194 | |||
| 195 | ✗ | return 0; | |
| 196 | } | ||
| 197 | |||
| 198 | 58412 | static void parity_revtab_generator(int *revtab, int n, int inv, int offset, | |
| 199 | int is_dual, int dual_high, int len, | ||
| 200 | int basis, int dual_stride, int inv_lookup) | ||
| 201 | { | ||
| 202 | 58412 | len >>= 1; | |
| 203 | |||
| 204 |
2/2✓ Branch 0 taken 39411 times.
✓ Branch 1 taken 19001 times.
|
58412 | if (len <= basis) { |
| 205 | int k1, k2, stride, even_idx, odd_idx; | ||
| 206 | |||
| 207 |
3/4✓ Branch 0 taken 29410 times.
✓ Branch 1 taken 10001 times.
✓ Branch 2 taken 29410 times.
✗ Branch 3 not taken.
|
39411 | is_dual = is_dual && dual_stride; |
| 208 | 39411 | dual_high = is_dual & dual_high; | |
| 209 |
2/2✓ Branch 0 taken 29410 times.
✓ Branch 1 taken 10001 times.
|
39411 | stride = is_dual ? FFMIN(dual_stride, len) : 0; |
| 210 | |||
| 211 | 39411 | even_idx = offset + dual_high*(stride - 2*len); | |
| 212 |
4/4✓ Branch 0 taken 29410 times.
✓ Branch 1 taken 10001 times.
✓ Branch 2 taken 14705 times.
✓ Branch 3 taken 14705 times.
|
39411 | odd_idx = even_idx + len + (is_dual && !dual_high)*len + dual_high*len; |
| 213 | |||
| 214 |
2/2✓ Branch 0 taken 118350 times.
✓ Branch 1 taken 39411 times.
|
157761 | for (int i = 0; i < len; i++) { |
| 215 | 118350 | k1 = -split_radix_permutation(offset + i*2 + 0, n, inv) & (n - 1); | |
| 216 | 118350 | k2 = -split_radix_permutation(offset + i*2 + 1, n, inv) & (n - 1); | |
| 217 |
2/2✓ Branch 0 taken 91156 times.
✓ Branch 1 taken 27194 times.
|
118350 | if (inv_lookup) { |
| 218 | 91156 | revtab[even_idx++] = k1; | |
| 219 | 91156 | revtab[odd_idx++] = k2; | |
| 220 | } else { | ||
| 221 | 27194 | revtab[k1] = even_idx++; | |
| 222 | 27194 | revtab[k2] = odd_idx++; | |
| 223 | } | ||
| 224 |
4/4✓ Branch 0 taken 78652 times.
✓ Branch 1 taken 39698 times.
✓ Branch 2 taken 39326 times.
✓ Branch 3 taken 39326 times.
|
118350 | if (stride && !((i + 1) % stride)) { |
| 225 | 39326 | even_idx += stride; | |
| 226 | 39326 | odd_idx += stride; | |
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | 39411 | return; | |
| 231 | } | ||
| 232 | |||
| 233 | 19001 | parity_revtab_generator(revtab, n, inv, offset, | |
| 234 | 0, 0, len >> 0, basis, dual_stride, inv_lookup); | ||
| 235 | 19001 | parity_revtab_generator(revtab, n, inv, offset + (len >> 0), | |
| 236 | 1, 0, len >> 1, basis, dual_stride, inv_lookup); | ||
| 237 | 19001 | parity_revtab_generator(revtab, n, inv, offset + (len >> 0) + (len >> 1), | |
| 238 | 1, 1, len >> 1, basis, dual_stride, inv_lookup); | ||
| 239 | } | ||
| 240 | |||
| 241 | 1409 | int ff_tx_gen_split_radix_parity_revtab(AVTXContext *s, int len, int inv, | |
| 242 | FFTXCodeletOptions *opts, | ||
| 243 | int basis, int dual_stride) | ||
| 244 | { | ||
| 245 | 1409 | basis >>= 1; | |
| 246 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1409 times.
|
1409 | if (len < basis) |
| 247 | ✗ | return AVERROR(EINVAL); | |
| 248 | |||
| 249 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1409 times.
|
1409 | if (!(s->map = av_mallocz(len*sizeof(*s->map)))) |
| 250 | ✗ | return AVERROR(ENOMEM); | |
| 251 | |||
| 252 |
3/4✓ Branch 0 taken 1155 times.
✓ Branch 1 taken 254 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1155 times.
|
1409 | av_assert0(!dual_stride || !(dual_stride & (dual_stride - 1))); |
| 253 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1409 times.
|
1409 | av_assert0(dual_stride <= basis); |
| 254 | |||
| 255 |
2/2✓ Branch 0 taken 1385 times.
✓ Branch 1 taken 24 times.
|
2794 | parity_revtab_generator(s->map, len, inv, 0, 0, 0, len, |
| 256 | basis, dual_stride, | ||
| 257 |
2/2✓ Branch 0 taken 673 times.
✓ Branch 1 taken 712 times.
|
1385 | opts ? opts->map_dir == FF_TX_MAP_GATHER : FF_TX_MAP_GATHER); |
| 258 | |||
| 259 |
2/2✓ Branch 0 taken 1385 times.
✓ Branch 1 taken 24 times.
|
1409 | s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER; |
| 260 | |||
| 261 | 1409 | return 0; | |
| 262 | } | ||
| 263 | |||
| 264 | 38687 | static void reset_ctx(AVTXContext *s, int free_sub) | |
| 265 | { | ||
| 266 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 38687 times.
|
38687 | if (!s) |
| 267 | ✗ | return; | |
| 268 | |||
| 269 |
2/2✓ Branch 0 taken 6883 times.
✓ Branch 1 taken 31804 times.
|
38687 | if (s->sub) |
| 270 |
2/2✓ Branch 0 taken 27532 times.
✓ Branch 1 taken 6883 times.
|
34415 | for (int i = 0; i < TX_MAX_SUB; i++) |
| 271 | 27532 | reset_ctx(&s->sub[i], free_sub + 1); | |
| 272 | |||
| 273 |
3/4✓ Branch 0 taken 18135 times.
✓ Branch 1 taken 20552 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18135 times.
|
38687 | if (s->cd_self && s->cd_self->uninit) |
| 274 | ✗ | s->cd_self->uninit(s); | |
| 275 | |||
| 276 |
2/2✓ Branch 0 taken 33822 times.
✓ Branch 1 taken 4865 times.
|
38687 | if (free_sub) |
| 277 | 33822 | av_freep(&s->sub); | |
| 278 | |||
| 279 | 38687 | av_freep(&s->map); | |
| 280 | 38687 | av_freep(&s->exp); | |
| 281 | 38687 | av_freep(&s->tmp); | |
| 282 | |||
| 283 | /* Nothing else needs to be reset, it gets overwritten if another | ||
| 284 | * ff_tx_init_subtx() call is made. */ | ||
| 285 | 38687 | s->nb_sub = 0; | |
| 286 | 38687 | s->opaque = NULL; | |
| 287 | 38687 | memset(s->fn, 0, sizeof(s->fn)); | |
| 288 | } | ||
| 289 | |||
| 290 | 97 | void ff_tx_clear_ctx(AVTXContext *s) | |
| 291 | { | ||
| 292 | 97 | reset_ctx(s, 0); | |
| 293 | 97 | } | |
| 294 | |||
| 295 | 6939 | av_cold void av_tx_uninit(AVTXContext **ctx) | |
| 296 | { | ||
| 297 |
2/2✓ Branch 0 taken 649 times.
✓ Branch 1 taken 6290 times.
|
6939 | if (!(*ctx)) |
| 298 | 649 | return; | |
| 299 | |||
| 300 | 6290 | reset_ctx(*ctx, 1); | |
| 301 | 6290 | av_freep(ctx); | |
| 302 | } | ||
| 303 | |||
| 304 | 14 | static av_cold int ff_tx_null_init(AVTXContext *s, const FFTXCodelet *cd, | |
| 305 | uint64_t flags, FFTXCodeletOptions *opts, | ||
| 306 | int len, int inv, const void *scale) | ||
| 307 | { | ||
| 308 | /* Can only handle one sample+type to one sample+type transforms */ | ||
| 309 |
6/12✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 14 times.
|
14 | if (TYPE_IS(MDCT, s->type) || TYPE_IS(RDFT, s->type)) |
| 310 | ✗ | return AVERROR(EINVAL); | |
| 311 | 14 | return 0; | |
| 312 | } | ||
| 313 | |||
| 314 | /* Null transform when the length is 1 */ | ||
| 315 | 3 | static void ff_tx_null(AVTXContext *s, void *_out, void *_in, ptrdiff_t stride) | |
| 316 | { | ||
| 317 | 3 | memcpy(_out, _in, stride); | |
| 318 | 3 | } | |
| 319 | |||
| 320 | static const FFTXCodelet ff_tx_null_def = { | ||
| 321 | .name = NULL_IF_CONFIG_SMALL("null"), | ||
| 322 | .function = ff_tx_null, | ||
| 323 | .type = TX_TYPE_ANY, | ||
| 324 | .flags = AV_TX_UNALIGNED | FF_TX_ALIGNED | | ||
| 325 | FF_TX_OUT_OF_PLACE | AV_TX_INPLACE, | ||
| 326 | .factors[0] = TX_FACTOR_ANY, | ||
| 327 | .min_len = 1, | ||
| 328 | .max_len = 1, | ||
| 329 | .init = ff_tx_null_init, | ||
| 330 | .cpu_flags = FF_TX_CPU_FLAGS_ALL, | ||
| 331 | .prio = FF_TX_PRIO_MAX, | ||
| 332 | }; | ||
| 333 | |||
| 334 | static const FFTXCodelet * const ff_tx_null_list[] = { | ||
| 335 | &ff_tx_null_def, | ||
| 336 | NULL, | ||
| 337 | }; | ||
| 338 | |||
| 339 | /* Array of all compiled codelet lists. Order is irrelevant. */ | ||
| 340 | static const FFTXCodelet * const * const codelet_list[] = { | ||
| 341 | ff_tx_codelet_list_float_c, | ||
| 342 | ff_tx_codelet_list_double_c, | ||
| 343 | ff_tx_codelet_list_int32_c, | ||
| 344 | ff_tx_null_list, | ||
| 345 | #if HAVE_X86ASM | ||
| 346 | ff_tx_codelet_list_float_x86, | ||
| 347 | #endif | ||
| 348 | #if ARCH_AARCH64 | ||
| 349 | ff_tx_codelet_list_float_aarch64, | ||
| 350 | #endif | ||
| 351 | }; | ||
| 352 | static const int codelet_list_num = FF_ARRAY_ELEMS(codelet_list); | ||
| 353 | |||
| 354 | static const int cpu_slow_mask = AV_CPU_FLAG_SSE2SLOW | AV_CPU_FLAG_SSE3SLOW | | ||
| 355 | AV_CPU_FLAG_ATOM | AV_CPU_FLAG_SSSE3SLOW | | ||
| 356 | AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER; | ||
| 357 | |||
| 358 | static const int cpu_slow_penalties[][2] = { | ||
| 359 | { AV_CPU_FLAG_SSE2SLOW, 1 + 64 }, | ||
| 360 | { AV_CPU_FLAG_SSE3SLOW, 1 + 64 }, | ||
| 361 | { AV_CPU_FLAG_SSSE3SLOW, 1 + 64 }, | ||
| 362 | { AV_CPU_FLAG_ATOM, 1 + 128 }, | ||
| 363 | { AV_CPU_FLAG_AVXSLOW, 1 + 128 }, | ||
| 364 | { AV_CPU_FLAG_SLOW_GATHER, 1 + 32 }, | ||
| 365 | }; | ||
| 366 | |||
| 367 | 35396 | static int get_codelet_prio(const FFTXCodelet *cd, int cpu_flags, int len) | |
| 368 | { | ||
| 369 | 35396 | int prio = cd->prio; | |
| 370 | 35396 | int max_factor = 0; | |
| 371 | |||
| 372 | /* If the CPU has a SLOW flag, and the instruction is also flagged | ||
| 373 | * as being slow for such, reduce its priority */ | ||
| 374 |
2/2✓ Branch 0 taken 212376 times.
✓ Branch 1 taken 35396 times.
|
247772 | for (int i = 0; i < FF_ARRAY_ELEMS(cpu_slow_penalties); i++) { |
| 375 |
2/2✓ Branch 0 taken 2214 times.
✓ Branch 1 taken 210162 times.
|
212376 | if ((cpu_flags & cd->cpu_flags) & cpu_slow_penalties[i][0]) |
| 376 | 2214 | prio -= cpu_slow_penalties[i][1]; | |
| 377 | } | ||
| 378 | |||
| 379 | /* Prioritize aligned-only codelets */ | ||
| 380 |
4/4✓ Branch 0 taken 4932 times.
✓ Branch 1 taken 30464 times.
✓ Branch 2 taken 4918 times.
✓ Branch 3 taken 14 times.
|
35396 | if ((cd->flags & FF_TX_ALIGNED) && !(cd->flags & AV_TX_UNALIGNED)) |
| 381 | 4918 | prio += 64; | |
| 382 | |||
| 383 | /* Codelets for specific lengths are generally faster */ | ||
| 384 |
4/4✓ Branch 0 taken 8136 times.
✓ Branch 1 taken 27260 times.
✓ Branch 2 taken 7429 times.
✓ Branch 3 taken 707 times.
|
35396 | if ((len == cd->min_len) && (len == cd->max_len)) |
| 385 | 7429 | prio += 64; | |
| 386 | |||
| 387 | /* Forward-only or inverse-only transforms are generally better */ | ||
| 388 |
2/2✓ Branch 0 taken 19131 times.
✓ Branch 1 taken 16265 times.
|
35396 | if ((cd->flags & (FF_TX_FORWARD_ONLY | FF_TX_INVERSE_ONLY))) |
| 389 | 19131 | prio += 64; | |
| 390 | |||
| 391 | /* Larger factors are generally better */ | ||
| 392 |
2/2✓ Branch 0 taken 141584 times.
✓ Branch 1 taken 35396 times.
|
176980 | for (int i = 0; i < TX_MAX_SUB; i++) |
| 393 | 141584 | max_factor = FFMAX(cd->factors[i], max_factor); | |
| 394 |
2/2✓ Branch 0 taken 33510 times.
✓ Branch 1 taken 1886 times.
|
35396 | if (max_factor) |
| 395 | 33510 | prio += 16*max_factor; | |
| 396 | |||
| 397 | 35396 | return prio; | |
| 398 | } | ||
| 399 | |||
| 400 | typedef struct FFTXLenDecomp { | ||
| 401 | int len; | ||
| 402 | int len2; | ||
| 403 | int prio; | ||
| 404 | const FFTXCodelet *cd; | ||
| 405 | } FFTXLenDecomp; | ||
| 406 | |||
| 407 | 475 | static int cmp_decomp(FFTXLenDecomp *a, FFTXLenDecomp *b) | |
| 408 | { | ||
| 409 | 475 | return FFDIFFSIGN(b->prio, a->prio); | |
| 410 | } | ||
| 411 | |||
| 412 | 4701 | int ff_tx_decompose_length(int dst[TX_MAX_DECOMPOSITIONS], enum AVTXType type, | |
| 413 | int len, int inv) | ||
| 414 | { | ||
| 415 | 4701 | int nb_decomp = 0; | |
| 416 | FFTXLenDecomp ld[TX_MAX_DECOMPOSITIONS]; | ||
| 417 | 4701 | int codelet_list_idx = codelet_list_num; | |
| 418 | |||
| 419 | 4701 | const int cpu_flags = av_get_cpu_flags(); | |
| 420 | |||
| 421 | /* Loop through all codelets in all codelet lists to find matches | ||
| 422 | * to the requirements */ | ||
| 423 |
2/2✓ Branch 0 taken 23505 times.
✓ Branch 1 taken 4701 times.
|
28206 | while (codelet_list_idx--) { |
| 424 | 23505 | const FFTXCodelet * const * list = codelet_list[codelet_list_idx]; | |
| 425 | 23505 | const FFTXCodelet *cd = NULL; | |
| 426 | |||
| 427 |
2/2✓ Branch 0 taken 1015416 times.
✓ Branch 1 taken 23505 times.
|
1038921 | while ((cd = *list++)) { |
| 428 | 1015416 | int fl = len; | |
| 429 | 1015416 | int skip = 0, prio; | |
| 430 | 1015416 | int factors_product = 1, factors_mod = 0; | |
| 431 | |||
| 432 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1015416 times.
|
1015416 | if (nb_decomp >= TX_MAX_DECOMPOSITIONS) |
| 433 | ✗ | goto sort; | |
| 434 | |||
| 435 | /* Check if the type matches */ | ||
| 436 |
4/4✓ Branch 0 taken 1010715 times.
✓ Branch 1 taken 4701 times.
✓ Branch 2 taken 687742 times.
✓ Branch 3 taken 322973 times.
|
1015416 | if (cd->type != TX_TYPE_ANY && type != cd->type) |
| 437 | 687742 | continue; | |
| 438 | |||
| 439 | /* Check direction for non-orthogonal codelets */ | ||
| 440 |
4/4✓ Branch 0 taken 23000 times.
✓ Branch 1 taken 304674 times.
✓ Branch 2 taken 3976 times.
✓ Branch 3 taken 19024 times.
|
327674 | if (((cd->flags & FF_TX_FORWARD_ONLY) && inv) || |
| 441 |
4/4✓ Branch 0 taken 8392 times.
✓ Branch 1 taken 300258 times.
✓ Branch 2 taken 7256 times.
✓ Branch 3 taken 1136 times.
|
308650 | ((cd->flags & (FF_TX_INVERSE_ONLY | AV_TX_FULL_IMDCT)) && !inv) || |
| 442 |
3/4✓ Branch 0 taken 3976 times.
✓ Branch 1 taken 303538 times.
✓ Branch 2 taken 3976 times.
✗ Branch 3 not taken.
|
307514 | ((cd->flags & (FF_TX_FORWARD_ONLY | AV_TX_REAL_TO_REAL)) && inv) || |
| 443 |
3/4✓ Branch 0 taken 3976 times.
✓ Branch 1 taken 303538 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3976 times.
|
307514 | ((cd->flags & (FF_TX_FORWARD_ONLY | AV_TX_REAL_TO_IMAGINARY)) && inv)) |
| 444 | 20160 | continue; | |
| 445 | |||
| 446 | /* Check if the CPU supports the required ISA */ | ||
| 447 |
2/2✓ Branch 0 taken 163076 times.
✓ Branch 1 taken 144438 times.
|
307514 | if (cd->cpu_flags != FF_TX_CPU_FLAGS_ALL && |
| 448 |
2/2✓ Branch 0 taken 161668 times.
✓ Branch 1 taken 1408 times.
|
163076 | !(cpu_flags & (cd->cpu_flags & ~cpu_slow_mask))) |
| 449 | 161668 | continue; | |
| 450 | |||
| 451 |
1/2✓ Branch 0 taken 319898 times.
✗ Branch 1 not taken.
|
319898 | for (int i = 0; i < TX_MAX_FACTORS; i++) { |
| 452 |
4/4✓ Branch 0 taken 183438 times.
✓ Branch 1 taken 136460 times.
✓ Branch 2 taken 174052 times.
✓ Branch 3 taken 9386 times.
|
319898 | if (!cd->factors[i] || (fl == 1)) |
| 453 | break; | ||
| 454 | |||
| 455 |
2/2✓ Branch 0 taken 28222 times.
✓ Branch 1 taken 145830 times.
|
174052 | if (cd->factors[i] == TX_FACTOR_ANY) { |
| 456 | 28222 | factors_mod++; | |
| 457 | 28222 | factors_product *= fl; | |
| 458 |
2/2✓ Branch 0 taken 91264 times.
✓ Branch 1 taken 54566 times.
|
145830 | } else if (!(fl % cd->factors[i])) { |
| 459 | 91264 | factors_mod++; | |
| 460 |
2/2✓ Branch 0 taken 90423 times.
✓ Branch 1 taken 841 times.
|
91264 | if (cd->factors[i] == 2) { |
| 461 | 90423 | int b = ff_ctz(fl); | |
| 462 | 90423 | fl >>= b; | |
| 463 | 90423 | factors_product <<= b; | |
| 464 | } else { | ||
| 465 | do { | ||
| 466 | 873 | fl /= cd->factors[i]; | |
| 467 | 873 | factors_product *= cd->factors[i]; | |
| 468 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 841 times.
|
873 | } while (!(fl % cd->factors[i])); |
| 469 | } | ||
| 470 | } | ||
| 471 | } | ||
| 472 | |||
| 473 | /* Disqualify if factor requirements are not satisfied or if trivial */ | ||
| 474 |
4/4✓ Branch 0 taken 109922 times.
✓ Branch 1 taken 35924 times.
✓ Branch 2 taken 107752 times.
✓ Branch 3 taken 2170 times.
|
145846 | if ((factors_mod < cd->nb_factors) || (len == factors_product)) |
| 475 | 143676 | continue; | |
| 476 | |||
| 477 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2170 times.
|
2170 | if (av_gcd(factors_product, fl) != 1) |
| 478 | ✗ | continue; | |
| 479 | |||
| 480 | /* Check if length is supported and factorization was successful */ | ||
| 481 |
2/2✓ Branch 0 taken 1198 times.
✓ Branch 1 taken 972 times.
|
2170 | if ((factors_product < cd->min_len) || |
| 482 |
3/4✓ Branch 0 taken 1198 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 616 times.
✓ Branch 3 taken 582 times.
|
1198 | (cd->max_len != TX_LEN_UNLIMITED && (factors_product > cd->max_len))) |
| 483 | 1588 | continue; | |
| 484 | |||
| 485 | 582 | prio = get_codelet_prio(cd, cpu_flags, factors_product) * factors_product; | |
| 486 | |||
| 487 | /* Check for duplicates */ | ||
| 488 |
2/2✓ Branch 0 taken 979 times.
✓ Branch 1 taken 348 times.
|
1327 | for (int i = 0; i < nb_decomp; i++) { |
| 489 |
2/2✓ Branch 0 taken 234 times.
✓ Branch 1 taken 745 times.
|
979 | if (factors_product == ld[i].len) { |
| 490 | /* Update priority if new one is higher */ | ||
| 491 |
2/2✓ Branch 0 taken 204 times.
✓ Branch 1 taken 30 times.
|
234 | if (prio > ld[i].prio) |
| 492 | 204 | ld[i].prio = prio; | |
| 493 | 234 | skip = 1; | |
| 494 | 234 | break; | |
| 495 | } | ||
| 496 | } | ||
| 497 | |||
| 498 | /* Add decomposition if unique */ | ||
| 499 |
2/2✓ Branch 0 taken 348 times.
✓ Branch 1 taken 234 times.
|
582 | if (!skip) { |
| 500 | 348 | ld[nb_decomp].cd = cd; | |
| 501 | 348 | ld[nb_decomp].len = factors_product; | |
| 502 | 348 | ld[nb_decomp].len2 = fl; | |
| 503 | 348 | ld[nb_decomp].prio = prio; | |
| 504 | 348 | nb_decomp++; | |
| 505 | } | ||
| 506 | } | ||
| 507 | } | ||
| 508 | |||
| 509 |
2/2✓ Branch 0 taken 4604 times.
✓ Branch 1 taken 97 times.
|
4701 | if (!nb_decomp) |
| 510 | 4604 | return AVERROR(EINVAL); | |
| 511 | |||
| 512 | 97 | sort: | |
| 513 |
27/44✓ Branch 0 taken 81 times.
✓ Branch 1 taken 89 times.
✓ Branch 3 taken 27 times.
✓ Branch 4 taken 54 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 27 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 54 times.
✓ Branch 12 taken 81 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 81 times.
✓ Branch 16 taken 81 times.
✓ Branch 17 taken 19 times.
✓ Branch 19 taken 19 times.
✓ Branch 20 taken 62 times.
✓ Branch 21 taken 62 times.
✓ Branch 22 taken 81 times.
✓ Branch 24 taken 62 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 81 times.
✓ Branch 28 taken 81 times.
✓ Branch 29 taken 81 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 81 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✓ Branch 43 taken 19 times.
✓ Branch 44 taken 62 times.
✓ Branch 46 taken 8 times.
✓ Branch 47 taken 81 times.
✓ Branch 48 taken 170 times.
✓ Branch 49 taken 89 times.
✓ Branch 50 taken 178 times.
✓ Branch 51 taken 97 times.
|
599 | AV_QSORT(ld, nb_decomp, FFTXLenDecomp, cmp_decomp); |
| 514 | |||
| 515 |
2/2✓ Branch 0 taken 348 times.
✓ Branch 1 taken 97 times.
|
445 | for (int i = 0; i < nb_decomp; i++) { |
| 516 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 348 times.
|
348 | if (ld[i].cd->nb_factors > 1) |
| 517 | ✗ | dst[i] = ld[i].len2; | |
| 518 | else | ||
| 519 | 348 | dst[i] = ld[i].len; | |
| 520 | } | ||
| 521 | |||
| 522 | 97 | return nb_decomp; | |
| 523 | } | ||
| 524 | |||
| 525 | 24 | int ff_tx_gen_default_map(AVTXContext *s, FFTXCodeletOptions *opts) | |
| 526 | { | ||
| 527 | 24 | s->map = av_malloc(s->len*sizeof(*s->map)); | |
| 528 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | if (!s->map) |
| 529 | ✗ | return AVERROR(ENOMEM); | |
| 530 | |||
| 531 | 24 | s->map[0] = 0; /* DC is always at the start */ | |
| 532 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | if (s->inv) /* Reversing the ACs flips the transform direction */ |
| 533 | ✗ | for (int i = 1; i < s->len; i++) | |
| 534 | ✗ | s->map[i] = s->len - i; | |
| 535 | else | ||
| 536 |
2/2✓ Branch 0 taken 144 times.
✓ Branch 1 taken 24 times.
|
168 | for (int i = 1; i < s->len; i++) |
| 537 | 144 | s->map[i] = i; | |
| 538 | |||
| 539 | 24 | s->map_dir = FF_TX_MAP_GATHER; | |
| 540 | |||
| 541 | 24 | return 0; | |
| 542 | } | ||
| 543 | |||
| 544 | #if !CONFIG_SMALL | ||
| 545 | 61540 | static void print_flags(AVBPrint *bp, uint64_t f) | |
| 546 | { | ||
| 547 | 61540 | int prev = 0; | |
| 548 | 61540 | const char *sep = ", "; | |
| 549 | 61540 | av_bprintf(bp, "flags: ["); | |
| 550 |
3/4✓ Branch 0 taken 21371 times.
✓ Branch 1 taken 40169 times.
✓ Branch 2 taken 21371 times.
✗ Branch 3 not taken.
|
61540 | if ((f & FF_TX_ALIGNED) && ++prev) |
| 551 | 21371 | av_bprintf(bp, "aligned"); | |
| 552 |
3/4✓ Branch 0 taken 40197 times.
✓ Branch 1 taken 21343 times.
✓ Branch 2 taken 40197 times.
✗ Branch 3 not taken.
|
61540 | if ((f & AV_TX_UNALIGNED) && ++prev) |
| 553 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 40169 times.
|
40197 | av_bprintf(bp, "%sunaligned", prev > 1 ? sep : ""); |
| 554 |
3/4✓ Branch 0 taken 28826 times.
✓ Branch 1 taken 32714 times.
✓ Branch 2 taken 28826 times.
✗ Branch 3 not taken.
|
61540 | if ((f & AV_TX_INPLACE) && ++prev) |
| 555 |
1/2✓ Branch 0 taken 28826 times.
✗ Branch 1 not taken.
|
28826 | av_bprintf(bp, "%sinplace", prev > 1 ? sep : ""); |
| 556 |
3/4✓ Branch 0 taken 54650 times.
✓ Branch 1 taken 6890 times.
✓ Branch 2 taken 54650 times.
✗ Branch 3 not taken.
|
61540 | if ((f & FF_TX_OUT_OF_PLACE) && ++prev) |
| 557 |
1/2✓ Branch 0 taken 54650 times.
✗ Branch 1 not taken.
|
54650 | av_bprintf(bp, "%sout_of_place", prev > 1 ? sep : ""); |
| 558 |
3/4✓ Branch 0 taken 1409 times.
✓ Branch 1 taken 60131 times.
✓ Branch 2 taken 1409 times.
✗ Branch 3 not taken.
|
61540 | if ((f & FF_TX_FORWARD_ONLY) && ++prev) |
| 559 |
1/2✓ Branch 0 taken 1409 times.
✗ Branch 1 not taken.
|
1409 | av_bprintf(bp, "%sfwd_only", prev > 1 ? sep : ""); |
| 560 |
3/4✓ Branch 0 taken 23518 times.
✓ Branch 1 taken 38022 times.
✓ Branch 2 taken 23518 times.
✗ Branch 3 not taken.
|
61540 | if ((f & FF_TX_INVERSE_ONLY) && ++prev) |
| 561 |
1/2✓ Branch 0 taken 23518 times.
✗ Branch 1 not taken.
|
23518 | av_bprintf(bp, "%sinv_only", prev > 1 ? sep : ""); |
| 562 |
3/4✓ Branch 0 taken 27258 times.
✓ Branch 1 taken 34282 times.
✓ Branch 2 taken 27258 times.
✗ Branch 3 not taken.
|
61540 | if ((f & FF_TX_PRESHUFFLE) && ++prev) |
| 563 |
1/2✓ Branch 0 taken 27258 times.
✗ Branch 1 not taken.
|
27258 | av_bprintf(bp, "%spreshuf", prev > 1 ? sep : ""); |
| 564 |
3/4✓ Branch 0 taken 276 times.
✓ Branch 1 taken 61264 times.
✓ Branch 2 taken 276 times.
✗ Branch 3 not taken.
|
61540 | if ((f & AV_TX_FULL_IMDCT) && ++prev) |
| 565 |
1/2✓ Branch 0 taken 276 times.
✗ Branch 1 not taken.
|
276 | av_bprintf(bp, "%simdct_full", prev > 1 ? sep : ""); |
| 566 |
3/4✓ Branch 0 taken 24 times.
✓ Branch 1 taken 61516 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
61540 | if ((f & AV_TX_REAL_TO_REAL) && ++prev) |
| 567 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 | av_bprintf(bp, "%sreal_to_real", prev > 1 ? sep : ""); |
| 568 |
3/4✓ Branch 0 taken 24 times.
✓ Branch 1 taken 61516 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
61540 | if ((f & AV_TX_REAL_TO_IMAGINARY) && ++prev) |
| 569 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 | av_bprintf(bp, "%sreal_to_imaginary", prev > 1 ? sep : ""); |
| 570 |
3/4✓ Branch 0 taken 6212 times.
✓ Branch 1 taken 55328 times.
✓ Branch 2 taken 6212 times.
✗ Branch 3 not taken.
|
61540 | if ((f & FF_TX_ASM_CALL) && ++prev) |
| 571 |
1/2✓ Branch 0 taken 6212 times.
✗ Branch 1 not taken.
|
6212 | av_bprintf(bp, "%sasm_call", prev > 1 ? sep : ""); |
| 572 | 61540 | av_bprintf(bp, "]"); | |
| 573 | 61540 | } | |
| 574 | |||
| 575 | 61540 | static void print_type(AVBPrint *bp, enum AVTXType type) | |
| 576 | { | ||
| 577 |
2/2✓ Branch 0 taken 61512 times.
✓ Branch 1 taken 28 times.
|
123052 | av_bprintf(bp, "%s", |
| 578 | type == TX_TYPE_ANY ? "any" : | ||
| 579 |
2/2✓ Branch 0 taken 34210 times.
✓ Branch 1 taken 27302 times.
|
95722 | type == AV_TX_FLOAT_FFT ? "fft_float" : |
| 580 |
2/2✓ Branch 0 taken 4571 times.
✓ Branch 1 taken 29639 times.
|
38781 | type == AV_TX_FLOAT_MDCT ? "mdct_float" : |
| 581 |
2/2✓ Branch 0 taken 4394 times.
✓ Branch 1 taken 177 times.
|
8965 | type == AV_TX_FLOAT_RDFT ? "rdft_float" : |
| 582 |
2/2✓ Branch 0 taken 4370 times.
✓ Branch 1 taken 24 times.
|
8764 | type == AV_TX_FLOAT_DCT_I ? "dctI_float" : |
| 583 |
2/2✓ Branch 0 taken 4346 times.
✓ Branch 1 taken 24 times.
|
8716 | type == AV_TX_FLOAT_DST_I ? "dstI_float" : |
| 584 |
2/2✓ Branch 0 taken 2414 times.
✓ Branch 1 taken 1932 times.
|
6760 | type == AV_TX_DOUBLE_FFT ? "fft_double" : |
| 585 |
1/2✓ Branch 0 taken 2414 times.
✗ Branch 1 not taken.
|
4828 | type == AV_TX_DOUBLE_MDCT ? "mdct_double" : |
| 586 |
1/2✓ Branch 0 taken 2414 times.
✗ Branch 1 not taken.
|
4828 | type == AV_TX_DOUBLE_RDFT ? "rdft_double" : |
| 587 |
1/2✓ Branch 0 taken 2414 times.
✗ Branch 1 not taken.
|
4828 | type == AV_TX_DOUBLE_DCT_I ? "dctI_double" : |
| 588 |
1/2✓ Branch 0 taken 2414 times.
✗ Branch 1 not taken.
|
4828 | type == AV_TX_DOUBLE_DST_I ? "dstI_double" : |
| 589 |
2/2✓ Branch 0 taken 1339 times.
✓ Branch 1 taken 1075 times.
|
3753 | type == AV_TX_INT32_FFT ? "fft_int32" : |
| 590 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1327 times.
|
1351 | type == AV_TX_INT32_MDCT ? "mdct_int32" : |
| 591 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
24 | type == AV_TX_INT32_RDFT ? "rdft_int32" : |
| 592 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
24 | type == AV_TX_INT32_DCT_I ? "dctI_int32" : |
| 593 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | type == AV_TX_INT32_DST_I ? "dstI_int32" : |
| 594 | "unknown"); | ||
| 595 | 61540 | } | |
| 596 | |||
| 597 | 48084 | static void print_cd_info(const FFTXCodelet *cd, int prio, int len, int print_prio, | |
| 598 | int log_level) | ||
| 599 | { | ||
| 600 | AVBPrint bp; | ||
| 601 | 48084 | av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); | |
| 602 | |||
| 603 | 48084 | av_bprintf(&bp, "%s - type: ", cd->name); | |
| 604 | |||
| 605 | 48084 | print_type(&bp, cd->type); | |
| 606 | |||
| 607 | 48084 | av_bprintf(&bp, ", len: "); | |
| 608 |
2/2✓ Branch 0 taken 34814 times.
✓ Branch 1 taken 13270 times.
|
48084 | if (!len) { |
| 609 |
2/2✓ Branch 0 taken 27949 times.
✓ Branch 1 taken 6865 times.
|
34814 | if (cd->min_len != cd->max_len) |
| 610 | 27949 | av_bprintf(&bp, "[%i, ", cd->min_len); | |
| 611 | |||
| 612 |
2/2✓ Branch 0 taken 25738 times.
✓ Branch 1 taken 9076 times.
|
34814 | if (cd->max_len == TX_LEN_UNLIMITED) |
| 613 | 25738 | av_bprintf(&bp, "∞"); | |
| 614 | else | ||
| 615 | 9076 | av_bprintf(&bp, "%i", cd->max_len); | |
| 616 | } else { | ||
| 617 | 13270 | av_bprintf(&bp, "%i", len); | |
| 618 | } | ||
| 619 | |||
| 620 |
2/2✓ Branch 0 taken 31216 times.
✓ Branch 1 taken 16868 times.
|
48084 | if (cd->factors[1]) { |
| 621 |
3/4✓ Branch 0 taken 24571 times.
✓ Branch 1 taken 6645 times.
✓ Branch 2 taken 24571 times.
✗ Branch 3 not taken.
|
31216 | av_bprintf(&bp, "%s, factors", !len && cd->min_len != cd->max_len ? "]" : ""); |
| 622 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 31208 times.
|
31216 | if (!cd->nb_factors) |
| 623 | 8 | av_bprintf(&bp, ": ["); | |
| 624 | else | ||
| 625 | 31208 | av_bprintf(&bp, "[%i]: [", cd->nb_factors); | |
| 626 | |||
| 627 |
1/2✓ Branch 0 taken 109119 times.
✗ Branch 1 not taken.
|
109119 | for (int i = 0; i < TX_MAX_FACTORS; i++) { |
| 628 |
4/4✓ Branch 0 taken 77903 times.
✓ Branch 1 taken 31216 times.
✓ Branch 2 taken 46687 times.
✓ Branch 3 taken 31216 times.
|
109119 | if (i && cd->factors[i]) |
| 629 | 46687 | av_bprintf(&bp, ", "); | |
| 630 |
2/2✓ Branch 0 taken 30280 times.
✓ Branch 1 taken 78839 times.
|
109119 | if (cd->factors[i] == TX_FACTOR_ANY) |
| 631 | 30280 | av_bprintf(&bp, "any"); | |
| 632 |
2/2✓ Branch 0 taken 47623 times.
✓ Branch 1 taken 31216 times.
|
78839 | else if (cd->factors[i]) |
| 633 | 47623 | av_bprintf(&bp, "%i", cd->factors[i]); | |
| 634 | else | ||
| 635 | 31216 | break; | |
| 636 | } | ||
| 637 | |||
| 638 | 31216 | av_bprintf(&bp, "], "); | |
| 639 | } else { | ||
| 640 | 16868 | av_bprintf(&bp, "%s, factor: %i, ", | |
| 641 |
4/4✓ Branch 0 taken 10243 times.
✓ Branch 1 taken 6625 times.
✓ Branch 2 taken 3378 times.
✓ Branch 3 taken 6865 times.
|
16868 | !len && cd->min_len != cd->max_len ? "]" : "", cd->factors[0]); |
| 642 | } | ||
| 643 | 48084 | print_flags(&bp, cd->flags); | |
| 644 | |||
| 645 |
2/2✓ Branch 0 taken 34814 times.
✓ Branch 1 taken 13270 times.
|
48084 | if (print_prio) |
| 646 | 34814 | av_bprintf(&bp, ", prio: %i", prio); | |
| 647 | |||
| 648 | 48084 | av_log(NULL, log_level, "%s\n", bp.str); | |
| 649 | 48084 | } | |
| 650 | |||
| 651 | 13270 | static void print_tx_structure(AVTXContext *s, int depth) | |
| 652 | { | ||
| 653 | 13270 | const FFTXCodelet *cd = s->cd_self; | |
| 654 | |||
| 655 |
2/2✓ Branch 0 taken 20938 times.
✓ Branch 1 taken 13270 times.
|
34208 | for (int i = 0; i <= depth; i++) |
| 656 | 20938 | av_log(NULL, AV_LOG_DEBUG, " "); | |
| 657 | |||
| 658 | 13270 | print_cd_info(cd, cd->prio, s->len, 0, AV_LOG_DEBUG); | |
| 659 | |||
| 660 |
2/2✓ Branch 0 taken 6980 times.
✓ Branch 1 taken 13270 times.
|
20250 | for (int i = 0; i < s->nb_sub; i++) |
| 661 | 6980 | print_tx_structure(&s->sub[i], depth + 1); | |
| 662 | 13270 | } | |
| 663 | #endif /* CONFIG_SMALL */ | ||
| 664 | |||
| 665 | typedef struct TXCodeletMatch { | ||
| 666 | const FFTXCodelet *cd; | ||
| 667 | int prio; | ||
| 668 | } TXCodeletMatch; | ||
| 669 | |||
| 670 | 35268 | static int cmp_matches(TXCodeletMatch *a, TXCodeletMatch *b) | |
| 671 | { | ||
| 672 | 35268 | return FFDIFFSIGN(b->prio, a->prio); | |
| 673 | } | ||
| 674 | |||
| 675 | /* We want all factors to completely cover the length */ | ||
| 676 | 60146 | static inline int check_cd_factors(const FFTXCodelet *cd, int len) | |
| 677 | { | ||
| 678 | 60146 | int matches = 0, any_flag = 0; | |
| 679 | |||
| 680 |
1/2✓ Branch 0 taken 184096 times.
✗ Branch 1 not taken.
|
184096 | for (int i = 0; i < TX_MAX_FACTORS; i++) { |
| 681 | 184096 | int factor = cd->factors[i]; | |
| 682 | |||
| 683 |
2/2✓ Branch 0 taken 49431 times.
✓ Branch 1 taken 134665 times.
|
184096 | if (factor == TX_FACTOR_ANY) { |
| 684 | 49431 | any_flag = 1; | |
| 685 | 49431 | matches++; | |
| 686 | 49431 | continue; | |
| 687 |
4/4✓ Branch 0 taken 112510 times.
✓ Branch 1 taken 22155 times.
✓ Branch 2 taken 74519 times.
✓ Branch 3 taken 37991 times.
|
134665 | } else if (len <= 1 || !factor) { |
| 688 | break; | ||
| 689 |
2/2✓ Branch 0 taken 28714 times.
✓ Branch 1 taken 45805 times.
|
74519 | } else if (factor == 2) { /* Fast path */ |
| 690 | 28714 | int bits_2 = ff_ctz(len); | |
| 691 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 28666 times.
|
28714 | if (!bits_2) |
| 692 | 48 | continue; /* Factor not supported */ | |
| 693 | |||
| 694 | 28666 | len >>= bits_2; | |
| 695 | 28666 | matches++; | |
| 696 | } else { | ||
| 697 | 45805 | int res = len % factor; | |
| 698 |
2/2✓ Branch 0 taken 39017 times.
✓ Branch 1 taken 6788 times.
|
45805 | if (res) |
| 699 | 39017 | continue; /* Factor not supported */ | |
| 700 | |||
| 701 |
2/2✓ Branch 0 taken 6962 times.
✓ Branch 1 taken 6788 times.
|
13750 | while (!res) { |
| 702 | 6962 | len /= factor; | |
| 703 | 6962 | res = len % factor; | |
| 704 | } | ||
| 705 | 6788 | matches++; | |
| 706 | } | ||
| 707 | } | ||
| 708 | |||
| 709 |
6/6✓ Branch 0 taken 36035 times.
✓ Branch 1 taken 24111 times.
✓ Branch 2 taken 10135 times.
✓ Branch 3 taken 25900 times.
✓ Branch 4 taken 8914 times.
✓ Branch 5 taken 1221 times.
|
60146 | return (cd->nb_factors <= matches) && (any_flag || len == 1); |
| 710 | } | ||
| 711 | |||
| 712 | 13456 | av_cold int ff_tx_init_subtx(AVTXContext *s, enum AVTXType type, | |
| 713 | uint64_t flags, FFTXCodeletOptions *opts, | ||
| 714 | int len, int inv, const void *scale) | ||
| 715 | { | ||
| 716 | 13456 | int ret = 0; | |
| 717 | 13456 | AVTXContext *sub = NULL; | |
| 718 | 13456 | TXCodeletMatch *cd_tmp, *cd_matches = NULL; | |
| 719 | 13456 | unsigned int cd_matches_size = 0; | |
| 720 | 13456 | int codelet_list_idx = codelet_list_num; | |
| 721 | 13456 | int nb_cd_matches = 0; | |
| 722 | #if !CONFIG_SMALL | ||
| 723 | AVBPrint bp; | ||
| 724 | #endif | ||
| 725 | |||
| 726 | /* We still accept functions marked with SLOW, even if the CPU is | ||
| 727 | * marked with the same flag, but we give them lower priority. */ | ||
| 728 | 13456 | const int cpu_flags = av_get_cpu_flags(); | |
| 729 | |||
| 730 | /* Flags the transform wants */ | ||
| 731 | 13456 | uint64_t req_flags = flags; | |
| 732 | |||
| 733 | /* Flags the codelet may require to be present */ | ||
| 734 | 13456 | uint64_t inv_req_mask = AV_TX_FULL_IMDCT | | |
| 735 | AV_TX_REAL_TO_REAL | | ||
| 736 | AV_TX_REAL_TO_IMAGINARY | | ||
| 737 | FF_TX_PRESHUFFLE | | ||
| 738 | FF_TX_ASM_CALL; | ||
| 739 | |||
| 740 | /* Unaligned codelets are compatible with the aligned flag */ | ||
| 741 |
1/2✓ Branch 0 taken 13456 times.
✗ Branch 1 not taken.
|
13456 | if (req_flags & FF_TX_ALIGNED) |
| 742 | 13456 | req_flags |= AV_TX_UNALIGNED; | |
| 743 | |||
| 744 | /* If either flag is set, both are okay, so don't check for an exact match */ | ||
| 745 |
3/4✓ Branch 0 taken 6890 times.
✓ Branch 1 taken 6566 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6890 times.
|
13456 | if ((req_flags & AV_TX_INPLACE) && (req_flags & FF_TX_OUT_OF_PLACE)) |
| 746 | ✗ | req_flags &= ~(AV_TX_INPLACE | FF_TX_OUT_OF_PLACE); | |
| 747 |
2/4✓ Branch 0 taken 13456 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13456 times.
✗ Branch 3 not taken.
|
13456 | if ((req_flags & FF_TX_ALIGNED) && (req_flags & AV_TX_UNALIGNED)) |
| 748 | 13456 | req_flags &= ~(FF_TX_ALIGNED | AV_TX_UNALIGNED); | |
| 749 | |||
| 750 | /* Loop through all codelets in all codelet lists to find matches | ||
| 751 | * to the requirements */ | ||
| 752 |
2/2✓ Branch 0 taken 67280 times.
✓ Branch 1 taken 13456 times.
|
80736 | while (codelet_list_idx--) { |
| 753 | 67280 | const FFTXCodelet * const * list = codelet_list[codelet_list_idx]; | |
| 754 | 67280 | const FFTXCodelet *cd = NULL; | |
| 755 | |||
| 756 |
2/2✓ Branch 0 taken 2906496 times.
✓ Branch 1 taken 67280 times.
|
2973776 | while ((cd = *list++)) { |
| 757 | /* Check if the type matches */ | ||
| 758 |
4/4✓ Branch 0 taken 2893040 times.
✓ Branch 1 taken 13456 times.
✓ Branch 2 taken 2283432 times.
✓ Branch 3 taken 609608 times.
|
2906496 | if (cd->type != TX_TYPE_ANY && type != cd->type) |
| 759 | 2283432 | continue; | |
| 760 | |||
| 761 | /* Check direction for non-orthogonal codelets */ | ||
| 762 |
4/4✓ Branch 0 taken 78562 times.
✓ Branch 1 taken 544502 times.
✓ Branch 2 taken 8878 times.
✓ Branch 3 taken 69684 times.
|
623064 | if (((cd->flags & FF_TX_FORWARD_ONLY) && inv) || |
| 763 |
4/4✓ Branch 0 taken 67302 times.
✓ Branch 1 taken 486078 times.
✓ Branch 2 taken 61727 times.
✓ Branch 3 taken 5575 times.
|
553380 | ((cd->flags & (FF_TX_INVERSE_ONLY | AV_TX_FULL_IMDCT)) && !inv) || |
| 764 |
3/4✓ Branch 0 taken 8878 times.
✓ Branch 1 taken 538927 times.
✓ Branch 2 taken 8878 times.
✗ Branch 3 not taken.
|
547805 | ((cd->flags & (FF_TX_FORWARD_ONLY | AV_TX_REAL_TO_REAL)) && inv) || |
| 765 |
3/4✓ Branch 0 taken 8878 times.
✓ Branch 1 taken 538927 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8878 times.
|
547805 | ((cd->flags & (FF_TX_FORWARD_ONLY | AV_TX_REAL_TO_IMAGINARY)) && inv)) |
| 766 | 75259 | continue; | |
| 767 | |||
| 768 | /* Check if the requested flags match from both sides */ | ||
| 769 |
2/2✓ Branch 0 taken 342251 times.
✓ Branch 1 taken 205554 times.
|
547805 | if (((req_flags & cd->flags) != (req_flags)) || |
| 770 |
2/2✓ Branch 0 taken 78469 times.
✓ Branch 1 taken 263782 times.
|
342251 | ((inv_req_mask & cd->flags) != (req_flags & inv_req_mask))) |
| 771 | 284023 | continue; | |
| 772 | |||
| 773 | /* Check if length is supported */ | ||
| 774 |
6/6✓ Branch 0 taken 178451 times.
✓ Branch 1 taken 85331 times.
✓ Branch 2 taken 122552 times.
✓ Branch 3 taken 55899 times.
✓ Branch 4 taken 101328 times.
✓ Branch 5 taken 21224 times.
|
263782 | if ((len < cd->min_len) || (cd->max_len != -1 && (len > cd->max_len))) |
| 775 | 186659 | continue; | |
| 776 | |||
| 777 | /* Check if the CPU supports the required ISA */ | ||
| 778 |
2/2✓ Branch 0 taken 23632 times.
✓ Branch 1 taken 53491 times.
|
77123 | if (cd->cpu_flags != FF_TX_CPU_FLAGS_ALL && |
| 779 |
2/2✓ Branch 0 taken 16977 times.
✓ Branch 1 taken 6655 times.
|
23632 | !(cpu_flags & (cd->cpu_flags & ~cpu_slow_mask))) |
| 780 | 16977 | continue; | |
| 781 | |||
| 782 | /* Check for factors */ | ||
| 783 |
2/2✓ Branch 1 taken 25332 times.
✓ Branch 2 taken 34814 times.
|
60146 | if (!check_cd_factors(cd, len)) |
| 784 | 25332 | continue; | |
| 785 | |||
| 786 | /* Realloc array and append */ | ||
| 787 | 34814 | cd_tmp = av_fast_realloc(cd_matches, &cd_matches_size, | |
| 788 | 34814 | sizeof(*cd_tmp) * (nb_cd_matches + 1)); | |
| 789 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34814 times.
|
34814 | if (!cd_tmp) { |
| 790 | ✗ | av_free(cd_matches); | |
| 791 | ✗ | return AVERROR(ENOMEM); | |
| 792 | } | ||
| 793 | |||
| 794 | 34814 | cd_matches = cd_tmp; | |
| 795 | 34814 | cd_matches[nb_cd_matches].cd = cd; | |
| 796 | 34814 | cd_matches[nb_cd_matches].prio = get_codelet_prio(cd, cpu_flags, len); | |
| 797 | 34814 | nb_cd_matches++; | |
| 798 | } | ||
| 799 | } | ||
| 800 | |||
| 801 | #if !CONFIG_SMALL | ||
| 802 | /* Print debugging info */ | ||
| 803 | 13456 | av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); | |
| 804 |
2/2✓ Branch 0 taken 11762 times.
✓ Branch 1 taken 1694 times.
|
13456 | av_bprintf(&bp, "For transform of length %i, %s, ", len, |
| 805 | inv ? "inverse" : "forward"); | ||
| 806 | 13456 | print_type(&bp, type); | |
| 807 | 13456 | av_bprintf(&bp, ", "); | |
| 808 | 13456 | print_flags(&bp, flags); | |
| 809 |
2/2✓ Branch 0 taken 13270 times.
✓ Branch 1 taken 186 times.
|
13456 | av_bprintf(&bp, ", found %i matches%s", nb_cd_matches, |
| 810 | nb_cd_matches ? ":" : "."); | ||
| 811 | #endif | ||
| 812 | |||
| 813 | /* No matches found */ | ||
| 814 |
2/2✓ Branch 0 taken 186 times.
✓ Branch 1 taken 13270 times.
|
13456 | if (!nb_cd_matches) |
| 815 | 186 | return AVERROR(ENOSYS); | |
| 816 | |||
| 817 | /* Sort the list */ | ||
| 818 |
44/44✓ Branch 0 taken 6093 times.
✓ Branch 1 taken 9216 times.
✓ Branch 3 taken 1623 times.
✓ Branch 4 taken 4470 times.
✓ Branch 6 taken 396 times.
✓ Branch 7 taken 1227 times.
✓ Branch 9 taken 2053 times.
✓ Branch 10 taken 2417 times.
✓ Branch 12 taken 2367 times.
✓ Branch 13 taken 3726 times.
✓ Branch 14 taken 3632 times.
✓ Branch 15 taken 2461 times.
✓ Branch 16 taken 4622 times.
✓ Branch 17 taken 1859 times.
✓ Branch 19 taken 3303 times.
✓ Branch 20 taken 1319 times.
✓ Branch 21 taken 1367 times.
✓ Branch 22 taken 2373 times.
✓ Branch 24 taken 562 times.
✓ Branch 25 taken 805 times.
✓ Branch 26 taken 2373 times.
✓ Branch 27 taken 805 times.
✓ Branch 28 taken 3178 times.
✓ Branch 29 taken 2461 times.
✓ Branch 30 taken 1006 times.
✓ Branch 31 taken 1455 times.
✓ Branch 32 taken 369 times.
✓ Branch 33 taken 637 times.
✓ Branch 34 taken 310 times.
✓ Branch 35 taken 59 times.
✓ Branch 36 taken 1784 times.
✓ Branch 37 taken 142 times.
✓ Branch 39 taken 979 times.
✓ Branch 40 taken 805 times.
✓ Branch 41 taken 142 times.
✓ Branch 42 taken 805 times.
✓ Branch 43 taken 1737 times.
✓ Branch 44 taken 582 times.
✓ Branch 46 taken 5728 times.
✓ Branch 47 taken 3488 times.
✓ Branch 48 taken 15309 times.
✓ Branch 49 taken 2599 times.
✓ Branch 50 taken 15589 times.
✓ Branch 51 taken 13270 times.
|
41661 | AV_QSORT(cd_matches, nb_cd_matches, TXCodeletMatch, cmp_matches); |
| 819 | |||
| 820 | #if !CONFIG_SMALL | ||
| 821 | 13270 | av_log(NULL, AV_LOG_TRACE, "%s\n", bp.str); | |
| 822 | |||
| 823 |
2/2✓ Branch 0 taken 34814 times.
✓ Branch 1 taken 13270 times.
|
48084 | for (int i = 0; i < nb_cd_matches; i++) { |
| 824 | 34814 | av_log(NULL, AV_LOG_TRACE, " %i: ", i + 1); | |
| 825 | 34814 | print_cd_info(cd_matches[i].cd, cd_matches[i].prio, 0, 1, AV_LOG_TRACE); | |
| 826 | } | ||
| 827 | #endif | ||
| 828 | |||
| 829 |
2/2✓ Branch 0 taken 13173 times.
✓ Branch 1 taken 97 times.
|
13270 | if (!s->sub) { |
| 830 | 13173 | s->sub = sub = av_mallocz(TX_MAX_SUB*sizeof(*sub)); | |
| 831 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13173 times.
|
13173 | if (!sub) { |
| 832 | ✗ | ret = AVERROR(ENOMEM); | |
| 833 | ✗ | goto end; | |
| 834 | } | ||
| 835 | } | ||
| 836 | |||
| 837 | /* Attempt to initialize each */ | ||
| 838 |
1/2✓ Branch 0 taken 18038 times.
✗ Branch 1 not taken.
|
18038 | for (int i = 0; i < nb_cd_matches; i++) { |
| 839 | 18038 | const FFTXCodelet *cd = cd_matches[i].cd; | |
| 840 | 18038 | AVTXContext *sctx = &s->sub[s->nb_sub]; | |
| 841 | |||
| 842 | 18038 | sctx->len = len; | |
| 843 | 18038 | sctx->inv = inv; | |
| 844 | 18038 | sctx->type = type; | |
| 845 | 18038 | sctx->flags = cd->flags | flags; | |
| 846 | 18038 | sctx->cd_self = cd; | |
| 847 | |||
| 848 | 18038 | s->fn[s->nb_sub] = cd->function; | |
| 849 | 18038 | s->cd[s->nb_sub] = cd; | |
| 850 | |||
| 851 | 18038 | ret = 0; | |
| 852 |
2/2✓ Branch 0 taken 18019 times.
✓ Branch 1 taken 19 times.
|
18038 | if (cd->init) |
| 853 | 18019 | ret = cd->init(sctx, cd, flags, opts, len, inv, scale); | |
| 854 | |||
| 855 |
2/2✓ Branch 0 taken 13270 times.
✓ Branch 1 taken 4768 times.
|
18038 | if (ret >= 0) { |
| 856 |
3/4✓ Branch 0 taken 6809 times.
✓ Branch 1 taken 6461 times.
✓ Branch 2 taken 6809 times.
✗ Branch 3 not taken.
|
13270 | if (opts && opts->map_dir != FF_TX_MAP_NONE && |
| 857 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 6787 times.
|
6809 | sctx->map_dir == FF_TX_MAP_NONE) { |
| 858 | /* If a specific map direction was requested, and it doesn't | ||
| 859 | * exist, create one.*/ | ||
| 860 | 22 | sctx->map = av_malloc(len*sizeof(*sctx->map)); | |
| 861 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
|
22 | if (!sctx->map) { |
| 862 | ✗ | ret = AVERROR(ENOMEM); | |
| 863 | ✗ | goto end; | |
| 864 | } | ||
| 865 | |||
| 866 |
2/2✓ Branch 0 taken 118 times.
✓ Branch 1 taken 22 times.
|
140 | for (int i = 0; i < len; i++) |
| 867 | 118 | sctx->map[i] = i; | |
| 868 |
4/4✓ Branch 0 taken 6787 times.
✓ Branch 1 taken 6461 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 6771 times.
|
13248 | } else if (opts && (opts->map_dir != sctx->map_dir)) { |
| 869 | 16 | int *tmp = av_malloc(len*sizeof(*sctx->map)); | |
| 870 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | if (!tmp) { |
| 871 | ✗ | ret = AVERROR(ENOMEM); | |
| 872 | ✗ | goto end; | |
| 873 | } | ||
| 874 | |||
| 875 | 16 | memcpy(tmp, sctx->map, len*sizeof(*sctx->map)); | |
| 876 | |||
| 877 |
2/2✓ Branch 0 taken 112 times.
✓ Branch 1 taken 16 times.
|
128 | for (int i = 0; i < len; i++) |
| 878 | 112 | sctx->map[tmp[i]] = i; | |
| 879 | |||
| 880 | 16 | av_free(tmp); | |
| 881 | } | ||
| 882 | |||
| 883 | 13270 | s->nb_sub++; | |
| 884 | 13270 | goto end; | |
| 885 | } | ||
| 886 | |||
| 887 | 4768 | s->fn[s->nb_sub] = NULL; | |
| 888 | 4768 | s->cd[s->nb_sub] = NULL; | |
| 889 | |||
| 890 | 4768 | reset_ctx(sctx, 0); | |
| 891 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4768 times.
|
4768 | if (ret == AVERROR(ENOMEM)) |
| 892 | ✗ | break; | |
| 893 | } | ||
| 894 | |||
| 895 | ✗ | if (!s->nb_sub) | |
| 896 | ✗ | av_freep(&s->sub); | |
| 897 | |||
| 898 | ✗ | end: | |
| 899 | 13270 | av_free(cd_matches); | |
| 900 | 13270 | return ret; | |
| 901 | } | ||
| 902 | |||
| 903 | 6290 | av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, | |
| 904 | int inv, int len, const void *scale, uint64_t flags) | ||
| 905 | { | ||
| 906 | int ret; | ||
| 907 | 6290 | AVTXContext tmp = { 0 }; | |
| 908 | 6290 | const double default_scale_d = 1.0; | |
| 909 | 6290 | const float default_scale_f = 1.0f; | |
| 910 | |||
| 911 |
4/8✓ Branch 0 taken 6290 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6290 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6290 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6290 times.
|
6290 | if (!len || type >= AV_TX_NB || !ctx || !tx) |
| 912 | ✗ | return AVERROR(EINVAL); | |
| 913 | |||
| 914 |
1/2✓ Branch 0 taken 6290 times.
✗ Branch 1 not taken.
|
6290 | if (!(flags & AV_TX_UNALIGNED)) |
| 915 | 6290 | flags |= FF_TX_ALIGNED; | |
| 916 |
1/2✓ Branch 0 taken 6290 times.
✗ Branch 1 not taken.
|
6290 | if (!(flags & AV_TX_INPLACE)) |
| 917 | 6290 | flags |= FF_TX_OUT_OF_PLACE; | |
| 918 | |||
| 919 |
5/8✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6278 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
|
6290 | if (!scale && ((type == AV_TX_DOUBLE_MDCT) || (type == AV_TX_DOUBLE_DCT) || |
| 920 |
2/4✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
|
12 | (type == AV_TX_DOUBLE_DCT_I) || (type == AV_TX_DOUBLE_DST_I) || |
| 921 | (type == AV_TX_DOUBLE_RDFT))) | ||
| 922 | ✗ | scale = &default_scale_d; | |
| 923 |
3/8✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6278 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
6290 | else if (!scale && !TYPE_IS(FFT, type)) |
| 924 | ✗ | scale = &default_scale_f; | |
| 925 | |||
| 926 | 6290 | ret = ff_tx_init_subtx(&tmp, type, flags, NULL, len, inv, scale); | |
| 927 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6290 times.
|
6290 | if (ret < 0) |
| 928 | ✗ | return ret; | |
| 929 | |||
| 930 | 6290 | *ctx = &tmp.sub[0]; | |
| 931 | 6290 | *tx = tmp.fn[0]; | |
| 932 | |||
| 933 | #if !CONFIG_SMALL | ||
| 934 | 6290 | av_log(NULL, AV_LOG_DEBUG, "Transform tree:\n"); | |
| 935 | 6290 | print_tx_structure(*ctx, 0); | |
| 936 | #endif | ||
| 937 | |||
| 938 | 6290 | return ret; | |
| 939 | } | ||
| 940 |