FFmpeg
tx.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
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 "qsort.h"
23 #include "bprint.h"
24 
25 #include "tx_priv.h"
26 
27 #define TYPE_IS(type, x) \
28  (((x) == AV_TX_FLOAT_ ## type) || \
29  ((x) == AV_TX_DOUBLE_ ## type) || \
30  ((x) == AV_TX_INT32_ ## type))
31 
32 /* Calculates the modular multiplicative inverse */
33 static av_always_inline int mulinv(int n, int m)
34 {
35  n = n % m;
36  for (int x = 1; x < m; x++)
37  if (((n * x) % m) == 1)
38  return x;
39  av_assert0(0); /* Never reached */
40  return 0;
41 }
42 
44  int d1, int d2)
45 {
46  const int sl = d1*d2;
47 
48  s->map = av_malloc(s->len*sizeof(*s->map));
49  if (!s->map)
50  return AVERROR(ENOMEM);
51 
52  for (int k = 0; k < s->len; k += sl) {
53  if (s->inv || (opts && opts->map_dir == FF_TX_MAP_SCATTER)) {
54  for (int m = 0; m < d2; m++)
55  for (int n = 0; n < d1; n++)
56  s->map[k + ((m*d1 + n*d2) % (sl))] = m*d1 + n;
57  } else {
58  for (int m = 0; m < d2; m++)
59  for (int n = 0; n < d1; n++)
60  s->map[k + m*d1 + n] = (m*d1 + n*d2) % (sl);
61  }
62 
63  if (s->inv)
64  for (int w = 1; w <= ((sl) >> 1); w++)
65  FFSWAP(int, s->map[k + w], s->map[k + sl - w]);
66  }
67 
68  s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER;
69 
70  return 0;
71 }
72 
73 /* Guaranteed to work for any n, m where gcd(n, m) == 1 */
75  int inv, int n, int m)
76 {
77  int *in_map, *out_map;
78  const int len = n*m; /* Will not be equal to s->len for MDCTs */
79  int m_inv, n_inv;
80 
81  /* Make sure the numbers are coprime */
82  if (av_gcd(n, m) != 1)
83  return AVERROR(EINVAL);
84 
85  m_inv = mulinv(m, n);
86  n_inv = mulinv(n, m);
87 
88  if (!(s->map = av_malloc(2*len*sizeof(*s->map))))
89  return AVERROR(ENOMEM);
90 
91  in_map = s->map;
92  out_map = s->map + len;
93 
94  /* Ruritanian map for input, CRT map for output, can be swapped */
95  if (opts && opts->map_dir == FF_TX_MAP_SCATTER) {
96  for (int j = 0; j < m; j++) {
97  for (int i = 0; i < n; i++) {
98  in_map[(i*m + j*n) % len] = j*n + i;
99  out_map[(i*m*m_inv + j*n*n_inv) % len] = i*m + j;
100  }
101  }
102  } else {
103  for (int j = 0; j < m; j++) {
104  for (int i = 0; i < n; i++) {
105  in_map[j*n + i] = (i*m + j*n) % len;
106  out_map[(i*m*m_inv + j*n*n_inv) % len] = i*m + j;
107  }
108  }
109  }
110 
111  if (inv) {
112  for (int i = 0; i < m; i++) {
113  int *in = &in_map[i*n + 1]; /* Skip the DC */
114  for (int j = 0; j < ((n - 1) >> 1); j++)
115  FFSWAP(int, in[j], in[n - j - 2]);
116  }
117  }
118 
119  s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER;
120 
121  return 0;
122 }
123 
124 static inline int split_radix_permutation(int i, int len, int inv)
125 {
126  len >>= 1;
127  if (len <= 1)
128  return i & 1;
129  if (!(i & len))
130  return split_radix_permutation(i, len, inv) * 2;
131  len >>= 1;
132  return split_radix_permutation(i, len, inv) * 4 + 1 - 2*(!(i & len) ^ inv);
133 }
134 
136 {
137  int len = s->len;
138 
139  if (!(s->map = av_malloc(len*sizeof(*s->map))))
140  return AVERROR(ENOMEM);
141 
142  if (opts && opts->map_dir == FF_TX_MAP_SCATTER) {
143  for (int i = 0; i < s->len; i++)
144  s->map[-split_radix_permutation(i, len, s->inv) & (len - 1)] = i;
145  } else {
146  for (int i = 0; i < s->len; i++)
147  s->map[i] = -split_radix_permutation(i, len, s->inv) & (len - 1);
148  }
149 
150  s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER;
151 
152  return 0;
153 }
154 
156 {
157  int *src_map, out_map_idx = 0;
158 
159  if (!s->sub || !s->sub->map)
160  return AVERROR(EINVAL);
161 
162  if (!(s->map = av_mallocz(len*sizeof(*s->map))))
163  return AVERROR(ENOMEM);
164 
165  src_map = s->sub->map;
166 
167  /* The first coefficient is always already in-place */
168  for (int src = 1; src < s->len; src++) {
169  int dst = src_map[src];
170  int found = 0;
171 
172  if (dst <= src)
173  continue;
174 
175  /* This just checks if a closed loop has been encountered before,
176  * and if so, skips it, since to fully permute a loop we must only
177  * enter it once. */
178  do {
179  for (int j = 0; j < out_map_idx; j++) {
180  if (dst == s->map[j]) {
181  found = 1;
182  break;
183  }
184  }
185  dst = src_map[dst];
186  } while (dst != src && !found);
187 
188  if (!found)
189  s->map[out_map_idx++] = src;
190  }
191 
192  s->map[out_map_idx++] = 0;
193 
194  return 0;
195 }
196 
197 static void parity_revtab_generator(int *revtab, int n, int inv, int offset,
198  int is_dual, int dual_high, int len,
199  int basis, int dual_stride, int inv_lookup)
200 {
201  len >>= 1;
202 
203  if (len <= basis) {
204  int k1, k2, stride, even_idx, odd_idx;
205 
206  is_dual = is_dual && dual_stride;
207  dual_high = is_dual & dual_high;
208  stride = is_dual ? FFMIN(dual_stride, len) : 0;
209 
210  even_idx = offset + dual_high*(stride - 2*len);
211  odd_idx = even_idx + len + (is_dual && !dual_high)*len + dual_high*len;
212 
213  for (int i = 0; i < len; i++) {
214  k1 = -split_radix_permutation(offset + i*2 + 0, n, inv) & (n - 1);
215  k2 = -split_radix_permutation(offset + i*2 + 1, n, inv) & (n - 1);
216  if (inv_lookup) {
217  revtab[even_idx++] = k1;
218  revtab[odd_idx++] = k2;
219  } else {
220  revtab[k1] = even_idx++;
221  revtab[k2] = odd_idx++;
222  }
223  if (stride && !((i + 1) % stride)) {
224  even_idx += stride;
225  odd_idx += stride;
226  }
227  }
228 
229  return;
230  }
231 
232  parity_revtab_generator(revtab, n, inv, offset,
233  0, 0, len >> 0, basis, dual_stride, inv_lookup);
234  parity_revtab_generator(revtab, n, inv, offset + (len >> 0),
235  1, 0, len >> 1, basis, dual_stride, inv_lookup);
236  parity_revtab_generator(revtab, n, inv, offset + (len >> 0) + (len >> 1),
237  1, 1, len >> 1, basis, dual_stride, inv_lookup);
238 }
239 
242  int basis, int dual_stride)
243 {
244  basis >>= 1;
245  if (len < basis)
246  return AVERROR(EINVAL);
247 
248  if (!(s->map = av_mallocz(len*sizeof(*s->map))))
249  return AVERROR(ENOMEM);
250 
251  av_assert0(!dual_stride || !(dual_stride & (dual_stride - 1)));
252  av_assert0(dual_stride <= basis);
253 
254  parity_revtab_generator(s->map, len, inv, 0, 0, 0, len,
255  basis, dual_stride,
256  opts ? opts->map_dir == FF_TX_MAP_GATHER : FF_TX_MAP_GATHER);
257 
258  s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER;
259 
260  return 0;
261 }
262 
263 static void reset_ctx(AVTXContext *s, int free_sub)
264 {
265  if (!s)
266  return;
267 
268  if (s->sub)
269  for (int i = 0; i < TX_MAX_SUB; i++)
270  reset_ctx(&s->sub[i], free_sub + 1);
271 
272  if (s->cd_self && s->cd_self->uninit)
273  s->cd_self->uninit(s);
274 
275  if (free_sub)
276  av_freep(&s->sub);
277 
278  av_freep(&s->map);
279  av_freep(&s->exp);
280  av_freep(&s->tmp);
281 
282  /* Nothing else needs to be reset, it gets overwritten if another
283  * ff_tx_init_subtx() call is made. */
284  s->nb_sub = 0;
285  s->opaque = NULL;
286  memset(s->fn, 0, sizeof(*s->fn));
287 }
288 
290 {
291  reset_ctx(s, 0);
292 }
293 
295 {
296  if (!(*ctx))
297  return;
298 
299  reset_ctx(*ctx, 1);
300  av_freep(ctx);
301 }
302 
304  uint64_t flags, FFTXCodeletOptions *opts,
305  int len, int inv, const void *scale)
306 {
307  /* Can only handle one sample+type to one sample+type transforms */
308  if (TYPE_IS(MDCT, s->type) || TYPE_IS(RDFT, s->type))
309  return AVERROR(EINVAL);
310  return 0;
311 }
312 
313 /* Null transform when the length is 1 */
314 static void ff_tx_null(AVTXContext *s, void *_out, void *_in, ptrdiff_t stride)
315 {
316  memcpy(_out, _in, stride);
317 }
318 
319 static const FFTXCodelet ff_tx_null_def = {
320  .name = NULL_IF_CONFIG_SMALL("null"),
321  .function = ff_tx_null,
322  .type = TX_TYPE_ANY,
323  .flags = AV_TX_UNALIGNED | FF_TX_ALIGNED |
325  .factors[0] = TX_FACTOR_ANY,
326  .min_len = 1,
327  .max_len = 1,
328  .init = ff_tx_null_init,
329  .cpu_flags = FF_TX_CPU_FLAGS_ALL,
330  .prio = FF_TX_PRIO_MAX,
331 };
332 
333 static const FFTXCodelet * const ff_tx_null_list[] = {
335  NULL,
336 };
337 
338 /* Array of all compiled codelet lists. Order is irrelevant. */
339 static const FFTXCodelet * const * const codelet_list[] = {
344 #if HAVE_X86ASM
346 #endif
347 #if ARCH_AARCH64
349 #endif
350 };
352 
356 
357 static const int cpu_slow_penalties[][2] = {
358  { AV_CPU_FLAG_SSE2SLOW, 1 + 64 },
359  { AV_CPU_FLAG_SSE3SLOW, 1 + 64 },
360  { AV_CPU_FLAG_SSSE3SLOW, 1 + 64 },
361  { AV_CPU_FLAG_ATOM, 1 + 128 },
362  { AV_CPU_FLAG_AVXSLOW, 1 + 128 },
363  { AV_CPU_FLAG_SLOW_GATHER, 1 + 32 },
364 };
365 
366 static int get_codelet_prio(const FFTXCodelet *cd, int cpu_flags, int len)
367 {
368  int prio = cd->prio;
369  int max_factor = 0;
370 
371  /* If the CPU has a SLOW flag, and the instruction is also flagged
372  * as being slow for such, reduce its priority */
373  for (int i = 0; i < FF_ARRAY_ELEMS(cpu_slow_penalties); i++) {
374  if ((cpu_flags & cd->cpu_flags) & cpu_slow_penalties[i][0])
375  prio -= cpu_slow_penalties[i][1];
376  }
377 
378  /* Prioritize aligned-only codelets */
379  if ((cd->flags & FF_TX_ALIGNED) && !(cd->flags & AV_TX_UNALIGNED))
380  prio += 64;
381 
382  /* Codelets for specific lengths are generally faster */
383  if ((len == cd->min_len) && (len == cd->max_len))
384  prio += 64;
385 
386  /* Forward-only or inverse-only transforms are generally better */
388  prio += 64;
389 
390  /* Larger factors are generally better */
391  for (int i = 0; i < TX_MAX_SUB; i++)
392  max_factor = FFMAX(cd->factors[i], max_factor);
393  if (max_factor)
394  prio += 16*max_factor;
395 
396  return prio;
397 }
398 
399 typedef struct FFTXLenDecomp {
400  int len;
401  int len2;
402  int prio;
403  const FFTXCodelet *cd;
404 } FFTXLenDecomp;
405 
407 {
408  return FFDIFFSIGN(b->prio, a->prio);
409 }
410 
412  int len, int inv)
413 {
414  int nb_decomp = 0;
416  int codelet_list_idx = codelet_list_num;
417 
418  const int cpu_flags = av_get_cpu_flags();
419 
420  /* Loop through all codelets in all codelet lists to find matches
421  * to the requirements */
422  while (codelet_list_idx--) {
423  const FFTXCodelet * const * list = codelet_list[codelet_list_idx];
424  const FFTXCodelet *cd = NULL;
425 
426  while ((cd = *list++)) {
427  int fl = len;
428  int skip = 0, prio;
429  int factors_product = 1, factors_mod = 0;
430 
431  if (nb_decomp >= TX_MAX_DECOMPOSITIONS)
432  goto sort;
433 
434  /* Check if the type matches */
435  if (cd->type != TX_TYPE_ANY && type != cd->type)
436  continue;
437 
438  /* Check direction for non-orthogonal codelets */
439  if (((cd->flags & FF_TX_FORWARD_ONLY) && inv) ||
440  ((cd->flags & (FF_TX_INVERSE_ONLY | AV_TX_FULL_IMDCT)) && !inv) ||
441  ((cd->flags & (FF_TX_FORWARD_ONLY | AV_TX_REAL_TO_REAL)) && inv) ||
442  ((cd->flags & (FF_TX_FORWARD_ONLY | AV_TX_REAL_TO_IMAGINARY)) && inv))
443  continue;
444 
445  /* Check if the CPU supports the required ISA */
446  if (cd->cpu_flags != FF_TX_CPU_FLAGS_ALL &&
447  !(cpu_flags & (cd->cpu_flags & ~cpu_slow_mask)))
448  continue;
449 
450  for (int i = 0; i < TX_MAX_FACTORS; i++) {
451  if (!cd->factors[i] || (fl == 1))
452  break;
453 
454  if (cd->factors[i] == TX_FACTOR_ANY) {
455  factors_mod++;
456  factors_product *= fl;
457  } else if (!(fl % cd->factors[i])) {
458  factors_mod++;
459  if (cd->factors[i] == 2) {
460  int b = ff_ctz(fl);
461  fl >>= b;
462  factors_product <<= b;
463  } else {
464  do {
465  fl /= cd->factors[i];
466  factors_product *= cd->factors[i];
467  } while (!(fl % cd->factors[i]));
468  }
469  }
470  }
471 
472  /* Disqualify if factor requirements are not satisfied or if trivial */
473  if ((factors_mod < cd->nb_factors) || (len == factors_product))
474  continue;
475 
476  if (av_gcd(factors_product, fl) != 1)
477  continue;
478 
479  /* Check if length is supported and factorization was successful */
480  if ((factors_product < cd->min_len) ||
481  (cd->max_len != TX_LEN_UNLIMITED && (factors_product > cd->max_len)))
482  continue;
483 
484  prio = get_codelet_prio(cd, cpu_flags, factors_product) * factors_product;
485 
486  /* Check for duplicates */
487  for (int i = 0; i < nb_decomp; i++) {
488  if (factors_product == ld[i].len) {
489  /* Update priority if new one is higher */
490  if (prio > ld[i].prio)
491  ld[i].prio = prio;
492  skip = 1;
493  break;
494  }
495  }
496 
497  /* Add decomposition if unique */
498  if (!skip) {
499  ld[nb_decomp].cd = cd;
500  ld[nb_decomp].len = factors_product;
501  ld[nb_decomp].len2 = fl;
502  ld[nb_decomp].prio = prio;
503  nb_decomp++;
504  }
505  }
506  }
507 
508  if (!nb_decomp)
509  return AVERROR(EINVAL);
510 
511 sort:
512  AV_QSORT(ld, nb_decomp, FFTXLenDecomp, cmp_decomp);
513 
514  for (int i = 0; i < nb_decomp; i++) {
515  if (ld[i].cd->nb_factors > 1)
516  dst[i] = ld[i].len2;
517  else
518  dst[i] = ld[i].len;
519  }
520 
521  return nb_decomp;
522 }
523 
525 {
526  s->map = av_malloc(s->len*sizeof(*s->map));
527  if (!s->map)
528  return AVERROR(ENOMEM);
529 
530  s->map[0] = 0; /* DC is always at the start */
531  if (s->inv) /* Reversing the ACs flips the transform direction */
532  for (int i = 1; i < s->len; i++)
533  s->map[i] = s->len - i;
534  else
535  for (int i = 1; i < s->len; i++)
536  s->map[i] = i;
537 
538  s->map_dir = FF_TX_MAP_GATHER;
539 
540  return 0;
541 }
542 
543 #if !CONFIG_SMALL
544 static void print_flags(AVBPrint *bp, uint64_t f)
545 {
546  int prev = 0;
547  const char *sep = ", ";
548  av_bprintf(bp, "flags: [");
549  if ((f & FF_TX_ALIGNED) && ++prev)
550  av_bprintf(bp, "aligned");
551  if ((f & AV_TX_UNALIGNED) && ++prev)
552  av_bprintf(bp, "%sunaligned", prev > 1 ? sep : "");
553  if ((f & AV_TX_INPLACE) && ++prev)
554  av_bprintf(bp, "%sinplace", prev > 1 ? sep : "");
555  if ((f & FF_TX_OUT_OF_PLACE) && ++prev)
556  av_bprintf(bp, "%sout_of_place", prev > 1 ? sep : "");
557  if ((f & FF_TX_FORWARD_ONLY) && ++prev)
558  av_bprintf(bp, "%sfwd_only", prev > 1 ? sep : "");
559  if ((f & FF_TX_INVERSE_ONLY) && ++prev)
560  av_bprintf(bp, "%sinv_only", prev > 1 ? sep : "");
561  if ((f & FF_TX_PRESHUFFLE) && ++prev)
562  av_bprintf(bp, "%spreshuf", prev > 1 ? sep : "");
563  if ((f & AV_TX_FULL_IMDCT) && ++prev)
564  av_bprintf(bp, "%simdct_full", prev > 1 ? sep : "");
565  if ((f & AV_TX_REAL_TO_REAL) && ++prev)
566  av_bprintf(bp, "%sreal_to_real", prev > 1 ? sep : "");
567  if ((f & AV_TX_REAL_TO_IMAGINARY) && ++prev)
568  av_bprintf(bp, "%sreal_to_imaginary", prev > 1 ? sep : "");
569  if ((f & FF_TX_ASM_CALL) && ++prev)
570  av_bprintf(bp, "%sasm_call", prev > 1 ? sep : "");
571  av_bprintf(bp, "]");
572 }
573 
574 static void print_type(AVBPrint *bp, enum AVTXType type)
575 {
576  av_bprintf(bp, "%s",
577  type == TX_TYPE_ANY ? "any" :
578  type == AV_TX_FLOAT_FFT ? "fft_float" :
579  type == AV_TX_FLOAT_MDCT ? "mdct_float" :
580  type == AV_TX_FLOAT_RDFT ? "rdft_float" :
581  type == AV_TX_FLOAT_DCT_I ? "dctI_float" :
582  type == AV_TX_FLOAT_DST_I ? "dstI_float" :
583  type == AV_TX_DOUBLE_FFT ? "fft_double" :
584  type == AV_TX_DOUBLE_MDCT ? "mdct_double" :
585  type == AV_TX_DOUBLE_RDFT ? "rdft_double" :
586  type == AV_TX_DOUBLE_DCT_I ? "dctI_double" :
587  type == AV_TX_DOUBLE_DST_I ? "dstI_double" :
588  type == AV_TX_INT32_FFT ? "fft_int32" :
589  type == AV_TX_INT32_MDCT ? "mdct_int32" :
590  type == AV_TX_INT32_RDFT ? "rdft_int32" :
591  type == AV_TX_INT32_DCT_I ? "dctI_int32" :
592  type == AV_TX_INT32_DST_I ? "dstI_int32" :
593  "unknown");
594 }
595 
596 static void print_cd_info(const FFTXCodelet *cd, int prio, int len, int print_prio,
597  int log_level)
598 {
599  AVBPrint bp;
601 
602  av_bprintf(&bp, "%s - type: ", cd->name);
603 
604  print_type(&bp, cd->type);
605 
606  av_bprintf(&bp, ", len: ");
607  if (!len) {
608  if (cd->min_len != cd->max_len)
609  av_bprintf(&bp, "[%i, ", cd->min_len);
610 
611  if (cd->max_len == TX_LEN_UNLIMITED)
612  av_bprintf(&bp, "∞");
613  else
614  av_bprintf(&bp, "%i", cd->max_len);
615  } else {
616  av_bprintf(&bp, "%i", len);
617  }
618 
619  if (cd->factors[1]) {
620  av_bprintf(&bp, "%s, factors", !len && cd->min_len != cd->max_len ? "]" : "");
621  if (!cd->nb_factors)
622  av_bprintf(&bp, ": [");
623  else
624  av_bprintf(&bp, "[%i]: [", cd->nb_factors);
625 
626  for (int i = 0; i < TX_MAX_FACTORS; i++) {
627  if (i && cd->factors[i])
628  av_bprintf(&bp, ", ");
629  if (cd->factors[i] == TX_FACTOR_ANY)
630  av_bprintf(&bp, "any");
631  else if (cd->factors[i])
632  av_bprintf(&bp, "%i", cd->factors[i]);
633  else
634  break;
635  }
636 
637  av_bprintf(&bp, "], ");
638  } else {
639  av_bprintf(&bp, "%s, factor: %i, ",
640  !len && cd->min_len != cd->max_len ? "]" : "", cd->factors[0]);
641  }
642  print_flags(&bp, cd->flags);
643 
644  if (print_prio)
645  av_bprintf(&bp, ", prio: %i", prio);
646 
647  av_log(NULL, log_level, "%s\n", bp.str);
648 }
649 
650 static void print_tx_structure(AVTXContext *s, int depth)
651 {
652  const FFTXCodelet *cd = s->cd_self;
653 
654  for (int i = 0; i <= depth; i++)
655  av_log(NULL, AV_LOG_DEBUG, " ");
656 
657  print_cd_info(cd, cd->prio, s->len, 0, AV_LOG_DEBUG);
658 
659  for (int i = 0; i < s->nb_sub; i++)
660  print_tx_structure(&s->sub[i], depth + 1);
661 }
662 #endif /* CONFIG_SMALL */
663 
664 typedef struct TXCodeletMatch {
665  const FFTXCodelet *cd;
666  int prio;
668 
670 {
671  return FFDIFFSIGN(b->prio, a->prio);
672 }
673 
674 /* We want all factors to completely cover the length */
675 static inline int check_cd_factors(const FFTXCodelet *cd, int len)
676 {
677  int matches = 0, any_flag = 0;
678 
679  for (int i = 0; i < TX_MAX_FACTORS; i++) {
680  int factor = cd->factors[i];
681 
682  if (factor == TX_FACTOR_ANY) {
683  any_flag = 1;
684  matches++;
685  continue;
686  } else if (len <= 1 || !factor) {
687  break;
688  } else if (factor == 2) { /* Fast path */
689  int bits_2 = ff_ctz(len);
690  if (!bits_2)
691  continue; /* Factor not supported */
692 
693  len >>= bits_2;
694  matches++;
695  } else {
696  int res = len % factor;
697  if (res)
698  continue; /* Factor not supported */
699 
700  while (!res) {
701  len /= factor;
702  res = len % factor;
703  }
704  matches++;
705  }
706  }
707 
708  return (cd->nb_factors <= matches) && (any_flag || len == 1);
709 }
710 
712  uint64_t flags, FFTXCodeletOptions *opts,
713  int len, int inv, const void *scale)
714 {
715  int ret = 0;
716  AVTXContext *sub = NULL;
717  TXCodeletMatch *cd_tmp, *cd_matches = NULL;
718  unsigned int cd_matches_size = 0;
719  int codelet_list_idx = codelet_list_num;
720  int nb_cd_matches = 0;
721 #if !CONFIG_SMALL
722  AVBPrint bp;
723 #endif
724 
725  /* We still accept functions marked with SLOW, even if the CPU is
726  * marked with the same flag, but we give them lower priority. */
727  const int cpu_flags = av_get_cpu_flags();
728 
729  /* Flags the transform wants */
730  uint64_t req_flags = flags;
731 
732  /* Flags the codelet may require to be present */
733  uint64_t inv_req_mask = AV_TX_FULL_IMDCT |
738 
739  /* Unaligned codelets are compatible with the aligned flag */
740  if (req_flags & FF_TX_ALIGNED)
741  req_flags |= AV_TX_UNALIGNED;
742 
743  /* If either flag is set, both are okay, so don't check for an exact match */
744  if ((req_flags & AV_TX_INPLACE) && (req_flags & FF_TX_OUT_OF_PLACE))
745  req_flags &= ~(AV_TX_INPLACE | FF_TX_OUT_OF_PLACE);
746  if ((req_flags & FF_TX_ALIGNED) && (req_flags & AV_TX_UNALIGNED))
747  req_flags &= ~(FF_TX_ALIGNED | AV_TX_UNALIGNED);
748 
749  /* Loop through all codelets in all codelet lists to find matches
750  * to the requirements */
751  while (codelet_list_idx--) {
752  const FFTXCodelet * const * list = codelet_list[codelet_list_idx];
753  const FFTXCodelet *cd = NULL;
754 
755  while ((cd = *list++)) {
756  /* Check if the type matches */
757  if (cd->type != TX_TYPE_ANY && type != cd->type)
758  continue;
759 
760  /* Check direction for non-orthogonal codelets */
761  if (((cd->flags & FF_TX_FORWARD_ONLY) && inv) ||
762  ((cd->flags & (FF_TX_INVERSE_ONLY | AV_TX_FULL_IMDCT)) && !inv) ||
763  ((cd->flags & (FF_TX_FORWARD_ONLY | AV_TX_REAL_TO_REAL)) && inv) ||
764  ((cd->flags & (FF_TX_FORWARD_ONLY | AV_TX_REAL_TO_IMAGINARY)) && inv))
765  continue;
766 
767  /* Check if the requested flags match from both sides */
768  if (((req_flags & cd->flags) != (req_flags)) ||
769  ((inv_req_mask & cd->flags) != (req_flags & inv_req_mask)))
770  continue;
771 
772  /* Check if length is supported */
773  if ((len < cd->min_len) || (cd->max_len != -1 && (len > cd->max_len)))
774  continue;
775 
776  /* Check if the CPU supports the required ISA */
777  if (cd->cpu_flags != FF_TX_CPU_FLAGS_ALL &&
778  !(cpu_flags & (cd->cpu_flags & ~cpu_slow_mask)))
779  continue;
780 
781  /* Check for factors */
782  if (!check_cd_factors(cd, len))
783  continue;
784 
785  /* Realloc array and append */
786  cd_tmp = av_fast_realloc(cd_matches, &cd_matches_size,
787  sizeof(*cd_tmp) * (nb_cd_matches + 1));
788  if (!cd_tmp) {
789  av_free(cd_matches);
790  return AVERROR(ENOMEM);
791  }
792 
793  cd_matches = cd_tmp;
794  cd_matches[nb_cd_matches].cd = cd;
795  cd_matches[nb_cd_matches].prio = get_codelet_prio(cd, cpu_flags, len);
796  nb_cd_matches++;
797  }
798  }
799 
800 #if !CONFIG_SMALL
801  /* Print debugging info */
803  av_bprintf(&bp, "For transform of length %i, %s, ", len,
804  inv ? "inverse" : "forward");
805  print_type(&bp, type);
806  av_bprintf(&bp, ", ");
807  print_flags(&bp, flags);
808  av_bprintf(&bp, ", found %i matches%s", nb_cd_matches,
809  nb_cd_matches ? ":" : ".");
810 #endif
811 
812  /* No matches found */
813  if (!nb_cd_matches)
814  return AVERROR(ENOSYS);
815 
816  /* Sort the list */
817  AV_QSORT(cd_matches, nb_cd_matches, TXCodeletMatch, cmp_matches);
818 
819 #if !CONFIG_SMALL
820  av_log(NULL, AV_LOG_TRACE, "%s\n", bp.str);
821 
822  for (int i = 0; i < nb_cd_matches; i++) {
823  av_log(NULL, AV_LOG_TRACE, " %i: ", i + 1);
824  print_cd_info(cd_matches[i].cd, cd_matches[i].prio, 0, 1, AV_LOG_TRACE);
825  }
826 #endif
827 
828  if (!s->sub) {
829  s->sub = sub = av_mallocz(TX_MAX_SUB*sizeof(*sub));
830  if (!sub) {
831  ret = AVERROR(ENOMEM);
832  goto end;
833  }
834  }
835 
836  /* Attempt to initialize each */
837  for (int i = 0; i < nb_cd_matches; i++) {
838  const FFTXCodelet *cd = cd_matches[i].cd;
839  AVTXContext *sctx = &s->sub[s->nb_sub];
840 
841  sctx->len = len;
842  sctx->inv = inv;
843  sctx->type = type;
844  sctx->flags = cd->flags | flags;
845  sctx->cd_self = cd;
846 
847  s->fn[s->nb_sub] = cd->function;
848  s->cd[s->nb_sub] = cd;
849 
850  ret = 0;
851  if (cd->init)
852  ret = cd->init(sctx, cd, flags, opts, len, inv, scale);
853 
854  if (ret >= 0) {
855  if (opts && opts->map_dir != FF_TX_MAP_NONE &&
856  sctx->map_dir == FF_TX_MAP_NONE) {
857  /* If a specific map direction was requested, and it doesn't
858  * exist, create one.*/
859  sctx->map = av_malloc(len*sizeof(*sctx->map));
860  if (!sctx->map) {
861  ret = AVERROR(ENOMEM);
862  goto end;
863  }
864 
865  for (int i = 0; i < len; i++)
866  sctx->map[i] = i;
867  } else if (opts && (opts->map_dir != sctx->map_dir)) {
868  int *tmp = av_malloc(len*sizeof(*sctx->map));
869  if (!tmp) {
870  ret = AVERROR(ENOMEM);
871  goto end;
872  }
873 
874  memcpy(tmp, sctx->map, len*sizeof(*sctx->map));
875 
876  for (int i = 0; i < len; i++)
877  sctx->map[tmp[i]] = i;
878 
879  av_free(tmp);
880  }
881 
882  s->nb_sub++;
883  goto end;
884  }
885 
886  s->fn[s->nb_sub] = NULL;
887  s->cd[s->nb_sub] = NULL;
888 
889  reset_ctx(sctx, 0);
890  if (ret == AVERROR(ENOMEM))
891  break;
892  }
893 
894  if (!s->nb_sub)
895  av_freep(&s->sub);
896 
897 end:
898  av_free(cd_matches);
899  return ret;
900 }
901 
903  int inv, int len, const void *scale, uint64_t flags)
904 {
905  int ret;
906  AVTXContext tmp = { 0 };
907  const double default_scale_d = 1.0;
908  const float default_scale_f = 1.0f;
909 
910  if (!len || type >= AV_TX_NB || !ctx || !tx)
911  return AVERROR(EINVAL);
912 
913  if (!(flags & AV_TX_UNALIGNED))
914  flags |= FF_TX_ALIGNED;
915  if (!(flags & AV_TX_INPLACE))
917 
918  if (!scale && ((type == AV_TX_DOUBLE_MDCT) || (type == AV_TX_DOUBLE_DCT) ||
920  (type == AV_TX_DOUBLE_RDFT)))
921  scale = &default_scale_d;
922  else if (!scale && !TYPE_IS(FFT, type))
923  scale = &default_scale_f;
924 
925  ret = ff_tx_init_subtx(&tmp, type, flags, NULL, len, inv, scale);
926  if (ret < 0)
927  return ret;
928 
929  *ctx = &tmp.sub[0];
930  *tx = tmp.fn[0];
931 
932 #if !CONFIG_SMALL
933  av_log(NULL, AV_LOG_DEBUG, "Transform tree:\n");
934  print_tx_structure(*ctx, 0);
935 #endif
936 
937  return ret;
938 }
AV_TX_DOUBLE_MDCT
@ AV_TX_DOUBLE_MDCT
Definition: tx.h:69
AV_TX_REAL_TO_REAL
@ AV_TX_REAL_TO_REAL
Perform a real to half-complex RDFT.
Definition: tx.h:184
AV_CPU_FLAG_SSSE3SLOW
#define AV_CPU_FLAG_SSSE3SLOW
SSSE3 supported, but usually not faster.
Definition: cpu.h:42
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
ff_ctz
#define ff_ctz
Definition: intmath.h:107
AVTXContext::map
int * map
Definition: tx_priv.h:240
TXCodeletMatch
Definition: tx.c:664
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
cmp_decomp
static int cmp_decomp(FFTXLenDecomp *a, FFTXLenDecomp *b)
Definition: tx.c:406
print_cd_info
static void print_cd_info(const FFTXCodelet *cd, int prio, int len, int print_prio, int log_level)
Definition: tx.c:596
AV_CPU_FLAG_SSE3SLOW
#define AV_CPU_FLAG_SSE3SLOW
SSE3 supported, but usually not faster.
Definition: cpu.h:39
AVTXContext
Definition: tx_priv.h:235
AVTXContext::map_dir
FFTXMapDirection map_dir
Definition: tx_priv.h:260
ff_tx_null_def
static const FFTXCodelet ff_tx_null_def
Definition: tx.c:319
basis
static int16_t basis[64][64]
Definition: mpegvideo_enc.c:4196
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
FFTXCodeletOptions
Definition: tx_priv.h:183
w
uint8_t w
Definition: llviddspenc.c:38
b
#define b
Definition: input.c:41
ff_tx_gen_split_radix_parity_revtab
int ff_tx_gen_split_radix_parity_revtab(AVTXContext *s, int len, int inv, FFTXCodeletOptions *opts, int basis, int dual_stride)
Definition: tx.c:240
TX_MAX_DECOMPOSITIONS
#define TX_MAX_DECOMPOSITIONS
Definition: tx_priv.h:197
ff_tx_gen_inplace_map
int ff_tx_gen_inplace_map(AVTXContext *s, int len)
Definition: tx.c:155
AV_TX_DOUBLE_FFT
@ AV_TX_DOUBLE_FFT
Definition: tx.h:48
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_get_cpu_flags
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:103
FF_TX_CPU_FLAGS_ALL
#define FF_TX_CPU_FLAGS_ALL
Definition: tx_priv.h:230
ff_tx_gen_compound_mapping
int ff_tx_gen_compound_mapping(AVTXContext *s, FFTXCodeletOptions *opts, int inv, int n, int m)
Definition: tx.c:74
print_type
static void print_type(AVBPrint *bp, enum AVTXType type)
Definition: tx.c:574
cpu_flags
static atomic_int cpu_flags
Definition: cpu.c:52
cmp_matches
static int cmp_matches(TXCodeletMatch *a, TXCodeletMatch *b)
Definition: tx.c:669
print_flags
static void print_flags(AVBPrint *bp, uint64_t f)
Definition: tx.c:544
av_tx_init
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
Definition: tx.c:902
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
av_gcd
int64_t av_gcd(int64_t a, int64_t b)
Compute the greatest common divisor of two integer operands.
Definition: mathematics.c:37
FFTXCodelet::nb_factors
int nb_factors
Definition: tx_priv.h:211
AV_TX_INT32_DCT_I
@ AV_TX_INT32_DCT_I
Definition: tx.h:118
AV_TX_DOUBLE_DCT
@ AV_TX_DOUBLE_DCT
Definition: tx.h:105
FF_TX_MAP_GATHER
@ FF_TX_MAP_GATHER
Definition: tx_priv.h:176
ff_tx_null_init
static av_cold int ff_tx_null_init(AVTXContext *s, const FFTXCodelet *cd, uint64_t flags, FFTXCodeletOptions *opts, int len, int inv, const void *scale)
Definition: tx.c:303
AV_BPRINT_SIZE_AUTOMATIC
#define AV_BPRINT_SIZE_AUTOMATIC
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
AV_TX_INT32_DST_I
@ AV_TX_INT32_DST_I
Definition: tx.h:130
TX_MAX_SUB
#define TX_MAX_SUB
Definition: tx_priv.h:194
FFTXCodelet::min_len
int min_len
Definition: tx_priv.h:214
FF_TX_ALIGNED
#define FF_TX_ALIGNED
Definition: tx_priv.h:155
FFTXCodelet::type
enum AVTXType type
Definition: tx_priv.h:202
FFDIFFSIGN
#define FFDIFFSIGN(x, y)
Comparator.
Definition: macros.h:45
AV_CPU_FLAG_SLOW_GATHER
#define AV_CPU_FLAG_SLOW_GATHER
CPU has slow gathers.
Definition: cpu.h:58
avassert.h
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:206
FFTXCodelet::factors
int factors[TX_MAX_FACTORS]
Definition: tx_priv.h:208
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
AV_TX_NB
@ AV_TX_NB
Definition: tx.h:133
av_tx_fn
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
Definition: tx.h:151
AV_TX_FLOAT_MDCT
@ AV_TX_FLOAT_MDCT
Standard MDCT with a sample data type of float, double or int32_t, respecively.
Definition: tx.h:68
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:495
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_TX_DOUBLE_DCT_I
@ AV_TX_DOUBLE_DCT_I
Definition: tx.h:117
FFTXCodelet::flags
uint64_t flags
Definition: tx_priv.h:205
FFTXCodelet::prio
int prio
Definition: tx_priv.h:232
AV_TX_INT32_MDCT
@ AV_TX_INT32_MDCT
Definition: tx.h:70
AVTXContext::type
enum AVTXType type
Definition: tx_priv.h:257
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
FF_TX_FORWARD_ONLY
#define FF_TX_FORWARD_ONLY
Definition: tx_priv.h:158
AVTXContext::len
int len
Definition: tx_priv.h:238
AV_TX_FLOAT_FFT
@ AV_TX_FLOAT_FFT
Standard complex to complex FFT with sample data type of AVComplexFloat, AVComplexDouble or AVComplex...
Definition: tx.h:47
split_radix_permutation
static int split_radix_permutation(int i, int len, int inv)
Definition: tx.c:124
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
FFTXCodelet::cpu_flags
int cpu_flags
Definition: tx_priv.h:227
codelet_list_num
static const int codelet_list_num
Definition: tx.c:351
TX_TYPE_ANY
#define TX_TYPE_ANY
Definition: tx_priv.h:203
AV_TX_FULL_IMDCT
@ AV_TX_FULL_IMDCT
Performs a full inverse MDCT rather than leaving out samples that can be derived through symmetry.
Definition: tx.h:175
opts
AVDictionary * opts
Definition: movenc.c:50
FFTXLenDecomp::len2
int len2
Definition: tx.c:401
TXCodeletMatch::cd
const FFTXCodelet * cd
Definition: tx.c:665
AV_TX_REAL_TO_IMAGINARY
@ AV_TX_REAL_TO_IMAGINARY
Definition: tx.h:185
NULL
#define NULL
Definition: coverity.c:32
AV_TX_INPLACE
@ AV_TX_INPLACE
Allows for in-place transformations, where input == output.
Definition: tx.h:161
ff_tx_gen_ptwo_revtab
int ff_tx_gen_ptwo_revtab(AVTXContext *s, FFTXCodeletOptions *opts)
Definition: tx.c:135
ff_tx_null
static void ff_tx_null(AVTXContext *s, void *_out, void *_in, ptrdiff_t stride)
Definition: tx.c:314
cpu_slow_mask
static const int cpu_slow_mask
Definition: tx.c:353
FF_TX_OUT_OF_PLACE
#define FF_TX_OUT_OF_PLACE
Definition: tx_priv.h:154
list
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining list
Definition: filter_design.txt:25
FF_TX_PRIO_MAX
@ FF_TX_PRIO_MAX
Definition: tx_priv.h:168
FFTXCodelet::init
int(* init)(AVTXContext *s, const struct FFTXCodelet *cd, uint64_t flags, FFTXCodeletOptions *opts, int len, int inv, const void *scale)
Definition: tx_priv.h:218
AV_TX_UNALIGNED
@ AV_TX_UNALIGNED
Relaxes alignment requirement for the in and out arrays of av_tx_fn().
Definition: tx.h:167
get_codelet_prio
static int get_codelet_prio(const FFTXCodelet *cd, int cpu_flags, int len)
Definition: tx.c:366
TXCodeletMatch::prio
int prio
Definition: tx.c:666
ff_tx_clear_ctx
void ff_tx_clear_ctx(AVTXContext *s)
Definition: tx.c:289
qsort.h
FF_TX_PRESHUFFLE
#define FF_TX_PRESHUFFLE
Definition: tx_priv.h:156
reset_ctx
static void reset_ctx(AVTXContext *s, int free_sub)
Definition: tx.c:263
ff_tx_gen_default_map
int ff_tx_gen_default_map(AVTXContext *s, FFTXCodeletOptions *opts)
Definition: tx.c:524
f
f
Definition: af_crystalizer.c:121
AV_TX_FLOAT_DCT_I
@ AV_TX_FLOAT_DCT_I
Discrete Cosine Transform I.
Definition: tx.h:116
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: vvc_intra.c:292
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
AV_CPU_FLAG_AVXSLOW
#define AV_CPU_FLAG_AVXSLOW
AVX supported, but slow when using YMM registers (e.g. Bulldozer)
Definition: cpu.h:48
cpu.h
AVTXType
AVTXType
Definition: tx.h:39
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
ff_tx_codelet_list_float_aarch64
const FFTXCodelet *const ff_tx_codelet_list_float_aarch64[]
Definition: tx_float_init.c:47
AV_CPU_FLAG_SSE2SLOW
#define AV_CPU_FLAG_SSE2SLOW
SSE2 supported, but usually not faster.
Definition: cpu.h:35
AV_TX_INT32_FFT
@ AV_TX_INT32_FFT
Definition: tx.h:49
ff_tx_codelet_list_double_c
const FFTXCodelet *const ff_tx_codelet_list_double_c[]
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
FFTXLenDecomp::cd
const FFTXCodelet * cd
Definition: tx.c:403
AVTXContext::inv
int inv
Definition: tx_priv.h:239
av_tx_uninit
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
Definition: tx.c:294
FFTXCodelet::max_len
int max_len
Definition: tx_priv.h:215
cpu_slow_penalties
static const int cpu_slow_penalties[][2]
Definition: tx.c:357
bprint.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AV_QSORT
#define AV_QSORT(p, num, type, cmp)
Quicksort This sort is fast, and fully inplace but not stable and it is possible to construct input t...
Definition: qsort.h:33
AV_TX_DOUBLE_DST_I
@ AV_TX_DOUBLE_DST_I
Definition: tx.h:129
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_TX_DOUBLE_RDFT
@ AV_TX_DOUBLE_RDFT
Definition: tx.h:91
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
len
int len
Definition: vorbis_enc_data.h:426
FF_TX_MAP_SCATTER
@ FF_TX_MAP_SCATTER
Definition: tx_priv.h:179
TX_LEN_UNLIMITED
#define TX_LEN_UNLIMITED
Definition: tx_priv.h:216
stride
#define stride
Definition: h264pred_template.c:537
AV_CPU_FLAG_ATOM
#define AV_CPU_FLAG_ATOM
Atom processor, some SSSE3 instructions are slower.
Definition: cpu.h:43
tx_priv.h
FFTXLenDecomp::len
int len
Definition: tx.c:400
AVTXContext::flags
uint64_t flags
Definition: tx_priv.h:258
ret
ret
Definition: filter_design.txt:187
ff_tx_init_subtx
av_cold int ff_tx_init_subtx(AVTXContext *s, enum AVTXType type, uint64_t flags, FFTXCodeletOptions *opts, int len, int inv, const void *scale)
Definition: tx.c:711
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
TX_FACTOR_ANY
#define TX_FACTOR_ANY
Definition: tx_priv.h:209
FF_TX_INVERSE_ONLY
#define FF_TX_INVERSE_ONLY
Definition: tx_priv.h:157
FFTXLenDecomp::prio
int prio
Definition: tx.c:402
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
ff_tx_codelet_list_float_c
const FFTXCodelet *const ff_tx_codelet_list_float_c[]
FFTXLenDecomp
Definition: tx.c:399
AV_TX_FLOAT_RDFT
@ AV_TX_FLOAT_RDFT
Real to complex and complex to real DFTs.
Definition: tx.h:90
FF_TX_MAP_NONE
@ FF_TX_MAP_NONE
Definition: tx_priv.h:173
FFTXCodelet
Definition: tx_priv.h:199
AV_TX_FLOAT_DST_I
@ AV_TX_FLOAT_DST_I
Discrete Sine Transform I.
Definition: tx.h:128
check_cd_factors
static int check_cd_factors(const FFTXCodelet *cd, int len)
Definition: tx.c:675
AV_TX_INT32_RDFT
@ AV_TX_INT32_RDFT
Definition: tx.h:92
AVTXContext::cd_self
const FFTXCodelet * cd_self
Definition: tx_priv.h:256
FFTXCodelet::name
const char * name
Definition: tx_priv.h:200
factor
static const int factor[16]
Definition: vf_pp7.c:78
FF_TX_ASM_CALL
#define FF_TX_ASM_CALL
Definition: tx_priv.h:159
ff_tx_codelet_list_float_x86
const FFTXCodelet *const ff_tx_codelet_list_float_x86[]
Definition: tx_float_init.c:230
print_tx_structure
static void print_tx_structure(AVTXContext *s, int depth)
Definition: tx.c:650
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
ff_tx_null_list
static const FFTXCodelet *const ff_tx_null_list[]
Definition: tx.c:333
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
mulinv
static av_always_inline int mulinv(int n, int m)
Definition: tx.c:33
ff_tx_codelet_list_int32_c
const FFTXCodelet *const ff_tx_codelet_list_int32_c[]
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
TX_MAX_FACTORS
#define TX_MAX_FACTORS
Definition: tx_priv.h:191
ff_tx_gen_pfa_input_map
int ff_tx_gen_pfa_input_map(AVTXContext *s, FFTXCodeletOptions *opts, int d1, int d2)
Definition: tx.c:43
TYPE_IS
#define TYPE_IS(type, x)
Definition: tx.c:27
FFTXCodelet::function
av_tx_fn function
Definition: tx_priv.h:201
parity_revtab_generator
static void parity_revtab_generator(int *revtab, int n, int inv, int offset, int is_dual, int dual_high, int len, int basis, int dual_stride, int inv_lookup)
Definition: tx.c:197
ff_tx_decompose_length
int ff_tx_decompose_length(int dst[TX_MAX_DECOMPOSITIONS], enum AVTXType type, int len, int inv)
Definition: tx.c:411
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:375
codelet_list
static const FFTXCodelet *const *const codelet_list[]
Definition: tx.c:339
intmath.h