FFmpeg
fft.c
Go to the documentation of this file.
1 /*
2  * (c) 2002 Fabrice Bellard
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * FFT and MDCT tests.
24  */
25 
26 #include "config.h"
27 
28 #ifndef AVFFT
29 #define AVFFT 0
30 #endif
31 
32 #include <math.h>
33 #if HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 
40 #include "libavutil/cpu.h"
41 #include "libavutil/error.h"
42 #include "libavutil/lfg.h"
43 #include "libavutil/log.h"
44 #include "libavutil/mathematics.h"
45 #include "libavutil/time.h"
46 
47 #if AVFFT
48 #include "libavcodec/avfft.h"
49 #else
50 #include "libavcodec/fft.h"
51 #endif
52 
53 #if FFT_FLOAT
54 #include "libavcodec/dct.h"
55 #include "libavcodec/rdft.h"
56 #endif
57 
58 /* reference fft */
59 
60 #define MUL16(a, b) ((a) * (b))
61 
62 #define CMAC(pre, pim, are, aim, bre, bim) \
63  { \
64  pre += (MUL16(are, bre) - MUL16(aim, bim)); \
65  pim += (MUL16(are, bim) + MUL16(bre, aim)); \
66  }
67 
68 #if FFT_FLOAT || AVFFT
69 #define RANGE 1.0
70 #define REF_SCALE(x, bits) (x)
71 #define FMT "%10.6f"
72 #else
73 #define RANGE 8388608
74 #define REF_SCALE(x, bits) (x)
75 #define FMT "%6d"
76 #endif
77 
78 static struct {
79  float re, im;
80 } *exptab;
81 
82 static int fft_ref_init(int nbits, int inverse)
83 {
84  int i, n = 1 << nbits;
85 
86  exptab = av_malloc_array((n / 2), sizeof(*exptab));
87  if (!exptab)
88  return AVERROR(ENOMEM);
89 
90  for (i = 0; i < (n / 2); i++) {
91  double alpha = 2 * M_PI * (float) i / (float) n;
92  double c1 = cos(alpha), s1 = sin(alpha);
93  if (!inverse)
94  s1 = -s1;
95  exptab[i].re = c1;
96  exptab[i].im = s1;
97  }
98  return 0;
99 }
100 
101 static void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits)
102 {
103  int i, j;
104  int n = 1 << nbits;
105  int n2 = n >> 1;
106 
107  for (i = 0; i < n; i++) {
108  double tmp_re = 0, tmp_im = 0;
109  FFTComplex *q = tab;
110  for (j = 0; j < n; j++) {
111  double s, c;
112  int k = (i * j) & (n - 1);
113  if (k >= n2) {
114  c = -exptab[k - n2].re;
115  s = -exptab[k - n2].im;
116  } else {
117  c = exptab[k].re;
118  s = exptab[k].im;
119  }
120  CMAC(tmp_re, tmp_im, c, s, q->re, q->im);
121  q++;
122  }
123  tabr[i].re = REF_SCALE(tmp_re, nbits);
124  tabr[i].im = REF_SCALE(tmp_im, nbits);
125  }
126 }
127 
128 #if CONFIG_MDCT
129 static void imdct_ref(FFTSample *out, FFTSample *in, int nbits)
130 {
131  int i, k, n = 1 << nbits;
132 
133  for (i = 0; i < n; i++) {
134  double sum = 0;
135  for (k = 0; k < n / 2; k++) {
136  int a = (2 * i + 1 + (n / 2)) * (2 * k + 1);
137  double f = cos(M_PI * a / (double) (2 * n));
138  sum += f * in[k];
139  }
140  out[i] = REF_SCALE(-sum, nbits - 2);
141  }
142 }
143 
144 /* NOTE: no normalisation by 1 / N is done */
145 static void mdct_ref(FFTSample *output, FFTSample *input, int nbits)
146 {
147  int i, k, n = 1 << nbits;
148 
149  /* do it by hand */
150  for (k = 0; k < n / 2; k++) {
151  double s = 0;
152  for (i = 0; i < n; i++) {
153  double a = (2 * M_PI * (2 * i + 1 + n / 2) * (2 * k + 1) / (4 * n));
154  s += input[i] * cos(a);
155  }
156  output[k] = REF_SCALE(s, nbits - 1);
157  }
158 }
159 #endif /* CONFIG_MDCT */
160 
161 #if FFT_FLOAT
162 #if CONFIG_DCT
163 static void idct_ref(FFTSample *output, FFTSample *input, int nbits)
164 {
165  int i, k, n = 1 << nbits;
166 
167  /* do it by hand */
168  for (i = 0; i < n; i++) {
169  double s = 0.5 * input[0];
170  for (k = 1; k < n; k++) {
171  double a = M_PI * k * (i + 0.5) / n;
172  s += input[k] * cos(a);
173  }
174  output[i] = 2 * s / n;
175  }
176 }
177 
178 static void dct_ref(FFTSample *output, FFTSample *input, int nbits)
179 {
180  int i, k, n = 1 << nbits;
181 
182  /* do it by hand */
183  for (k = 0; k < n; k++) {
184  double s = 0;
185  for (i = 0; i < n; i++) {
186  double a = M_PI * k * (i + 0.5) / n;
187  s += input[i] * cos(a);
188  }
189  output[k] = s;
190  }
191 }
192 #endif /* CONFIG_DCT */
193 #endif /* FFT_FLOAT */
194 
195 static FFTSample frandom(AVLFG *prng)
196 {
197  return (int16_t) av_lfg_get(prng) / 32768.0 * RANGE;
198 }
199 
200 static int check_diff(FFTSample *tab1, FFTSample *tab2, int n, double scale)
201 {
202  int i, err = 0;
203  double error = 0, max = 0;
204 
205  for (i = 0; i < n; i++) {
206  double e = fabs(tab1[i] - (tab2[i] / scale)) / RANGE;
207  if (e >= 1e-3) {
208  av_log(NULL, AV_LOG_ERROR, "ERROR %5d: "FMT" "FMT"\n",
209  i, tab1[i], tab2[i]);
210  err = 1;
211  }
212  error += e * e;
213  if (e > max)
214  max = e;
215  }
216  av_log(NULL, AV_LOG_INFO, "max:%f e:%g\n", max, sqrt(error / n));
217  return err;
218 }
219 
220 static inline void fft_init(FFTContext **s, int nbits, int inverse)
221 {
222 #if AVFFT
223  *s = av_fft_init(nbits, inverse);
224 #else
225  ff_fft_init(*s, nbits, inverse);
226 #endif
227 }
228 
229 static inline void mdct_init(FFTContext **s, int nbits, int inverse, double scale)
230 {
231 #if AVFFT
232  *s = av_mdct_init(nbits, inverse, scale);
233 #else
234  ff_mdct_init(*s, nbits, inverse, scale);
235 #endif
236 }
237 
238 static inline void mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
239 {
240 #if AVFFT
242 #else
243  s->mdct_calc(s, output, input);
244 #endif
245 }
246 
247 static inline void imdct_calc(struct FFTContext *s, FFTSample *output, const FFTSample *input)
248 {
249 #if AVFFT
251 #else
252  s->imdct_calc(s, output, input);
253 #endif
254 }
255 
256 static inline void fft_permute(FFTContext *s, FFTComplex *z)
257 {
258 #if AVFFT
259  av_fft_permute(s, z);
260 #else
261  s->fft_permute(s, z);
262 #endif
263 }
264 
265 static inline void fft_calc(FFTContext *s, FFTComplex *z)
266 {
267 #if AVFFT
268  av_fft_calc(s, z);
269 #else
270  s->fft_calc(s, z);
271 #endif
272 }
273 
274 static inline void mdct_end(FFTContext *s)
275 {
276 #if AVFFT
277  av_mdct_end(s);
278 #else
279  ff_mdct_end(s);
280 #endif
281 }
282 
283 static inline void fft_end(FFTContext *s)
284 {
285 #if AVFFT
286  av_fft_end(s);
287 #else
288  ff_fft_end(s);
289 #endif
290 }
291 
292 #if FFT_FLOAT
293 static inline void rdft_init(RDFTContext **r, int nbits, enum RDFTransformType trans)
294 {
295 #if AVFFT
296  *r = av_rdft_init(nbits, trans);
297 #else
298  ff_rdft_init(*r, nbits, trans);
299 #endif
300 }
301 
302 static inline void dct_init(DCTContext **d, int nbits, enum DCTTransformType trans)
303 {
304 #if AVFFT
305  *d = av_dct_init(nbits, trans);
306 #else
307  ff_dct_init(*d, nbits, trans);
308 #endif
309 }
310 
311 static inline void rdft_calc(RDFTContext *r, FFTSample *tab)
312 {
313 #if AVFFT
314  av_rdft_calc(r, tab);
315 #else
316  r->rdft_calc(r, tab);
317 #endif
318 }
319 
320 static inline void dct_calc(DCTContext *d, FFTSample *data)
321 {
322 #if AVFFT
323  av_dct_calc(d, data);
324 #else
325  d->dct_calc(d, data);
326 #endif
327 }
328 
329 static inline void rdft_end(RDFTContext *r)
330 {
331 #if AVFFT
332  av_rdft_end(r);
333 #else
334  ff_rdft_end(r);
335 #endif
336 }
337 
338 static inline void dct_end(DCTContext *d)
339 {
340 #if AVFFT
341  av_dct_end(d);
342 #else
343  ff_dct_end(d);
344 #endif
345 }
346 #endif /* FFT_FLOAT */
347 
348 static void help(void)
349 {
351  "usage: fft-test [-h] [-s] [-i] [-n b]\n"
352  "-h print this help\n"
353  "-s speed test\n"
354  "-m (I)MDCT test\n"
355  "-d (I)DCT test\n"
356  "-r (I)RDFT test\n"
357  "-i inverse transform test\n"
358  "-n b set the transform size to 2^b\n"
359  "-f x set scale factor for output data of (I)MDCT to x\n");
360 }
361 
367 };
368 
369 #if !HAVE_GETOPT
370 #include "compat/getopt.c"
371 #endif
372 
373 int main(int argc, char **argv)
374 {
375  FFTComplex *tab, *tab1, *tab_ref;
376  FFTSample *tab2;
378  FFTContext *m, *s;
379 #if FFT_FLOAT
380  RDFTContext *r;
381  DCTContext *d;
382 #endif /* FFT_FLOAT */
383  int it, i, err = 1;
384  int do_speed = 0, do_inverse = 0;
385  int fft_nbits = 9, fft_size;
386  double scale = 1.0;
387  AVLFG prng;
388 
389 #if !AVFFT
390  s = av_mallocz(sizeof(*s));
391  m = av_mallocz(sizeof(*m));
392 #endif
393 
394 #if !AVFFT && FFT_FLOAT
395  r = av_mallocz(sizeof(*r));
396  d = av_mallocz(sizeof(*d));
397 #endif
398 
399  av_lfg_init(&prng, 1);
400 
401  for (;;) {
402  int c = getopt(argc, argv, "hsimrdn:f:c:");
403  if (c == -1)
404  break;
405  switch (c) {
406  case 'h':
407  help();
408  return 1;
409  case 's':
410  do_speed = 1;
411  break;
412  case 'i':
413  do_inverse = 1;
414  break;
415  case 'm':
417  break;
418  case 'r':
420  break;
421  case 'd':
423  break;
424  case 'n':
425  fft_nbits = atoi(optarg);
426  break;
427  case 'f':
428  scale = atof(optarg);
429  break;
430  case 'c':
431  {
432  unsigned cpuflags = av_get_cpu_flags();
433 
434  if (av_parse_cpu_caps(&cpuflags, optarg) < 0)
435  return 1;
436 
437  av_force_cpu_flags(cpuflags);
438  break;
439  }
440  }
441  }
442 
443  fft_size = 1 << fft_nbits;
444  tab = av_malloc_array(fft_size, sizeof(FFTComplex));
445  tab1 = av_malloc_array(fft_size, sizeof(FFTComplex));
446  tab_ref = av_malloc_array(fft_size, sizeof(FFTComplex));
447  tab2 = av_malloc_array(fft_size, sizeof(FFTSample));
448 
449  if (!(tab && tab1 && tab_ref && tab2))
450  goto cleanup;
451 
452  switch (transform) {
453 #if CONFIG_MDCT
454  case TRANSFORM_MDCT:
455  av_log(NULL, AV_LOG_INFO, "Scale factor is set to %f\n", scale);
456  if (do_inverse)
457  av_log(NULL, AV_LOG_INFO, "IMDCT");
458  else
459  av_log(NULL, AV_LOG_INFO, "MDCT");
460  mdct_init(&m, fft_nbits, do_inverse, scale);
461  break;
462 #endif /* CONFIG_MDCT */
463  case TRANSFORM_FFT:
464  if (do_inverse)
465  av_log(NULL, AV_LOG_INFO, "IFFT");
466  else
467  av_log(NULL, AV_LOG_INFO, "FFT");
468  fft_init(&s, fft_nbits, do_inverse);
469  if ((err = fft_ref_init(fft_nbits, do_inverse)) < 0)
470  goto cleanup;
471  break;
472 #if FFT_FLOAT
473 # if CONFIG_RDFT
474  case TRANSFORM_RDFT:
475  if (do_inverse)
476  av_log(NULL, AV_LOG_INFO, "IDFT_C2R");
477  else
478  av_log(NULL, AV_LOG_INFO, "DFT_R2C");
479  rdft_init(&r, fft_nbits, do_inverse ? IDFT_C2R : DFT_R2C);
480  if ((err = fft_ref_init(fft_nbits, do_inverse)) < 0)
481  goto cleanup;
482  break;
483 # endif /* CONFIG_RDFT */
484 # if CONFIG_DCT
485  case TRANSFORM_DCT:
486  if (do_inverse)
487  av_log(NULL, AV_LOG_INFO, "DCT_III");
488  else
489  av_log(NULL, AV_LOG_INFO, "DCT_II");
490  dct_init(&d, fft_nbits, do_inverse ? DCT_III : DCT_II);
491  break;
492 # endif /* CONFIG_DCT */
493 #endif /* FFT_FLOAT */
494  default:
495  av_log(NULL, AV_LOG_ERROR, "Requested transform not supported\n");
496  goto cleanup;
497  }
498  av_log(NULL, AV_LOG_INFO, " %d test\n", fft_size);
499 
500  /* generate random data */
501 
502  for (i = 0; i < fft_size; i++) {
503  tab1[i].re = frandom(&prng);
504  tab1[i].im = frandom(&prng);
505  }
506 
507  /* checking result */
508  av_log(NULL, AV_LOG_INFO, "Checking...\n");
509 
510  switch (transform) {
511 #if CONFIG_MDCT
512  case TRANSFORM_MDCT:
513  if (do_inverse) {
514  imdct_ref(&tab_ref->re, &tab1->re, fft_nbits);
515  imdct_calc(m, tab2, &tab1->re);
516  err = check_diff(&tab_ref->re, tab2, fft_size, scale);
517  } else {
518  mdct_ref(&tab_ref->re, &tab1->re, fft_nbits);
519  mdct_calc(m, tab2, &tab1->re);
520  err = check_diff(&tab_ref->re, tab2, fft_size / 2, scale);
521  }
522  break;
523 #endif /* CONFIG_MDCT */
524  case TRANSFORM_FFT:
525  memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
526  fft_permute(s, tab);
527  fft_calc(s, tab);
528 
529  fft_ref(tab_ref, tab1, fft_nbits);
530  err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 1.0);
531  break;
532 #if FFT_FLOAT
533 #if CONFIG_RDFT
534  case TRANSFORM_RDFT:
535  {
536  int fft_size_2 = fft_size >> 1;
537  if (do_inverse) {
538  tab1[0].im = 0;
539  tab1[fft_size_2].im = 0;
540  for (i = 1; i < fft_size_2; i++) {
541  tab1[fft_size_2 + i].re = tab1[fft_size_2 - i].re;
542  tab1[fft_size_2 + i].im = -tab1[fft_size_2 - i].im;
543  }
544 
545  memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
546  tab2[1] = tab1[fft_size_2].re;
547 
548  rdft_calc(r, tab2);
549  fft_ref(tab_ref, tab1, fft_nbits);
550  for (i = 0; i < fft_size; i++) {
551  tab[i].re = tab2[i];
552  tab[i].im = 0;
553  }
554  err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 0.5);
555  } else {
556  for (i = 0; i < fft_size; i++) {
557  tab2[i] = tab1[i].re;
558  tab1[i].im = 0;
559  }
560  rdft_calc(r, tab2);
561  fft_ref(tab_ref, tab1, fft_nbits);
562  tab_ref[0].im = tab_ref[fft_size_2].re;
563  err = check_diff(&tab_ref->re, tab2, fft_size, 1.0);
564  }
565  break;
566  }
567 #endif /* CONFIG_RDFT */
568 #if CONFIG_DCT
569  case TRANSFORM_DCT:
570  memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
571  dct_calc(d, &tab->re);
572  if (do_inverse)
573  idct_ref(&tab_ref->re, &tab1->re, fft_nbits);
574  else
575  dct_ref(&tab_ref->re, &tab1->re, fft_nbits);
576  err = check_diff(&tab_ref->re, &tab->re, fft_size, 1.0);
577  break;
578 #endif /* CONFIG_DCT */
579 #endif /* FFT_FLOAT */
580  }
581 
582  /* do a speed test */
583 
584  if (do_speed) {
585  int64_t time_start, duration;
586  int nb_its;
587 
588  av_log(NULL, AV_LOG_INFO, "Speed test...\n");
589  /* we measure during about 1 seconds */
590  nb_its = 1;
591  for (;;) {
592  time_start = av_gettime_relative();
593  for (it = 0; it < nb_its; it++) {
594  switch (transform) {
595  case TRANSFORM_MDCT:
596  if (do_inverse)
597  imdct_calc(m, &tab->re, &tab1->re);
598  else
599  mdct_calc(m, &tab->re, &tab1->re);
600  break;
601  case TRANSFORM_FFT:
602  memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
603  fft_calc(s, tab);
604  break;
605 #if FFT_FLOAT
606  case TRANSFORM_RDFT:
607  memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
608  rdft_calc(r, tab2);
609  break;
610  case TRANSFORM_DCT:
611  memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
612  dct_calc(d, tab2);
613  break;
614 #endif /* FFT_FLOAT */
615  }
616  }
617  duration = av_gettime_relative() - time_start;
618  if (duration >= 1000000)
619  break;
620  nb_its *= 2;
621  }
623  "time: %0.1f us/transform [total time=%0.2f s its=%d]\n",
624  (double) duration / nb_its,
625  (double) duration / 1000000.0,
626  nb_its);
627  }
628 
629  switch (transform) {
630 #if CONFIG_MDCT
631  case TRANSFORM_MDCT:
632  mdct_end(m);
633  break;
634 #endif /* CONFIG_MDCT */
635  case TRANSFORM_FFT:
636  fft_end(s);
637  break;
638 #if FFT_FLOAT
639 # if CONFIG_RDFT
640  case TRANSFORM_RDFT:
641  rdft_end(r);
642  break;
643 # endif /* CONFIG_RDFT */
644 # if CONFIG_DCT
645  case TRANSFORM_DCT:
646  dct_end(d);
647  break;
648 # endif /* CONFIG_DCT */
649 #endif /* FFT_FLOAT */
650  }
651 
652 cleanup:
653  av_free(tab);
654  av_free(tab1);
655  av_free(tab2);
656  av_free(tab_ref);
657  av_free(exptab);
658 
659 #if !AVFFT
660  av_free(s);
661  av_free(m);
662 #endif
663 
664 #if !AVFFT && FFT_FLOAT
665  av_free(r);
666  av_free(d);
667 #endif
668 
669  if (err)
670  printf("Error: %d.\n", err);
671 
672  return !!err;
673 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
ff_fft_init
#define ff_fft_init
Definition: fft.h:135
av_fft_end
av_cold void av_fft_end(FFTContext *s)
Definition: avfft.c:48
av_force_cpu_flags
void av_force_cpu_flags(int arg)
Disables cpu detection and forces the specified flags.
Definition: cpu.c:73
av_imdct_calc
void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
r
const char * r
Definition: vf_curves.c:116
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
out
FILE * out
Definition: movenc.c:54
av_lfg_init
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:32
inverse
inverse
Definition: af_crystalizer.c:122
mdct_init
static void mdct_init(FFTContext **s, int nbits, int inverse, double scale)
Definition: fft.c:229
rdft.h
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
TRANSFORM_DCT
@ TRANSFORM_DCT
Definition: fft.c:366
im
float im
Definition: fft.c:79
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
data
const char data[16]
Definition: mxf.c:143
ff_mdct_init
#define ff_mdct_init
Definition: fft.h:153
av_fft_permute
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
Definition: avfft.c:38
av_dct_init
DCTContext * av_dct_init(int nbits, enum DCTTransformType type)
Set up DCT.
max
#define max(a, b)
Definition: cuda_runtime.h:33
mathematics.h
av_get_cpu_flags
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:101
c1
static const uint64_t c1
Definition: murmur3.c:51
CMAC
#define CMAC(pre, pim, are, aim, bre, bim)
Definition: fft.c:62
DCT_III
@ DCT_III
Definition: avfft.h:95
av_parse_cpu_caps
int av_parse_cpu_caps(unsigned *flags, const char *s)
Parse CPU caps from a string and update the given AV_CPU_* flags based on that.
Definition: cpu.c:111
tab
static const struct twinvq_data tab
Definition: twinvq_data.h:10345
IDFT_C2R
@ IDFT_C2R
Definition: avfft.h:73
ff_rdft_end
av_cold void ff_rdft_end(RDFTContext *s)
Definition: rdft.c:117
REF_SCALE
#define REF_SCALE(x, bits)
Definition: fft.c:74
tab2
const int16_t * tab2
Definition: mace.c:145
TRANSFORM_FFT
@ TRANSFORM_FFT
Definition: fft.c:363
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1389
frandom
static FFTSample frandom(AVLFG *prng)
Definition: fft.c:195
tab1
const int16_t * tab1
Definition: mace.c:145
main
int main(int argc, char **argv)
Definition: fft.c:373
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
dct.h
av_dct_end
void av_dct_end(DCTContext *s)
getopt
static int getopt(int argc, char *argv[], char *opts)
Definition: getopt.c:41
duration
int64_t duration
Definition: movenc.c:64
float
float
Definition: af_crystalizer.c:122
s
#define s(width, name)
Definition: cbs_vp9.c:256
av_lfg_get
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition: lfg.h:53
help
static void help(void)
Definition: fft.c:348
s1
#define s1
Definition: regdef.h:38
fft_end
static void fft_end(FFTContext *s)
Definition: fft.c:283
lfg.h
ff_fft_end
#define ff_fft_end
Definition: fft.h:136
av_rdft_calc
void av_rdft_calc(RDFTContext *s, FFTSample *data)
av_dct_calc
void av_dct_calc(DCTContext *s, FFTSample *data)
av_mdct_init
FFTContext * av_mdct_init(int nbits, int inverse, double scale)
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
TRANSFORM_MDCT
@ TRANSFORM_MDCT
Definition: fft.c:364
transform
static const int8_t transform[32][32]
Definition: hevcdsp.c:27
imdct_calc
static void imdct_calc(struct FFTContext *s, FFTSample *output, const FFTSample *input)
Definition: fft.c:247
av_mdct_end
void av_mdct_end(FFTContext *s)
tf_transform
tf_transform
Definition: fft.c:362
DFT_R2C
@ DFT_R2C
Definition: avfft.h:72
time.h
FFTSample
float FFTSample
Definition: avfft.h:35
avfft.h
fft_calc
static void fft_calc(FFTContext *s, FFTComplex *z)
Definition: fft.c:265
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
error.h
fft_permute
static void fft_permute(FFTContext *s, FFTComplex *z)
Definition: fft.c:256
AVLFG
Context structure for the Lagged Fibonacci PRNG.
Definition: lfg.h:33
f
f
Definition: af_crystalizer.c:122
av_rdft_init
RDFTContext * av_rdft_init(int nbits, enum RDFTransformType trans)
Set up a real FFT.
cpu.h
ff_mdct_end
#define ff_mdct_end
Definition: fft.h:154
FFTComplex::im
FFTSample im
Definition: avfft.h:38
printf
printf("static const uint8_t my_array[100] = {\n")
FFTComplex::re
FFTSample re
Definition: avfft.h:38
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
ff_dct_end
av_cold void ff_dct_end(DCTContext *s)
Definition: dct.c:224
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
M_PI
#define M_PI
Definition: mathematics.h:52
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
ff_rdft_init
av_cold int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans)
Set up a real FFT.
Definition: rdft.c:89
FFTContext
Definition: fft.h:75
ff_dct_init
av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse)
Set up DCT.
Definition: dct.c:179
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
RDFTContext
Definition: rdft.h:28
RDFTransformType
RDFTransformType
Definition: avfft.h:71
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
fft_ref_init
static int fft_ref_init(int nbits, int inverse)
Definition: fft.c:82
DCTContext
Definition: dct.h:32
fft_init
static void fft_init(FFTContext **s, int nbits, int inverse)
Definition: fft.c:220
exptab
static struct @134 * exptab
mdct_end
static void mdct_end(FFTContext *s)
Definition: fft.c:274
dct_init
static av_cold int dct_init(MpegEncContext *s)
Definition: mpegvideo.c:282
getopt.c
av_fft_init
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
Definition: avfft.c:28
fft.h
check_diff
static int check_diff(FFTSample *tab1, FFTSample *tab2, int n, double scale)
Definition: fft.c:200
FMT
#define FMT
Definition: fft.c:75
optarg
static char * optarg
Definition: getopt.c:39
mdct_calc
static void mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
Definition: fft.c:238
it
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s it
Definition: writing_filters.txt:31
RANGE
#define RANGE
Definition: fft.c:73
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
fft_ref
static void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits)
Definition: fft.c:101
TRANSFORM_RDFT
@ TRANSFORM_RDFT
Definition: fft.c:365
d
d
Definition: ffmpeg_filter.c:153
DCT_II
@ DCT_II
Definition: avfft.h:94
av_rdft_end
void av_rdft_end(RDFTContext *s)
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_fft_calc
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
Definition: avfft.c:43
av_mdct_calc
void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
DCTTransformType
DCTTransformType
Definition: avfft.h:93
FFTComplex
Definition: avfft.h:37
re
float re
Definition: fft.c:79