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/lfg.h"
42 #include "libavutil/log.h"
43 #include "libavutil/mathematics.h"
44 #include "libavutil/time.h"
45 
46 #if AVFFT
47 #include "libavcodec/avfft.h"
48 #else
49 #include "libavcodec/fft.h"
50 #endif
51 
52 #if FFT_FLOAT
53 #include "libavcodec/dct.h"
54 #include "libavcodec/rdft.h"
55 #endif
56 
57 /* reference fft */
58 
59 #define MUL16(a, b) ((a) * (b))
60 
61 #define CMAC(pre, pim, are, aim, bre, bim) \
62  { \
63  pre += (MUL16(are, bre) - MUL16(aim, bim)); \
64  pim += (MUL16(are, bim) + MUL16(bre, aim)); \
65  }
66 
67 #if FFT_FLOAT || AVFFT
68 #define RANGE 1.0
69 #define REF_SCALE(x, bits) (x)
70 #define FMT "%10.6f"
71 #else
72 #define RANGE 8388608
73 #define REF_SCALE(x, bits) (x)
74 #define FMT "%6d"
75 #endif
76 
77 static struct {
78  float re, im;
79 } *exptab;
80 
81 static int fft_ref_init(int nbits, int inverse)
82 {
83  int i, n = 1 << nbits;
84 
85  exptab = av_malloc_array((n / 2), sizeof(*exptab));
86  if (!exptab)
87  return AVERROR(ENOMEM);
88 
89  for (i = 0; i < (n / 2); i++) {
90  double alpha = 2 * M_PI * (float) i / (float) n;
91  double c1 = cos(alpha), s1 = sin(alpha);
92  if (!inverse)
93  s1 = -s1;
94  exptab[i].re = c1;
95  exptab[i].im = s1;
96  }
97  return 0;
98 }
99 
100 static void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits)
101 {
102  int i, j;
103  int n = 1 << nbits;
104  int n2 = n >> 1;
105 
106  for (i = 0; i < n; i++) {
107  double tmp_re = 0, tmp_im = 0;
108  FFTComplex *q = tab;
109  for (j = 0; j < n; j++) {
110  double s, c;
111  int k = (i * j) & (n - 1);
112  if (k >= n2) {
113  c = -exptab[k - n2].re;
114  s = -exptab[k - n2].im;
115  } else {
116  c = exptab[k].re;
117  s = exptab[k].im;
118  }
119  CMAC(tmp_re, tmp_im, c, s, q->re, q->im);
120  q++;
121  }
122  tabr[i].re = REF_SCALE(tmp_re, nbits);
123  tabr[i].im = REF_SCALE(tmp_im, nbits);
124  }
125 }
126 
127 #if CONFIG_MDCT
128 static void imdct_ref(FFTSample *out, FFTSample *in, int nbits)
129 {
130  int i, k, n = 1 << nbits;
131 
132  for (i = 0; i < n; i++) {
133  double sum = 0;
134  for (k = 0; k < n / 2; k++) {
135  int a = (2 * i + 1 + (n / 2)) * (2 * k + 1);
136  double f = cos(M_PI * a / (double) (2 * n));
137  sum += f * in[k];
138  }
139  out[i] = REF_SCALE(-sum, nbits - 2);
140  }
141 }
142 
143 /* NOTE: no normalisation by 1 / N is done */
144 static void mdct_ref(FFTSample *output, FFTSample *input, int nbits)
145 {
146  int i, k, n = 1 << nbits;
147 
148  /* do it by hand */
149  for (k = 0; k < n / 2; k++) {
150  double s = 0;
151  for (i = 0; i < n; i++) {
152  double a = (2 * M_PI * (2 * i + 1 + n / 2) * (2 * k + 1) / (4 * n));
153  s += input[i] * cos(a);
154  }
155  output[k] = REF_SCALE(s, nbits - 1);
156  }
157 }
158 #endif /* CONFIG_MDCT */
159 
160 #if FFT_FLOAT
161 #if CONFIG_DCT
162 static void idct_ref(FFTSample *output, FFTSample *input, int nbits)
163 {
164  int i, k, n = 1 << nbits;
165 
166  /* do it by hand */
167  for (i = 0; i < n; i++) {
168  double s = 0.5 * input[0];
169  for (k = 1; k < n; k++) {
170  double a = M_PI * k * (i + 0.5) / n;
171  s += input[k] * cos(a);
172  }
173  output[i] = 2 * s / n;
174  }
175 }
176 
177 static void dct_ref(FFTSample *output, FFTSample *input, int nbits)
178 {
179  int i, k, n = 1 << nbits;
180 
181  /* do it by hand */
182  for (k = 0; k < n; k++) {
183  double s = 0;
184  for (i = 0; i < n; i++) {
185  double a = M_PI * k * (i + 0.5) / n;
186  s += input[i] * cos(a);
187  }
188  output[k] = s;
189  }
190 }
191 #endif /* CONFIG_DCT */
192 #endif /* FFT_FLOAT */
193 
194 static FFTSample frandom(AVLFG *prng)
195 {
196  return (int16_t) av_lfg_get(prng) / 32768.0 * RANGE;
197 }
198 
199 static int check_diff(FFTSample *tab1, FFTSample *tab2, int n, double scale)
200 {
201  int i, err = 0;
202  double error = 0, max = 0;
203 
204  for (i = 0; i < n; i++) {
205  double e = fabs(tab1[i] - (tab2[i] / scale)) / RANGE;
206  if (e >= 1e-3) {
207  av_log(NULL, AV_LOG_ERROR, "ERROR %5d: "FMT" "FMT"\n",
208  i, tab1[i], tab2[i]);
209  err = 1;
210  }
211  error += e * e;
212  if (e > max)
213  max = e;
214  }
215  av_log(NULL, AV_LOG_INFO, "max:%f e:%g\n", max, sqrt(error / n));
216  return err;
217 }
218 
219 static inline void fft_init(FFTContext **s, int nbits, int inverse)
220 {
221 #if AVFFT
222  *s = av_fft_init(nbits, inverse);
223 #else
224  ff_fft_init(*s, nbits, inverse);
225 #endif
226 }
227 
228 static inline void mdct_init(FFTContext **s, int nbits, int inverse, double scale)
229 {
230 #if AVFFT
231  *s = av_mdct_init(nbits, inverse, scale);
232 #else
233  ff_mdct_init(*s, nbits, inverse, scale);
234 #endif
235 }
236 
237 static inline void mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
238 {
239 #if AVFFT
241 #else
242  s->mdct_calc(s, output, input);
243 #endif
244 }
245 
246 static inline void imdct_calc(struct FFTContext *s, FFTSample *output, const FFTSample *input)
247 {
248 #if AVFFT
250 #else
251  s->imdct_calc(s, output, input);
252 #endif
253 }
254 
255 static inline void fft_permute(FFTContext *s, FFTComplex *z)
256 {
257 #if AVFFT
258  av_fft_permute(s, z);
259 #else
260  s->fft_permute(s, z);
261 #endif
262 }
263 
264 static inline void fft_calc(FFTContext *s, FFTComplex *z)
265 {
266 #if AVFFT
267  av_fft_calc(s, z);
268 #else
269  s->fft_calc(s, z);
270 #endif
271 }
272 
273 static inline void mdct_end(FFTContext *s)
274 {
275 #if AVFFT
276  av_mdct_end(s);
277 #else
278  ff_mdct_end(s);
279 #endif
280 }
281 
282 static inline void fft_end(FFTContext *s)
283 {
284 #if AVFFT
285  av_fft_end(s);
286 #else
287  ff_fft_end(s);
288 #endif
289 }
290 
291 #if FFT_FLOAT
292 static inline void rdft_init(RDFTContext **r, int nbits, enum RDFTransformType trans)
293 {
294 #if AVFFT
295  *r = av_rdft_init(nbits, trans);
296 #else
297  ff_rdft_init(*r, nbits, trans);
298 #endif
299 }
300 
301 static inline void dct_init(DCTContext **d, int nbits, enum DCTTransformType trans)
302 {
303 #if AVFFT
304  *d = av_dct_init(nbits, trans);
305 #else
306  ff_dct_init(*d, nbits, trans);
307 #endif
308 }
309 
310 static inline void rdft_calc(RDFTContext *r, FFTSample *tab)
311 {
312 #if AVFFT
313  av_rdft_calc(r, tab);
314 #else
315  r->rdft_calc(r, tab);
316 #endif
317 }
318 
319 static inline void dct_calc(DCTContext *d, FFTSample *data)
320 {
321 #if AVFFT
322  av_dct_calc(d, data);
323 #else
324  d->dct_calc(d, data);
325 #endif
326 }
327 
328 static inline void rdft_end(RDFTContext *r)
329 {
330 #if AVFFT
331  av_rdft_end(r);
332 #else
333  ff_rdft_end(r);
334 #endif
335 }
336 
337 static inline void dct_end(DCTContext *d)
338 {
339 #if AVFFT
340  av_dct_end(d);
341 #else
342  ff_dct_end(d);
343 #endif
344 }
345 #endif /* FFT_FLOAT */
346 
347 static void help(void)
348 {
350  "usage: fft-test [-h] [-s] [-i] [-n b]\n"
351  "-h print this help\n"
352  "-s speed test\n"
353  "-m (I)MDCT test\n"
354  "-d (I)DCT test\n"
355  "-r (I)RDFT test\n"
356  "-i inverse transform test\n"
357  "-n b set the transform size to 2^b\n"
358  "-f x set scale factor for output data of (I)MDCT to x\n");
359 }
360 
366 };
367 
368 #if !HAVE_GETOPT
369 #include "compat/getopt.c"
370 #endif
371 
372 int main(int argc, char **argv)
373 {
374  FFTComplex *tab, *tab1, *tab_ref;
375  FFTSample *tab2;
377  FFTContext *m, *s;
378 #if FFT_FLOAT
379  RDFTContext *r;
380  DCTContext *d;
381 #endif /* FFT_FLOAT */
382  int it, i, err = 1;
383  int do_speed = 0, do_inverse = 0;
384  int fft_nbits = 9, fft_size;
385  double scale = 1.0;
386  AVLFG prng;
387 
388 #if !AVFFT
389  s = av_mallocz(sizeof(*s));
390  m = av_mallocz(sizeof(*m));
391 #endif
392 
393 #if !AVFFT && FFT_FLOAT
394  r = av_mallocz(sizeof(*r));
395  d = av_mallocz(sizeof(*d));
396 #endif
397 
398  av_lfg_init(&prng, 1);
399 
400  for (;;) {
401  int c = getopt(argc, argv, "hsimrdn:f:c:");
402  if (c == -1)
403  break;
404  switch (c) {
405  case 'h':
406  help();
407  return 1;
408  case 's':
409  do_speed = 1;
410  break;
411  case 'i':
412  do_inverse = 1;
413  break;
414  case 'm':
416  break;
417  case 'r':
419  break;
420  case 'd':
422  break;
423  case 'n':
424  fft_nbits = atoi(optarg);
425  break;
426  case 'f':
427  scale = atof(optarg);
428  break;
429  case 'c':
430  {
431  unsigned cpuflags = av_get_cpu_flags();
432 
433  if (av_parse_cpu_caps(&cpuflags, optarg) < 0)
434  return 1;
435 
436  av_force_cpu_flags(cpuflags);
437  break;
438  }
439  }
440  }
441 
442  fft_size = 1 << fft_nbits;
443  tab = av_malloc_array(fft_size, sizeof(FFTComplex));
444  tab1 = av_malloc_array(fft_size, sizeof(FFTComplex));
445  tab_ref = av_malloc_array(fft_size, sizeof(FFTComplex));
446  tab2 = av_malloc_array(fft_size, sizeof(FFTSample));
447 
448  if (!(tab && tab1 && tab_ref && tab2))
449  goto cleanup;
450 
451  switch (transform) {
452 #if CONFIG_MDCT
453  case TRANSFORM_MDCT:
454  av_log(NULL, AV_LOG_INFO, "Scale factor is set to %f\n", scale);
455  if (do_inverse)
456  av_log(NULL, AV_LOG_INFO, "IMDCT");
457  else
458  av_log(NULL, AV_LOG_INFO, "MDCT");
459  mdct_init(&m, fft_nbits, do_inverse, scale);
460  break;
461 #endif /* CONFIG_MDCT */
462  case TRANSFORM_FFT:
463  if (do_inverse)
464  av_log(NULL, AV_LOG_INFO, "IFFT");
465  else
466  av_log(NULL, AV_LOG_INFO, "FFT");
467  fft_init(&s, fft_nbits, do_inverse);
468  if ((err = fft_ref_init(fft_nbits, do_inverse)) < 0)
469  goto cleanup;
470  break;
471 #if FFT_FLOAT
472 # if CONFIG_RDFT
473  case TRANSFORM_RDFT:
474  if (do_inverse)
475  av_log(NULL, AV_LOG_INFO, "IDFT_C2R");
476  else
477  av_log(NULL, AV_LOG_INFO, "DFT_R2C");
478  rdft_init(&r, fft_nbits, do_inverse ? IDFT_C2R : DFT_R2C);
479  if ((err = fft_ref_init(fft_nbits, do_inverse)) < 0)
480  goto cleanup;
481  break;
482 # endif /* CONFIG_RDFT */
483 # if CONFIG_DCT
484  case TRANSFORM_DCT:
485  if (do_inverse)
486  av_log(NULL, AV_LOG_INFO, "DCT_III");
487  else
488  av_log(NULL, AV_LOG_INFO, "DCT_II");
489  dct_init(&d, fft_nbits, do_inverse ? DCT_III : DCT_II);
490  break;
491 # endif /* CONFIG_DCT */
492 #endif /* FFT_FLOAT */
493  default:
494  av_log(NULL, AV_LOG_ERROR, "Requested transform not supported\n");
495  goto cleanup;
496  }
497  av_log(NULL, AV_LOG_INFO, " %d test\n", fft_size);
498 
499  /* generate random data */
500 
501  for (i = 0; i < fft_size; i++) {
502  tab1[i].re = frandom(&prng);
503  tab1[i].im = frandom(&prng);
504  }
505 
506  /* checking result */
507  av_log(NULL, AV_LOG_INFO, "Checking...\n");
508 
509  switch (transform) {
510 #if CONFIG_MDCT
511  case TRANSFORM_MDCT:
512  if (do_inverse) {
513  imdct_ref(&tab_ref->re, &tab1->re, fft_nbits);
514  imdct_calc(m, tab2, &tab1->re);
515  err = check_diff(&tab_ref->re, tab2, fft_size, scale);
516  } else {
517  mdct_ref(&tab_ref->re, &tab1->re, fft_nbits);
518  mdct_calc(m, tab2, &tab1->re);
519  err = check_diff(&tab_ref->re, tab2, fft_size / 2, scale);
520  }
521  break;
522 #endif /* CONFIG_MDCT */
523  case TRANSFORM_FFT:
524  memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
525  fft_permute(s, tab);
526  fft_calc(s, tab);
527 
528  fft_ref(tab_ref, tab1, fft_nbits);
529  err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 1.0);
530  break;
531 #if FFT_FLOAT
532 #if CONFIG_RDFT
533  case TRANSFORM_RDFT:
534  {
535  int fft_size_2 = fft_size >> 1;
536  if (do_inverse) {
537  tab1[0].im = 0;
538  tab1[fft_size_2].im = 0;
539  for (i = 1; i < fft_size_2; i++) {
540  tab1[fft_size_2 + i].re = tab1[fft_size_2 - i].re;
541  tab1[fft_size_2 + i].im = -tab1[fft_size_2 - i].im;
542  }
543 
544  memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
545  tab2[1] = tab1[fft_size_2].re;
546 
547  rdft_calc(r, tab2);
548  fft_ref(tab_ref, tab1, fft_nbits);
549  for (i = 0; i < fft_size; i++) {
550  tab[i].re = tab2[i];
551  tab[i].im = 0;
552  }
553  err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 0.5);
554  } else {
555  for (i = 0; i < fft_size; i++) {
556  tab2[i] = tab1[i].re;
557  tab1[i].im = 0;
558  }
559  rdft_calc(r, tab2);
560  fft_ref(tab_ref, tab1, fft_nbits);
561  tab_ref[0].im = tab_ref[fft_size_2].re;
562  err = check_diff(&tab_ref->re, tab2, fft_size, 1.0);
563  }
564  break;
565  }
566 #endif /* CONFIG_RDFT */
567 #if CONFIG_DCT
568  case TRANSFORM_DCT:
569  memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
570  dct_calc(d, &tab->re);
571  if (do_inverse)
572  idct_ref(&tab_ref->re, &tab1->re, fft_nbits);
573  else
574  dct_ref(&tab_ref->re, &tab1->re, fft_nbits);
575  err = check_diff(&tab_ref->re, &tab->re, fft_size, 1.0);
576  break;
577 #endif /* CONFIG_DCT */
578 #endif /* FFT_FLOAT */
579  }
580 
581  /* do a speed test */
582 
583  if (do_speed) {
584  int64_t time_start, duration;
585  int nb_its;
586 
587  av_log(NULL, AV_LOG_INFO, "Speed test...\n");
588  /* we measure during about 1 seconds */
589  nb_its = 1;
590  for (;;) {
591  time_start = av_gettime_relative();
592  for (it = 0; it < nb_its; it++) {
593  switch (transform) {
594  case TRANSFORM_MDCT:
595  if (do_inverse)
596  imdct_calc(m, &tab->re, &tab1->re);
597  else
598  mdct_calc(m, &tab->re, &tab1->re);
599  break;
600  case TRANSFORM_FFT:
601  memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
602  fft_calc(s, tab);
603  break;
604 #if FFT_FLOAT
605  case TRANSFORM_RDFT:
606  memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
607  rdft_calc(r, tab2);
608  break;
609  case TRANSFORM_DCT:
610  memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
611  dct_calc(d, tab2);
612  break;
613 #endif /* FFT_FLOAT */
614  }
615  }
616  duration = av_gettime_relative() - time_start;
617  if (duration >= 1000000)
618  break;
619  nb_its *= 2;
620  }
622  "time: %0.1f us/transform [total time=%0.2f s its=%d]\n",
623  (double) duration / nb_its,
624  (double) duration / 1000000.0,
625  nb_its);
626  }
627 
628  switch (transform) {
629 #if CONFIG_MDCT
630  case TRANSFORM_MDCT:
631  mdct_end(m);
632  break;
633 #endif /* CONFIG_MDCT */
634  case TRANSFORM_FFT:
635  fft_end(s);
636  break;
637 #if FFT_FLOAT
638 # if CONFIG_RDFT
639  case TRANSFORM_RDFT:
640  rdft_end(r);
641  break;
642 # endif /* CONFIG_RDFT */
643 # if CONFIG_DCT
644  case TRANSFORM_DCT:
645  dct_end(d);
646  break;
647 # endif /* CONFIG_DCT */
648 #endif /* FFT_FLOAT */
649  }
650 
651 cleanup:
652  av_free(tab);
653  av_free(tab1);
654  av_free(tab2);
655  av_free(tab_ref);
656  av_free(exptab);
657 
658 #if !AVFFT
659  av_free(s);
660  av_free(m);
661 #endif
662 
663 #if !AVFFT && FFT_FLOAT
664  av_free(r);
665  av_free(d);
666 #endif
667 
668  if (err)
669  printf("Error: %d.\n", err);
670 
671  return !!err;
672 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
exptab
static struct @131 * exptab
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:70
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
mdct_init
static void mdct_init(FFTContext **s, int nbits, int inverse, double scale)
Definition: fft.c:228
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:365
im
float im
Definition: fft.c:78
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:128
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:98
c1
static const uint64_t c1
Definition: murmur3.c:51
CMAC
#define CMAC(pre, pim, are, aim, bre, bim)
Definition: fft.c:61
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:108
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:114
REF_SCALE
#define REF_SCALE(x, bits)
Definition: fft.c:73
tab2
const int16_t * tab2
Definition: mace.c:144
TRANSFORM_FFT
@ TRANSFORM_FFT
Definition: fft.c:362
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1388
frandom
static FFTSample frandom(AVLFG *prng)
Definition: fft.c:194
tab1
const int16_t * tab1
Definition: mace.c:144
main
int main(int argc, char **argv)
Definition: fft.c:372
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
s
#define s(width, name)
Definition: cbs_vp9.c:257
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:347
s1
#define s1
Definition: regdef.h:38
fft_end
static void fft_end(FFTContext *s)
Definition: fft.c:282
lfg.h
ff_fft_end
#define ff_fft_end
Definition: fft.h:136
f
#define f(width, name)
Definition: cbs_vp9.c:255
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:363
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:246
av_mdct_end
void av_mdct_end(FFTContext *s)
tf_transform
tf_transform
Definition: fft.c:361
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:264
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
fft_permute
static void fft_permute(FFTContext *s, FFTComplex *z)
Definition: fft.c:255
AVLFG
Context structure for the Lagged Fibonacci PRNG.
Definition: lfg.h:33
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:221
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:88
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:177
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
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:263
fft_ref_init
static int fft_ref_init(int nbits, int inverse)
Definition: fft.c:81
DCTContext
Definition: dct.h:32
fft_init
static void fft_init(FFTContext **s, int nbits, int inverse)
Definition: fft.c:219
mdct_end
static void mdct_end(FFTContext *s)
Definition: fft.c:273
dct_init
static av_cold int dct_init(MpegEncContext *s)
Definition: mpegvideo.c:284
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:199
inverse
static int inverse(AudioFWTDNContext *s, double **in, int *in_length, double *out, int out_length, int ch, uint64_t sn)
Definition: af_afwtdn.c:762
FMT
#define FMT
Definition: fft.c:74
optarg
static char * optarg
Definition: getopt.c:39
mdct_calc
static void mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
Definition: fft.c:237
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:72
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
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:100
TRANSFORM_RDFT
@ TRANSFORM_RDFT
Definition: fft.c:364
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:28
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:78