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 {
598  AVBPrint bp;
600 
601  av_bprintf(&bp, "%s - type: ", cd->name);
602 
603  print_type(&bp, cd->type);
604 
605  av_bprintf(&bp, ", len: ");
606  if (!len) {
607  if (cd->min_len != cd->max_len)
608  av_bprintf(&bp, "[%i, ", cd->min_len);
609 
610  if (cd->max_len == TX_LEN_UNLIMITED)
611  av_bprintf(&bp, "∞");
612  else
613  av_bprintf(&bp, "%i", cd->max_len);
614  } else {
615  av_bprintf(&bp, "%i", len);
616  }
617 
618  if (cd->factors[1]) {
619  av_bprintf(&bp, "%s, factors", !len && cd->min_len != cd->max_len ? "]" : "");
620  if (!cd->nb_factors)
621  av_bprintf(&bp, ": [");
622  else
623  av_bprintf(&bp, "[%i]: [", cd->nb_factors);
624 
625  for (int i = 0; i < TX_MAX_FACTORS; i++) {
626  if (i && cd->factors[i])
627  av_bprintf(&bp, ", ");
628  if (cd->factors[i] == TX_FACTOR_ANY)
629  av_bprintf(&bp, "any");
630  else if (cd->factors[i])
631  av_bprintf(&bp, "%i", cd->factors[i]);
632  else
633  break;
634  }
635 
636  av_bprintf(&bp, "], ");
637  } else {
638  av_bprintf(&bp, "%s, factor: %i, ",
639  !len && cd->min_len != cd->max_len ? "]" : "", cd->factors[0]);
640  }
641  print_flags(&bp, cd->flags);
642 
643  if (print_prio)
644  av_bprintf(&bp, ", prio: %i", prio);
645 
646  av_log(NULL, AV_LOG_DEBUG, "%s\n", bp.str);
647 }
648 
649 static void print_tx_structure(AVTXContext *s, int depth)
650 {
651  const FFTXCodelet *cd = s->cd_self;
652 
653  for (int i = 0; i <= depth; i++)
654  av_log(NULL, AV_LOG_DEBUG, " ");
655 
656  print_cd_info(cd, cd->prio, s->len, 0);
657 
658  for (int i = 0; i < s->nb_sub; i++)
659  print_tx_structure(&s->sub[i], depth + 1);
660 }
661 #endif /* CONFIG_SMALL */
662 
663 typedef struct TXCodeletMatch {
664  const FFTXCodelet *cd;
665  int prio;
667 
669 {
670  return FFDIFFSIGN(b->prio, a->prio);
671 }
672 
673 /* We want all factors to completely cover the length */
674 static inline int check_cd_factors(const FFTXCodelet *cd, int len)
675 {
676  int matches = 0, any_flag = 0;
677 
678  for (int i = 0; i < TX_MAX_FACTORS; i++) {
679  int factor = cd->factors[i];
680 
681  if (factor == TX_FACTOR_ANY) {
682  any_flag = 1;
683  matches++;
684  continue;
685  } else if (len <= 1 || !factor) {
686  break;
687  } else if (factor == 2) { /* Fast path */
688  int bits_2 = ff_ctz(len);
689  if (!bits_2)
690  continue; /* Factor not supported */
691 
692  len >>= bits_2;
693  matches++;
694  } else {
695  int res = len % factor;
696  if (res)
697  continue; /* Factor not supported */
698 
699  while (!res) {
700  len /= factor;
701  res = len % factor;
702  }
703  matches++;
704  }
705  }
706 
707  return (cd->nb_factors <= matches) && (any_flag || len == 1);
708 }
709 
711  uint64_t flags, FFTXCodeletOptions *opts,
712  int len, int inv, const void *scale)
713 {
714  int ret = 0;
715  AVTXContext *sub = NULL;
716  TXCodeletMatch *cd_tmp, *cd_matches = NULL;
717  unsigned int cd_matches_size = 0;
718  int codelet_list_idx = codelet_list_num;
719  int nb_cd_matches = 0;
720 #if !CONFIG_SMALL
721  AVBPrint bp;
722 #endif
723 
724  /* We still accept functions marked with SLOW, even if the CPU is
725  * marked with the same flag, but we give them lower priority. */
726  const int cpu_flags = av_get_cpu_flags();
727 
728  /* Flags the transform wants */
729  uint64_t req_flags = flags;
730 
731  /* Flags the codelet may require to be present */
732  uint64_t inv_req_mask = AV_TX_FULL_IMDCT |
737 
738  /* Unaligned codelets are compatible with the aligned flag */
739  if (req_flags & FF_TX_ALIGNED)
740  req_flags |= AV_TX_UNALIGNED;
741 
742  /* If either flag is set, both are okay, so don't check for an exact match */
743  if ((req_flags & AV_TX_INPLACE) && (req_flags & FF_TX_OUT_OF_PLACE))
744  req_flags &= ~(AV_TX_INPLACE | FF_TX_OUT_OF_PLACE);
745  if ((req_flags & FF_TX_ALIGNED) && (req_flags & AV_TX_UNALIGNED))
746  req_flags &= ~(FF_TX_ALIGNED | AV_TX_UNALIGNED);
747 
748  /* Loop through all codelets in all codelet lists to find matches
749  * to the requirements */
750  while (codelet_list_idx--) {
751  const FFTXCodelet * const * list = codelet_list[codelet_list_idx];
752  const FFTXCodelet *cd = NULL;
753 
754  while ((cd = *list++)) {
755  /* Check if the type matches */
756  if (cd->type != TX_TYPE_ANY && type != cd->type)
757  continue;
758 
759  /* Check direction for non-orthogonal codelets */
760  if (((cd->flags & FF_TX_FORWARD_ONLY) && inv) ||
761  ((cd->flags & (FF_TX_INVERSE_ONLY | AV_TX_FULL_IMDCT)) && !inv) ||
762  ((cd->flags & (FF_TX_FORWARD_ONLY | AV_TX_REAL_TO_REAL)) && inv) ||
763  ((cd->flags & (FF_TX_FORWARD_ONLY | AV_TX_REAL_TO_IMAGINARY)) && inv))
764  continue;
765 
766  /* Check if the requested flags match from both sides */
767  if (((req_flags & cd->flags) != (req_flags)) ||
768  ((inv_req_mask & cd->flags) != (req_flags & inv_req_mask)))
769  continue;
770 
771  /* Check if length is supported */
772  if ((len < cd->min_len) || (cd->max_len != -1 && (len > cd->max_len)))
773  continue;
774 
775  /* Check if the CPU supports the required ISA */
776  if (cd->cpu_flags != FF_TX_CPU_FLAGS_ALL &&
777  !(cpu_flags & (cd->cpu_flags & ~cpu_slow_mask)))
778  continue;
779 
780  /* Check for factors */
781  if (!check_cd_factors(cd, len))
782  continue;
783 
784  /* Realloc array and append */
785  cd_tmp = av_fast_realloc(cd_matches, &cd_matches_size,
786  sizeof(*cd_tmp) * (nb_cd_matches + 1));
787  if (!cd_tmp) {
788  av_free(cd_matches);
789  return AVERROR(ENOMEM);
790  }
791 
792  cd_matches = cd_tmp;
793  cd_matches[nb_cd_matches].cd = cd;
794  cd_matches[nb_cd_matches].prio = get_codelet_prio(cd, cpu_flags, len);
795  nb_cd_matches++;
796  }
797  }
798 
799 #if !CONFIG_SMALL
800  /* Print debugging info */
802  av_bprintf(&bp, "For transform of length %i, %s, ", len,
803  inv ? "inverse" : "forward");
804  print_type(&bp, type);
805  av_bprintf(&bp, ", ");
806  print_flags(&bp, flags);
807  av_bprintf(&bp, ", found %i matches%s", nb_cd_matches,
808  nb_cd_matches ? ":" : ".");
809 #endif
810 
811  /* No matches found */
812  if (!nb_cd_matches)
813  return AVERROR(ENOSYS);
814 
815  /* Sort the list */
816  AV_QSORT(cd_matches, nb_cd_matches, TXCodeletMatch, cmp_matches);
817 
818 #if !CONFIG_SMALL
819  av_log(NULL, AV_LOG_DEBUG, "%s\n", bp.str);
820 
821  for (int i = 0; i < nb_cd_matches; i++) {
822  av_log(NULL, AV_LOG_DEBUG, " %i: ", i + 1);
823  print_cd_info(cd_matches[i].cd, cd_matches[i].prio, 0, 1);
824  }
825 #endif
826 
827  if (!s->sub) {
828  s->sub = sub = av_mallocz(TX_MAX_SUB*sizeof(*sub));
829  if (!sub) {
830  ret = AVERROR(ENOMEM);
831  goto end;
832  }
833  }
834 
835  /* Attempt to initialize each */
836  for (int i = 0; i < nb_cd_matches; i++) {
837  const FFTXCodelet *cd = cd_matches[i].cd;
838  AVTXContext *sctx = &s->sub[s->nb_sub];
839 
840  sctx->len = len;
841  sctx->inv = inv;
842  sctx->type = type;
843  sctx->flags = cd->flags | flags;
844  sctx->cd_self = cd;
845 
846  s->fn[s->nb_sub] = cd->function;
847  s->cd[s->nb_sub] = cd;
848 
849  ret = 0;
850  if (cd->init)
851  ret = cd->init(sctx, cd, flags, opts, len, inv, scale);
852 
853  if (ret >= 0) {
854  if (opts && opts->map_dir != FF_TX_MAP_NONE &&
855  sctx->map_dir == FF_TX_MAP_NONE) {
856  /* If a specific map direction was requested, and it doesn't
857  * exist, create one.*/
858  sctx->map = av_malloc(len*sizeof(*sctx->map));
859  if (!sctx->map) {
860  ret = AVERROR(ENOMEM);
861  goto end;
862  }
863 
864  for (int i = 0; i < len; i++)
865  sctx->map[i] = i;
866  } else if (opts && (opts->map_dir != sctx->map_dir)) {
867  int *tmp = av_malloc(len*sizeof(*sctx->map));
868  if (!tmp) {
869  ret = AVERROR(ENOMEM);
870  goto end;
871  }
872 
873  memcpy(tmp, sctx->map, len*sizeof(*sctx->map));
874 
875  for (int i = 0; i < len; i++)
876  sctx->map[tmp[i]] = i;
877 
878  av_free(tmp);
879  }
880 
881  s->nb_sub++;
882  goto end;
883  }
884 
885  s->fn[s->nb_sub] = NULL;
886  s->cd[s->nb_sub] = NULL;
887 
888  reset_ctx(sctx, 0);
889  if (ret == AVERROR(ENOMEM))
890  break;
891  }
892 
893  if (!s->nb_sub)
894  av_freep(&s->sub);
895 
896 end:
897  av_free(cd_matches);
898  return ret;
899 }
900 
902  int inv, int len, const void *scale, uint64_t flags)
903 {
904  int ret;
905  AVTXContext tmp = { 0 };
906  const double default_scale_d = 1.0;
907  const float default_scale_f = 1.0f;
908 
909  if (!len || type >= AV_TX_NB || !ctx || !tx)
910  return AVERROR(EINVAL);
911 
912  if (!(flags & AV_TX_UNALIGNED))
913  flags |= FF_TX_ALIGNED;
914  if (!(flags & AV_TX_INPLACE))
916 
917  if (!scale && ((type == AV_TX_FLOAT_MDCT) || (type == AV_TX_INT32_MDCT)))
918  scale = &default_scale_f;
919  else if (!scale && (type == AV_TX_DOUBLE_MDCT))
920  scale = &default_scale_d;
921 
922  ret = ff_tx_init_subtx(&tmp, type, flags, NULL, len, inv, scale);
923  if (ret < 0)
924  return ret;
925 
926  *ctx = &tmp.sub[0];
927  *tx = tmp.fn[0];
928 
929 #if !CONFIG_SMALL
930  av_log(NULL, AV_LOG_DEBUG, "Transform tree:\n");
931  print_tx_structure(*ctx, 0);
932 #endif
933 
934  return ret;
935 }
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:663
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
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
print_cd_info
static void print_cd_info(const FFTXCodelet *cd, int prio, int len, int print_prio)
Definition: tx.c:596
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:668
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:901
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
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
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1389
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
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:664
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:665
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
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:710
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:674
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:649
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