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 "cpu.h"
20 #include "qsort.h"
21 #include "bprint.h"
22 
23 #include "tx_priv.h"
24 
25 #define TYPE_IS(type, x) \
26  (((x) == AV_TX_FLOAT_ ## type) || \
27  ((x) == AV_TX_DOUBLE_ ## type) || \
28  ((x) == AV_TX_INT32_ ## type))
29 
30 /* Calculates the modular multiplicative inverse */
31 static av_always_inline int mulinv(int n, int m)
32 {
33  n = n % m;
34  for (int x = 1; x < m; x++)
35  if (((n * x) % m) == 1)
36  return x;
37  av_assert0(0); /* Never reached */
38  return 0;
39 }
40 
41 /* Guaranteed to work for any n, m where gcd(n, m) == 1 */
43 {
44  int *in_map, *out_map;
45  const int inv = s->inv;
46  const int len = n*m; /* Will not be equal to s->len for MDCTs */
47  const int mdct = TYPE_IS(MDCT, s->type);
48  int m_inv, n_inv;
49 
50  /* Make sure the numbers are coprime */
51  if (av_gcd(n, m) != 1)
52  return AVERROR(EINVAL);
53 
54  m_inv = mulinv(m, n);
55  n_inv = mulinv(n, m);
56 
57  if (!(s->map = av_malloc(2*len*sizeof(*s->map))))
58  return AVERROR(ENOMEM);
59 
60  in_map = s->map;
61  out_map = s->map + len;
62 
63  /* Ruritanian map for input, CRT map for output, can be swapped */
64  for (int j = 0; j < m; j++) {
65  for (int i = 0; i < n; i++) {
66  /* Shifted by 1 to simplify MDCTs */
67  in_map[j*n + i] = ((i*m + j*n) % len) << mdct;
68  out_map[(i*m*m_inv + j*n*n_inv) % len] = i*m + j;
69  }
70  }
71 
72  /* Change transform direction by reversing all ACs */
73  if (inv) {
74  for (int i = 0; i < m; i++) {
75  int *in = &in_map[i*n + 1]; /* Skip the DC */
76  for (int j = 0; j < ((n - 1) >> 1); j++)
77  FFSWAP(int, in[j], in[n - j - 2]);
78  }
79  }
80 
81  /* Our 15-point transform is also a compound one, so embed its input map */
82  if (n == 15) {
83  for (int k = 0; k < m; k++) {
84  int tmp[15];
85  memcpy(tmp, &in_map[k*15], 15*sizeof(*tmp));
86  for (int i = 0; i < 5; i++) {
87  for (int j = 0; j < 3; j++)
88  in_map[k*15 + i*3 + j] = tmp[(i*3 + j*5) % 15];
89  }
90  }
91  }
92 
93  return 0;
94 }
95 
96 static inline int split_radix_permutation(int i, int len, int inv)
97 {
98  len >>= 1;
99  if (len <= 1)
100  return i & 1;
101  if (!(i & len))
102  return split_radix_permutation(i, len, inv) * 2;
103  len >>= 1;
104  return split_radix_permutation(i, len, inv) * 4 + 1 - 2*(!(i & len) ^ inv);
105 }
106 
107 int ff_tx_gen_ptwo_revtab(AVTXContext *s, int invert_lookup)
108 {
109  int len = s->len;
110 
111  if (!(s->map = av_malloc(len*sizeof(*s->map))))
112  return AVERROR(ENOMEM);
113 
114  if (invert_lookup) {
115  for (int i = 0; i < s->len; i++)
116  s->map[i] = -split_radix_permutation(i, len, s->inv) & (len - 1);
117  } else {
118  for (int i = 0; i < s->len; i++)
119  s->map[-split_radix_permutation(i, len, s->inv) & (len - 1)] = i;
120  }
121 
122  return 0;
123 }
124 
126 {
127  int *src_map, out_map_idx = 0, len = s->len;
128 
129  if (!s->sub || !s->sub->map)
130  return AVERROR(EINVAL);
131 
132  if (!(s->map = av_mallocz(len*sizeof(*s->map))))
133  return AVERROR(ENOMEM);
134 
135  src_map = s->sub->map;
136 
137  /* The first coefficient is always already in-place */
138  for (int src = 1; src < s->len; src++) {
139  int dst = src_map[src];
140  int found = 0;
141 
142  if (dst <= src)
143  continue;
144 
145  /* This just checks if a closed loop has been encountered before,
146  * and if so, skips it, since to fully permute a loop we must only
147  * enter it once. */
148  do {
149  for (int j = 0; j < out_map_idx; j++) {
150  if (dst == s->map[j]) {
151  found = 1;
152  break;
153  }
154  }
155  dst = src_map[dst];
156  } while (dst != src && !found);
157 
158  if (!found)
159  s->map[out_map_idx++] = src;
160  }
161 
162  s->map[out_map_idx++] = 0;
163 
164  return 0;
165 }
166 
167 static void parity_revtab_generator(int *revtab, int n, int inv, int offset,
168  int is_dual, int dual_high, int len,
169  int basis, int dual_stride, int inv_lookup)
170 {
171  len >>= 1;
172 
173  if (len <= basis) {
174  int k1, k2, stride, even_idx, odd_idx;
175 
176  is_dual = is_dual && dual_stride;
177  dual_high = is_dual & dual_high;
178  stride = is_dual ? FFMIN(dual_stride, len) : 0;
179 
180  even_idx = offset + dual_high*(stride - 2*len);
181  odd_idx = even_idx + len + (is_dual && !dual_high)*len + dual_high*len;
182 
183  for (int i = 0; i < len; i++) {
184  k1 = -split_radix_permutation(offset + i*2 + 0, n, inv) & (n - 1);
185  k2 = -split_radix_permutation(offset + i*2 + 1, n, inv) & (n - 1);
186  if (inv_lookup) {
187  revtab[even_idx++] = k1;
188  revtab[odd_idx++] = k2;
189  } else {
190  revtab[k1] = even_idx++;
191  revtab[k2] = odd_idx++;
192  }
193  if (stride && !((i + 1) % stride)) {
194  even_idx += stride;
195  odd_idx += stride;
196  }
197  }
198 
199  return;
200  }
201 
202  parity_revtab_generator(revtab, n, inv, offset,
203  0, 0, len >> 0, basis, dual_stride, inv_lookup);
204  parity_revtab_generator(revtab, n, inv, offset + (len >> 0),
205  1, 0, len >> 1, basis, dual_stride, inv_lookup);
206  parity_revtab_generator(revtab, n, inv, offset + (len >> 0) + (len >> 1),
207  1, 1, len >> 1, basis, dual_stride, inv_lookup);
208 }
209 
211  int basis, int dual_stride)
212 {
213  int len = s->len;
214  int inv = s->inv;
215 
216  if (!(s->map = av_mallocz(len*sizeof(*s->map))))
217  return AVERROR(ENOMEM);
218 
219  basis >>= 1;
220  if (len < basis)
221  return AVERROR(EINVAL);
222 
223  av_assert0(!dual_stride || !(dual_stride & (dual_stride - 1)));
224  av_assert0(dual_stride <= basis);
225  parity_revtab_generator(s->map, len, inv, 0, 0, 0, len,
226  basis, dual_stride, invert_lookup);
227 
228  return 0;
229 }
230 
231 static void reset_ctx(AVTXContext *s)
232 {
233  if (!s)
234  return;
235 
236  if (s->sub)
237  for (int i = 0; i < s->nb_sub; i++)
238  reset_ctx(&s->sub[i]);
239 
240  if (s->cd_self->uninit)
241  s->cd_self->uninit(s);
242 
243  av_freep(&s->sub);
244  av_freep(&s->map);
245  av_freep(&s->exp);
246  av_freep(&s->tmp);
247 
248  memset(s, 0, sizeof(*s));
249 }
250 
252 {
253  if (!(*ctx))
254  return;
255 
256  reset_ctx(*ctx);
257  av_freep(ctx);
258 }
259 
261  uint64_t flags, FFTXCodeletOptions *opts,
262  int len, int inv, const void *scale)
263 {
264  /* Can only handle one sample+type to one sample+type transforms */
265  if (TYPE_IS(MDCT, s->type) || TYPE_IS(RDFT, s->type))
266  return AVERROR(EINVAL);
267  return 0;
268 }
269 
270 /* Null transform when the length is 1 */
271 static void ff_tx_null(AVTXContext *s, void *_out, void *_in, ptrdiff_t stride)
272 {
273  memcpy(_out, _in, stride);
274 }
275 
276 static const FFTXCodelet ff_tx_null_def = {
277  .name = NULL_IF_CONFIG_SMALL("null"),
278  .function = ff_tx_null,
279  .type = TX_TYPE_ANY,
280  .flags = AV_TX_UNALIGNED | FF_TX_ALIGNED |
282  .factors[0] = TX_FACTOR_ANY,
283  .min_len = 1,
284  .max_len = 1,
285  .init = ff_tx_null_init,
286  .cpu_flags = FF_TX_CPU_FLAGS_ALL,
287  .prio = FF_TX_PRIO_MAX,
288 };
289 
290 static const FFTXCodelet * const ff_tx_null_list[] = {
292  NULL,
293 };
294 
295 #if !CONFIG_SMALL
296 static void print_flags(AVBPrint *bp, uint64_t f)
297 {
298  int prev = 0;
299  const char *sep = ", ";
300  av_bprintf(bp, "flags: [");
301  if ((f & FF_TX_ALIGNED) && ++prev)
302  av_bprintf(bp, "aligned");
303  if ((f & AV_TX_UNALIGNED) && ++prev)
304  av_bprintf(bp, "%sunaligned", prev > 1 ? sep : "");
305  if ((f & AV_TX_INPLACE) && ++prev)
306  av_bprintf(bp, "%sinplace", prev > 1 ? sep : "");
307  if ((f & FF_TX_OUT_OF_PLACE) && ++prev)
308  av_bprintf(bp, "%sout_of_place", prev > 1 ? sep : "");
309  if ((f & FF_TX_FORWARD_ONLY) && ++prev)
310  av_bprintf(bp, "%sfwd_only", prev > 1 ? sep : "");
311  if ((f & FF_TX_INVERSE_ONLY) && ++prev)
312  av_bprintf(bp, "%sinv_only", prev > 1 ? sep : "");
313  if ((f & FF_TX_PRESHUFFLE) && ++prev)
314  av_bprintf(bp, "%spreshuf", prev > 1 ? sep : "");
315  if ((f & AV_TX_FULL_IMDCT) && ++prev)
316  av_bprintf(bp, "%simdct_full", prev > 1 ? sep : "");
317  av_bprintf(bp, "]");
318 }
319 
320 static void print_type(AVBPrint *bp, enum AVTXType type)
321 {
322  av_bprintf(bp, "%s",
323  type == TX_TYPE_ANY ? "any" :
324  type == AV_TX_FLOAT_FFT ? "fft_float" :
325  type == AV_TX_FLOAT_MDCT ? "mdct_float" :
326  type == AV_TX_FLOAT_RDFT ? "rdft_float" :
327  type == AV_TX_DOUBLE_FFT ? "fft_double" :
328  type == AV_TX_DOUBLE_MDCT ? "mdct_double" :
329  type == AV_TX_DOUBLE_RDFT ? "rdft_double" :
330  type == AV_TX_INT32_FFT ? "fft_int32" :
331  type == AV_TX_INT32_MDCT ? "mdct_int32" :
332  type == AV_TX_INT32_RDFT ? "rdft_int32" :
333  "unknown");
334 }
335 
336 static void print_cd_info(const FFTXCodelet *cd, int prio, int print_prio)
337 {
338  AVBPrint bp = { 0 };
340 
341  av_bprintf(&bp, "%s - type: ", cd->name);
342 
343  print_type(&bp, cd->type);
344 
345  av_bprintf(&bp, ", len: ");
346  if (cd->min_len != cd->max_len)
347  av_bprintf(&bp, "[%i, ", cd->min_len);
348 
349  if (cd->max_len == TX_LEN_UNLIMITED)
350  av_bprintf(&bp, "∞");
351  else
352  av_bprintf(&bp, "%i", cd->max_len);
353 
354  av_bprintf(&bp, "%s, factors: [", cd->min_len != cd->max_len ? "]" : "");
355  for (int i = 0; i < TX_MAX_SUB; i++) {
356  if (i && cd->factors[i])
357  av_bprintf(&bp, ", ");
358  if (cd->factors[i] == TX_FACTOR_ANY)
359  av_bprintf(&bp, "any");
360  else if (cd->factors[i])
361  av_bprintf(&bp, "%i", cd->factors[i]);
362  else
363  break;
364  }
365 
366  av_bprintf(&bp, "], ");
367  print_flags(&bp, cd->flags);
368 
369  if (print_prio)
370  av_bprintf(&bp, ", prio: %i", prio);
371 
372  av_log(NULL, AV_LOG_VERBOSE, "%s\n", bp.str);
373 }
374 
375 static void print_tx_structure(AVTXContext *s, int depth)
376 {
377  const FFTXCodelet *cd = s->cd_self;
378 
379  for (int i = 0; i <= depth; i++)
380  av_log(NULL, AV_LOG_VERBOSE, " ");
381 
382  print_cd_info(cd, cd->prio, 0);
383 
384  for (int i = 0; i < s->nb_sub; i++)
385  print_tx_structure(&s->sub[i], depth + 1);
386 }
387 #endif /* CONFIG_SMALL */
388 
389 typedef struct TXCodeletMatch {
390  const FFTXCodelet *cd;
391  int prio;
393 
395 {
396  return FFDIFFSIGN(b->prio, a->prio);
397 }
398 
399 /* We want all factors to completely cover the length */
400 static inline int check_cd_factors(const FFTXCodelet *cd, int len)
401 {
402  int all_flag = 0;
403 
404  for (int i = 0; i < TX_MAX_SUB; i++) {
405  int factor = cd->factors[i];
406 
407  /* Conditions satisfied */
408  if (len == 1)
409  return 1;
410 
411  /* No more factors */
412  if (!factor) {
413  break;
414  } else if (factor == TX_FACTOR_ANY) {
415  all_flag = 1;
416  continue;
417  }
418 
419  if (factor == 2) { /* Fast path */
420  int bits_2 = ff_ctz(len);
421  if (!bits_2)
422  return 0; /* Factor not supported */
423 
424  len >>= bits_2;
425  } else {
426  int res = len % factor;
427  if (res)
428  return 0; /* Factor not supported */
429 
430  while (!res) {
431  len /= factor;
432  res = len % factor;
433  }
434  }
435  }
436 
437  return all_flag || (len == 1);
438 }
439 
441  uint64_t flags, FFTXCodeletOptions *opts,
442  int len, int inv, const void *scale)
443 {
444  int ret = 0;
445  AVTXContext *sub = NULL;
446  TXCodeletMatch *cd_tmp, *cd_matches = NULL;
447  unsigned int cd_matches_size = 0;
448  int nb_cd_matches = 0;
449 #if !CONFIG_SMALL
450  AVBPrint bp = { 0 };
451 #endif
452 
453  /* Array of all compiled codelet lists. Order is irrelevant. */
454  const FFTXCodelet * const * const codelet_list[] = {
459 #if HAVE_X86ASM
461 #endif
462  };
463  int codelet_list_num = FF_ARRAY_ELEMS(codelet_list);
464 
465  /* We still accept functions marked with SLOW, even if the CPU is
466  * marked with the same flag, but we give them lower priority. */
467  const int cpu_flags = av_get_cpu_flags();
468  const int slow_mask = AV_CPU_FLAG_SSE2SLOW | AV_CPU_FLAG_SSE3SLOW |
471 
472  /* Flags the transform wants */
473  uint64_t req_flags = flags;
474 
475  /* Flags the codelet may require to be present */
476  uint64_t inv_req_mask = AV_TX_FULL_IMDCT | FF_TX_PRESHUFFLE;
477 
478  /* Unaligned codelets are compatible with the aligned flag */
479  if (req_flags & FF_TX_ALIGNED)
480  req_flags |= AV_TX_UNALIGNED;
481 
482  /* If either flag is set, both are okay, so don't check for an exact match */
483  if ((req_flags & AV_TX_INPLACE) && (req_flags & FF_TX_OUT_OF_PLACE))
484  req_flags &= ~(AV_TX_INPLACE | FF_TX_OUT_OF_PLACE);
485  if ((req_flags & FF_TX_ALIGNED) && (req_flags & AV_TX_UNALIGNED))
486  req_flags &= ~(FF_TX_ALIGNED | AV_TX_UNALIGNED);
487 
488  /* Loop through all codelets in all codelet lists to find matches
489  * to the requirements */
490  while (codelet_list_num--) {
491  const FFTXCodelet * const * list = codelet_list[codelet_list_num];
492  const FFTXCodelet *cd = NULL;
493 
494  while ((cd = *list++)) {
495  int max_factor = 0;
496 
497  /* Check if the type matches */
498  if (cd->type != TX_TYPE_ANY && type != cd->type)
499  continue;
500 
501  /* Check direction for non-orthogonal codelets */
502  if (((cd->flags & FF_TX_FORWARD_ONLY) && inv) ||
503  ((cd->flags & (FF_TX_INVERSE_ONLY | AV_TX_FULL_IMDCT)) && !inv))
504  continue;
505 
506  /* Check if the requested flags match from both sides */
507  if (((req_flags & cd->flags) != (req_flags)) ||
508  ((inv_req_mask & cd->flags) != (req_flags & inv_req_mask)))
509  continue;
510 
511  /* Check if length is supported */
512  if ((len < cd->min_len) || (cd->max_len != -1 && (len > cd->max_len)))
513  continue;
514 
515  /* Check if the CPU supports the required ISA */
516  if (cd->cpu_flags != FF_TX_CPU_FLAGS_ALL &&
517  !(cpu_flags & (cd->cpu_flags & ~slow_mask)))
518  continue;
519 
520  /* Check for factors */
521  if (!check_cd_factors(cd, len))
522  continue;
523 
524  /* Realloc array and append */
525  cd_tmp = av_fast_realloc(cd_matches, &cd_matches_size,
526  sizeof(*cd_tmp) * (nb_cd_matches + 1));
527  if (!cd_tmp) {
528  av_free(cd_matches);
529  return AVERROR(ENOMEM);
530  }
531 
532  cd_matches = cd_tmp;
533  cd_matches[nb_cd_matches].cd = cd;
534  cd_matches[nb_cd_matches].prio = cd->prio;
535 
536  /* If the CPU has a SLOW flag, and the instruction is also flagged
537  * as being slow for such, reduce its priority */
538  if ((cpu_flags & cd->cpu_flags) & slow_mask)
539  cd_matches[nb_cd_matches].prio -= 64;
540 
541  /* Prioritize aligned-only codelets */
542  if ((cd->flags & FF_TX_ALIGNED) && !(cd->flags & AV_TX_UNALIGNED))
543  cd_matches[nb_cd_matches].prio += 64;
544 
545  /* Codelets for specific lengths are generally faster */
546  if ((len == cd->min_len) && (len == cd->max_len))
547  cd_matches[nb_cd_matches].prio += 64;
548 
549  /* Forward-only or inverse-only transforms are generally better */
551  cd_matches[nb_cd_matches].prio += 64;
552 
553  /* Larger factors are generally better */
554  for (int i = 0; i < TX_MAX_SUB; i++)
555  max_factor = FFMAX(cd->factors[i], max_factor);
556  if (max_factor)
557  cd_matches[nb_cd_matches].prio += 16*max_factor;
558 
559  nb_cd_matches++;
560  }
561  }
562 
563 #if !CONFIG_SMALL
564  /* Print debugging info */
566  av_bprintf(&bp, "For transform of length %i, %s, ", len,
567  inv ? "inverse" : "forward");
568  print_type(&bp, type);
569  av_bprintf(&bp, ", ");
570  print_flags(&bp, flags);
571  av_bprintf(&bp, ", found %i matches%s", nb_cd_matches,
572  nb_cd_matches ? ":" : ".");
573 #endif
574 
575  /* No matches found */
576  if (!nb_cd_matches)
577  return AVERROR(ENOSYS);
578 
579  /* Sort the list */
580  AV_QSORT(cd_matches, nb_cd_matches, TXCodeletMatch, cmp_matches);
581 
582 #if !CONFIG_SMALL
583  av_log(NULL, AV_LOG_VERBOSE, "%s\n", bp.str);
584 
585  for (int i = 0; i < nb_cd_matches; i++) {
586  av_log(NULL, AV_LOG_VERBOSE, " %i: ", i + 1);
587  print_cd_info(cd_matches[i].cd, cd_matches[i].prio, 1);
588  }
589 #endif
590 
591  if (!s->sub) {
592  s->sub = sub = av_mallocz(TX_MAX_SUB*sizeof(*sub));
593  if (!sub) {
594  ret = AVERROR(ENOMEM);
595  goto end;
596  }
597  }
598 
599  /* Attempt to initialize each */
600  for (int i = 0; i < nb_cd_matches; i++) {
601  const FFTXCodelet *cd = cd_matches[i].cd;
602  AVTXContext *sctx = &s->sub[s->nb_sub];
603 
604  sctx->len = len;
605  sctx->inv = inv;
606  sctx->type = type;
607  sctx->flags = flags;
608  sctx->cd_self = cd;
609 
610  s->fn[s->nb_sub] = cd->function;
611  s->cd[s->nb_sub] = cd;
612 
613  ret = 0;
614  if (cd->init)
615  ret = cd->init(sctx, cd, flags, opts, len, inv, scale);
616 
617  if (ret >= 0) {
618  s->nb_sub++;
619  goto end;
620  }
621 
622  s->fn[s->nb_sub] = NULL;
623  s->cd[s->nb_sub] = NULL;
624 
625  reset_ctx(sctx);
626  if (ret == AVERROR(ENOMEM))
627  break;
628  }
629 
630  if (!s->nb_sub)
631  av_freep(&s->sub);
632 
633 end:
634  av_free(cd_matches);
635  return ret;
636 }
637 
639  int inv, int len, const void *scale, uint64_t flags)
640 {
641  int ret;
642  AVTXContext tmp = { 0 };
643  const double default_scale_d = 1.0;
644  const float default_scale_f = 1.0f;
645 
646  if (!len || type >= AV_TX_NB || !ctx || !tx)
647  return AVERROR(EINVAL);
648 
649  if (!(flags & AV_TX_UNALIGNED))
650  flags |= FF_TX_ALIGNED;
651  if (!(flags & AV_TX_INPLACE))
653 
654  if (!scale && ((type == AV_TX_FLOAT_MDCT) || (type == AV_TX_INT32_MDCT)))
655  scale = &default_scale_f;
656  else if (!scale && (type == AV_TX_DOUBLE_MDCT))
657  scale = &default_scale_d;
658 
659  ret = ff_tx_init_subtx(&tmp, type, flags, NULL, len, inv, scale);
660  if (ret < 0)
661  return ret;
662 
663  *ctx = &tmp.sub[0];
664  *tx = tmp.fn[0];
665 
666 #if !CONFIG_SMALL
667  av_log(NULL, AV_LOG_VERBOSE, "Transform tree:\n");
668  print_tx_structure(*ctx, 0);
669 #endif
670 
671  return ret;
672 }
AV_TX_DOUBLE_MDCT
@ AV_TX_DOUBLE_MDCT
Definition: tx.h:69
AV_CPU_FLAG_SSSE3SLOW
#define AV_CPU_FLAG_SSSE3SLOW
SSSE3 supported, but usually not faster.
Definition: cpu.h:42
ff_tx_gen_ptwo_inplace_revtab_idx
int ff_tx_gen_ptwo_inplace_revtab_idx(AVTXContext *s)
Definition: tx.c:125
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:106
TXCodeletMatch
Definition: tx.c:389
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
sub
static float sub(float src0, float src1)
Definition: dnn_backend_native_layer_mathbinary.c:31
AV_CPU_FLAG_SSE3SLOW
#define AV_CPU_FLAG_SSE3SLOW
SSE3 supported, but usually not faster.
Definition: cpu.h:39
AVTXContext
Definition: tx_priv.h:201
ff_tx_null_def
static const FFTXCodelet ff_tx_null_def
Definition: tx.c:276
basis
static int16_t basis[64][64]
Definition: mpegvideo_enc.c:4090
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
FFTXCodeletOptions
Definition: tx_priv.h:160
ff_tx_gen_compound_mapping
int ff_tx_gen_compound_mapping(AVTXContext *s, int n, int m)
Definition: tx.c:42
b
#define b
Definition: input.c:34
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
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:100
FF_TX_CPU_FLAGS_ALL
#define FF_TX_CPU_FLAGS_ALL
Definition: tx_priv.h:196
print_type
static void print_type(AVBPrint *bp, enum AVTXType type)
Definition: tx.c:320
cpu_flags
static atomic_int cpu_flags
Definition: cpu.c:52
cmp_matches
static int cmp_matches(TXCodeletMatch *a, TXCodeletMatch *b)
Definition: tx.c:394
print_flags
static void print_flags(AVBPrint *bp, uint64_t f)
Definition: tx.c:296
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:638
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
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:260
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
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1388
TX_MAX_SUB
#define TX_MAX_SUB
Definition: tx_priv.h:166
FFTXCodelet::min_len
int min_len
Definition: tx_priv.h:180
FF_TX_ALIGNED
#define FF_TX_ALIGNED
Definition: tx_priv.h:144
FFTXCodelet::type
enum AVTXType type
Definition: tx_priv.h:171
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
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:93
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:111
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:505
s
#define s(width, name)
Definition: cbs_vp9.c:256
print_cd_info
static void print_cd_info(const FFTXCodelet *cd, int prio, int print_prio)
Definition: tx.c:336
FFTXCodelet::flags
uint64_t flags
Definition: tx_priv.h:174
FFTXCodelet::prio
int prio
Definition: tx_priv.h:198
AV_TX_INT32_MDCT
@ AV_TX_INT32_MDCT
Definition: tx.h:70
AVTXContext::type
enum AVTXType type
Definition: tx_priv.h:222
ff_tx_gen_split_radix_parity_revtab
int ff_tx_gen_split_radix_parity_revtab(AVTXContext *s, int invert_lookup, int basis, int dual_stride)
Definition: tx.c:210
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
FF_TX_FORWARD_ONLY
#define FF_TX_FORWARD_ONLY
Definition: tx_priv.h:147
AVTXContext::len
int len
Definition: tx_priv.h:204
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:96
ctx
AVFormatContext * ctx
Definition: movenc.c:48
FFTXCodelet::cpu_flags
int cpu_flags
Definition: tx_priv.h:193
TX_TYPE_ANY
#define TX_TYPE_ANY
Definition: tx_priv.h:172
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:136
reset_ctx
static void reset_ctx(AVTXContext *s)
Definition: tx.c:231
opts
AVDictionary * opts
Definition: movenc.c:50
TXCodeletMatch::cd
const FFTXCodelet * cd
Definition: tx.c:390
NULL
#define NULL
Definition: coverity.c:32
AV_TX_INPLACE
@ AV_TX_INPLACE
Performs an in-place transformation on the input.
Definition: tx.h:122
ff_tx_null
static void ff_tx_null(AVTXContext *s, void *_out, void *_in, ptrdiff_t stride)
Definition: tx.c:271
FF_TX_OUT_OF_PLACE
#define FF_TX_OUT_OF_PLACE
Definition: tx_priv.h:143
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:156
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:184
AV_TX_UNALIGNED
@ AV_TX_UNALIGNED
Relaxes alignment requirement for the in and out arrays of av_tx_fn().
Definition: tx.h:128
TXCodeletMatch::prio
int prio
Definition: tx.c:391
qsort.h
FF_TX_PRESHUFFLE
#define FF_TX_PRESHUFFLE
Definition: tx_priv.h:145
f
f
Definition: af_crystalizer.c:122
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:116
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
AV_CPU_FLAG_SSE2SLOW
#define AV_CPU_FLAG_SSE2SLOW
SSE2 supported, but usually not faster.
Definition: cpu.h:35
ff_tx_codelet_list_double_c
const FFTXCodelet *const ff_tx_codelet_list_double_c[]
AV_TX_INT32_FFT
@ AV_TX_INT32_FFT
Definition: tx.h:49
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
AVTXContext::inv
int inv
Definition: tx_priv.h:205
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:251
FFTXCodelet::max_len
int max_len
Definition: tx_priv.h:181
bprint.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
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
ff_tx_gen_ptwo_revtab
int ff_tx_gen_ptwo_revtab(AVTXContext *s, int invert_lookup)
Definition: tx.c:107
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:89
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:264
len
int len
Definition: vorbis_enc_data.h:426
TX_LEN_UNLIMITED
#define TX_LEN_UNLIMITED
Definition: tx_priv.h:182
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
AVTXContext::flags
uint64_t flags
Definition: tx_priv.h:223
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:440
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
TX_FACTOR_ANY
#define TX_FACTOR_ANY
Definition: tx_priv.h:178
FF_TX_INVERSE_ONLY
#define FF_TX_INVERSE_ONLY
Definition: tx_priv.h:146
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
ff_tx_codelet_list_float_c
const FFTXCodelet *const ff_tx_codelet_list_float_c[]
AV_TX_FLOAT_RDFT
@ AV_TX_FLOAT_RDFT
Real to complex and complex to real DFTs.
Definition: tx.h:88
FFTXCodelet
Definition: tx_priv.h:168
check_cd_factors
static int check_cd_factors(const FFTXCodelet *cd, int len)
Definition: tx.c:400
AV_TX_INT32_RDFT
@ AV_TX_INT32_RDFT
Definition: tx.h:90
AVTXContext::cd_self
const FFTXCodelet * cd_self
Definition: tx_priv.h:221
FFTXCodelet::name
const char * name
Definition: tx_priv.h:169
factor
static const int factor[16]
Definition: vf_pp7.c:76
ff_tx_codelet_list_float_x86
const FFTXCodelet *const ff_tx_codelet_list_float_x86[]
Definition: tx_float_init.c:66
print_tx_structure
static void print_tx_structure(AVTXContext *s, int depth)
Definition: tx.c:375
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:290
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
mulinv
static av_always_inline int mulinv(int n, int m)
Definition: tx.c:31
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
FFTXCodelet::factors
int factors[TX_MAX_SUB]
Definition: tx_priv.h:177
TYPE_IS
#define TYPE_IS(type, x)
Definition: tx.c:25
FFTXCodelet::function
av_tx_fn function
Definition: tx_priv.h:170
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:167