FFmpeg
af_afftfilt.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 2.1 of the License,
9  * 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 #include "libavutil/audio_fifo.h"
22 #include "libavutil/avstring.h"
23 #include "libavfilter/internal.h"
24 #include "libavutil/common.h"
25 #include "libavutil/opt.h"
26 #include "libavcodec/avfft.h"
27 #include "libavutil/eval.h"
28 #include "audio.h"
29 #include "filters.h"
30 #include "window_func.h"
31 
32 typedef struct AFFTFiltContext {
33  const AVClass *class;
34  char *real_str;
35  char *img_str;
36  int fft_size;
37  int fft_bits;
38 
42  int nb_exprs;
43  int channels;
48  int64_t pts;
49  int hop_size;
50  float overlap;
52  int eof;
53  int win_func;
56 
57 static const char *const var_names[] = { "sr", "b", "nb", "ch", "chs", "pts", "re", "im", NULL };
59 
60 #define OFFSET(x) offsetof(AFFTFiltContext, x)
61 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
62 
63 static const AVOption afftfilt_options[] = {
64  { "real", "set channels real expressions", OFFSET(real_str), AV_OPT_TYPE_STRING, {.str = "re" }, 0, 0, A },
65  { "imag", "set channels imaginary expressions", OFFSET(img_str), AV_OPT_TYPE_STRING, {.str = "im" }, 0, 0, A },
66  { "win_size", "set window size", OFFSET(fft_size), AV_OPT_TYPE_INT, {.i64=4096}, 16, 131072, A },
67  { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64 = WFUNC_HANNING}, 0, NB_WFUNC-1, A, "win_func" },
68  { "rect", "Rectangular", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_RECT}, 0, 0, A, "win_func" },
69  { "bartlett", "Bartlett", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BARTLETT}, 0, 0, A, "win_func" },
70  { "hann", "Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, A, "win_func" },
71  { "hanning", "Hanning", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, A, "win_func" },
72  { "hamming", "Hamming", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HAMMING}, 0, 0, A, "win_func" },
73  { "blackman", "Blackman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BLACKMAN}, 0, 0, A, "win_func" },
74  { "welch", "Welch", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_WELCH}, 0, 0, A, "win_func" },
75  { "flattop", "Flat-top", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_FLATTOP}, 0, 0, A, "win_func" },
76  { "bharris", "Blackman-Harris", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHARRIS}, 0, 0, A, "win_func" },
77  { "bnuttall", "Blackman-Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BNUTTALL}, 0, 0, A, "win_func" },
78  { "bhann", "Bartlett-Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHANN}, 0, 0, A, "win_func" },
79  { "sine", "Sine", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_SINE}, 0, 0, A, "win_func" },
80  { "nuttall", "Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_NUTTALL}, 0, 0, A, "win_func" },
81  { "lanczos", "Lanczos", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_LANCZOS}, 0, 0, A, "win_func" },
82  { "gauss", "Gauss", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_GAUSS}, 0, 0, A, "win_func" },
83  { "tukey", "Tukey", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_TUKEY}, 0, 0, A, "win_func" },
84  { "dolph", "Dolph-Chebyshev", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_DOLPH}, 0, 0, A, "win_func" },
85  { "cauchy", "Cauchy", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_CAUCHY}, 0, 0, A, "win_func" },
86  { "parzen", "Parzen", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_PARZEN}, 0, 0, A, "win_func" },
87  { "poisson", "Poisson", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_POISSON}, 0, 0, A, "win_func" },
88  { "bohman", "Bohman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BOHMAN}, 0, 0, A, "win_func" },
89  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, A },
90  { NULL },
91 };
92 
93 AVFILTER_DEFINE_CLASS(afftfilt);
94 
95 static inline double getreal(void *priv, double x, double ch)
96 {
97  AFFTFiltContext *s = priv;
98  int ich, ix;
99 
100  ich = av_clip(ch, 0, s->nb_exprs - 1);
101  ix = av_clip(x, 0, s->window_size / 2);
102 
103  return s->fft_data[ich][ix].re;
104 }
105 
106 static inline double getimag(void *priv, double x, double ch)
107 {
108  AFFTFiltContext *s = priv;
109  int ich, ix;
110 
111  ich = av_clip(ch, 0, s->nb_exprs - 1);
112  ix = av_clip(x, 0, s->window_size / 2);
113 
114  return s->fft_data[ich][ix].im;
115 }
116 
117 static double realf(void *priv, double x, double ch) { return getreal(priv, x, ch); }
118 static double imagf(void *priv, double x, double ch) { return getimag(priv, x, ch); }
119 
120 static const char *const func2_names[] = { "real", "imag", NULL };
121 double (*func2[])(void *, double, double) = { realf, imagf, NULL };
122 
124 {
125  AVFilterContext *ctx = inlink->dst;
126  AFFTFiltContext *s = ctx->priv;
127  char *saveptr = NULL;
128  int ret = 0, ch;
129  float overlap;
130  char *args;
131  const char *last_expr = "1";
132 
133  s->channels = inlink->channels;
134  s->pts = AV_NOPTS_VALUE;
135  s->fft_bits = av_log2(s->fft_size);
136  s->fft = av_fft_init(s->fft_bits, 0);
137  s->ifft = av_fft_init(s->fft_bits, 1);
138  if (!s->fft || !s->ifft)
139  return AVERROR(ENOMEM);
140 
141  s->window_size = 1 << s->fft_bits;
142 
143  s->fft_data = av_calloc(inlink->channels, sizeof(*s->fft_data));
144  if (!s->fft_data)
145  return AVERROR(ENOMEM);
146 
147  s->fft_temp = av_calloc(inlink->channels, sizeof(*s->fft_temp));
148  if (!s->fft_temp)
149  return AVERROR(ENOMEM);
150 
151  for (ch = 0; ch < inlink->channels; ch++) {
152  s->fft_data[ch] = av_calloc(s->window_size, sizeof(**s->fft_data));
153  if (!s->fft_data[ch])
154  return AVERROR(ENOMEM);
155  }
156 
157  for (ch = 0; ch < inlink->channels; ch++) {
158  s->fft_temp[ch] = av_calloc(s->window_size, sizeof(**s->fft_temp));
159  if (!s->fft_temp[ch])
160  return AVERROR(ENOMEM);
161  }
162 
163  s->real = av_calloc(inlink->channels, sizeof(*s->real));
164  if (!s->real)
165  return AVERROR(ENOMEM);
166 
167  s->imag = av_calloc(inlink->channels, sizeof(*s->imag));
168  if (!s->imag)
169  return AVERROR(ENOMEM);
170 
171  args = av_strdup(s->real_str);
172  if (!args)
173  return AVERROR(ENOMEM);
174 
175  for (ch = 0; ch < inlink->channels; ch++) {
176  char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr);
177 
178  ret = av_expr_parse(&s->real[ch], arg ? arg : last_expr, var_names,
179  NULL, NULL, func2_names, func2, 0, ctx);
180  if (ret < 0)
181  goto fail;
182  if (arg)
183  last_expr = arg;
184  s->nb_exprs++;
185  }
186 
187  av_freep(&args);
188 
189  args = av_strdup(s->img_str ? s->img_str : s->real_str);
190  if (!args)
191  return AVERROR(ENOMEM);
192 
193  saveptr = NULL;
194  last_expr = "1";
195  for (ch = 0; ch < inlink->channels; ch++) {
196  char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr);
197 
198  ret = av_expr_parse(&s->imag[ch], arg ? arg : last_expr, var_names,
199  NULL, NULL, func2_names, func2, 0, ctx);
200  if (ret < 0)
201  goto fail;
202  if (arg)
203  last_expr = arg;
204  }
205 
206  av_freep(&args);
207 
208  s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size);
209  if (!s->fifo)
210  return AVERROR(ENOMEM);
211 
213  sizeof(*s->window_func_lut));
214  if (!s->window_func_lut)
215  return AVERROR(ENOMEM);
217  if (s->overlap == 1)
218  s->overlap = overlap;
219 
220  s->hop_size = s->window_size * (1 - s->overlap);
221  if (s->hop_size <= 0)
222  return AVERROR(EINVAL);
223 
224  s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2);
225  if (!s->buffer)
226  return AVERROR(ENOMEM);
227 
228 fail:
229  av_freep(&args);
230 
231  return ret;
232 }
233 
235 {
236  AVFilterContext *ctx = inlink->dst;
237  AVFilterLink *outlink = ctx->outputs[0];
238  AFFTFiltContext *s = ctx->priv;
239  const int window_size = s->window_size;
240  const float f = 1. / (s->window_size / 2);
241  double values[VAR_VARS_NB];
242  AVFrame *out, *in = NULL;
243  int ch, n, ret, i;
244 
245  if (!in) {
246  in = ff_get_audio_buffer(outlink, window_size);
247  if (!in)
248  return AVERROR(ENOMEM);
249  }
250 
251  ret = av_audio_fifo_peek(s->fifo, (void **)in->extended_data, window_size);
252  if (ret < 0)
253  goto fail;
254 
255  for (ch = 0; ch < inlink->channels; ch++) {
256  const float *src = (float *)in->extended_data[ch];
257  FFTComplex *fft_data = s->fft_data[ch];
258 
259  for (n = 0; n < in->nb_samples; n++) {
260  fft_data[n].re = src[n] * s->window_func_lut[n];
261  fft_data[n].im = 0;
262  }
263 
264  for (; n < window_size; n++) {
265  fft_data[n].re = 0;
266  fft_data[n].im = 0;
267  }
268  }
269 
270  values[VAR_PTS] = s->pts;
271  values[VAR_SAMPLE_RATE] = inlink->sample_rate;
272  values[VAR_NBBINS] = window_size / 2;
273  values[VAR_CHANNELS] = inlink->channels;
274 
275  for (ch = 0; ch < inlink->channels; ch++) {
277 
278  av_fft_permute(s->fft, fft_data);
279  av_fft_calc(s->fft, fft_data);
280  }
281 
282  for (ch = 0; ch < inlink->channels; ch++) {
285  float *buf = (float *)s->buffer->extended_data[ch];
286  int x;
287  values[VAR_CHANNEL] = ch;
288 
289  for (n = 0; n <= window_size / 2; n++) {
290  float fr, fi;
291 
292  values[VAR_BIN] = n;
293  values[VAR_REAL] = fft_data[n].re;
294  values[VAR_IMAG] = fft_data[n].im;
295 
296  fr = av_expr_eval(s->real[ch], values, s);
297  fi = av_expr_eval(s->imag[ch], values, s);
298 
299  fft_temp[n].re = fr;
300  fft_temp[n].im = fi;
301  }
302 
303  for (n = window_size / 2 + 1, x = window_size / 2 - 1; n < window_size; n++, x--) {
304  fft_temp[n].re = fft_temp[x].re;
305  fft_temp[n].im = -fft_temp[x].im;
306  }
307 
308  av_fft_permute(s->ifft, fft_temp);
309  av_fft_calc(s->ifft, fft_temp);
310 
311  for (i = 0; i < window_size; i++) {
312  buf[i] += s->fft_temp[ch][i].re * f;
313  }
314  }
315 
316  out = ff_get_audio_buffer(outlink, s->hop_size);
317  if (!out) {
318  ret = AVERROR(ENOMEM);
319  goto fail;
320  }
321 
322  out->pts = s->pts;
323  s->pts += av_rescale_q(s->hop_size, (AVRational){1, outlink->sample_rate}, outlink->time_base);
324 
325  for (ch = 0; ch < inlink->channels; ch++) {
326  float *dst = (float *)out->extended_data[ch];
327  float *buf = (float *)s->buffer->extended_data[ch];
328 
329  for (n = 0; n < s->hop_size; n++)
330  dst[n] = buf[n] * (1.f - s->overlap);
331  memmove(buf, buf + s->hop_size, window_size * 4);
332  }
333 
334  ret = ff_filter_frame(outlink, out);
335  if (ret < 0)
336  goto fail;
337 
339 
340 fail:
341  av_frame_free(&in);
342  return ret < 0 ? ret : 0;
343 }
344 
346 {
347  AVFilterLink *inlink = ctx->inputs[0];
348  AVFilterLink *outlink = ctx->outputs[0];
349  AFFTFiltContext *s = ctx->priv;
350  AVFrame *in = NULL;
351  int ret = 0, status;
352  int64_t pts;
353 
354  FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
355 
356  if (!s->eof && av_audio_fifo_size(s->fifo) < s->window_size) {
357  ret = ff_inlink_consume_frame(inlink, &in);
358  if (ret < 0)
359  return ret;
360 
361  if (ret > 0) {
362  ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
363  in->nb_samples);
364  if (ret >= 0 && s->pts == AV_NOPTS_VALUE)
365  s->pts = in->pts;
366 
367  av_frame_free(&in);
368  if (ret < 0)
369  return ret;
370  }
371  }
372 
373  if ((av_audio_fifo_size(s->fifo) >= s->window_size) ||
374  (av_audio_fifo_size(s->fifo) > 0 && s->eof)) {
375  ret = filter_frame(inlink);
376  if (av_audio_fifo_size(s->fifo) >= s->window_size)
377  ff_filter_set_ready(ctx, 100);
378  return ret;
379  }
380 
381  if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
382  if (status == AVERROR_EOF) {
383  s->eof = 1;
384  if (av_audio_fifo_size(s->fifo) >= 0) {
385  ff_filter_set_ready(ctx, 100);
386  return 0;
387  }
388  }
389  }
390 
391  if (s->eof && av_audio_fifo_size(s->fifo) <= 0) {
392  ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
393  return 0;
394  }
395 
396  if (!s->eof)
397  FF_FILTER_FORWARD_WANTED(outlink, inlink);
398 
399  return FFERROR_NOT_READY;
400 }
401 
403 {
406  static const enum AVSampleFormat sample_fmts[] = {
409  };
410  int ret;
411 
412  layouts = ff_all_channel_counts();
413  if (!layouts)
414  return AVERROR(ENOMEM);
415  ret = ff_set_common_channel_layouts(ctx, layouts);
416  if (ret < 0)
417  return ret;
418 
419  formats = ff_make_format_list(sample_fmts);
420  if (!formats)
421  return AVERROR(ENOMEM);
422  ret = ff_set_common_formats(ctx, formats);
423  if (ret < 0)
424  return ret;
425 
426  formats = ff_all_samplerates();
427  if (!formats)
428  return AVERROR(ENOMEM);
429  return ff_set_common_samplerates(ctx, formats);
430 }
431 
433 {
434  AFFTFiltContext *s = ctx->priv;
435  int i;
436 
437  av_fft_end(s->fft);
438  av_fft_end(s->ifft);
439 
440  for (i = 0; i < s->channels; i++) {
441  if (s->fft_data)
442  av_freep(&s->fft_data[i]);
443  if (s->fft_temp)
444  av_freep(&s->fft_temp[i]);
445  }
446  av_freep(&s->fft_data);
447  av_freep(&s->fft_temp);
448 
449  for (i = 0; i < s->nb_exprs; i++) {
450  av_expr_free(s->real[i]);
451  av_expr_free(s->imag[i]);
452  }
453 
454  av_freep(&s->real);
455  av_freep(&s->imag);
456  av_frame_free(&s->buffer);
458 
460 }
461 
462 static const AVFilterPad inputs[] = {
463  {
464  .name = "default",
465  .type = AVMEDIA_TYPE_AUDIO,
466  .config_props = config_input,
467  },
468  { NULL }
469 };
470 
471 static const AVFilterPad outputs[] = {
472  {
473  .name = "default",
474  .type = AVMEDIA_TYPE_AUDIO,
475  },
476  { NULL }
477 };
478 
480  .name = "afftfilt",
481  .description = NULL_IF_CONFIG_SMALL("Apply arbitrary expressions to samples in frequency domain."),
482  .priv_size = sizeof(AFFTFiltContext),
483  .priv_class = &afftfilt_class,
484  .inputs = inputs,
485  .outputs = outputs,
486  .activate = activate,
488  .uninit = uninit,
489 };
float, planar
Definition: samplefmt.h:69
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link&#39;s FIFO and update the link&#39;s stats.
Definition: avfilter.c:1476
#define NULL
Definition: coverity.c:32
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates...
Definition: formats.c:550
FFTContext * fft
Definition: af_afftfilt.c:39
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition: audio_fifo.c:59
#define av_realloc_f(p, o, n)
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVOption.
Definition: opt.h:246
AVAudioFifo * fifo
Definition: af_afftfilt.c:47
av_cold void av_fft_end(FFTContext *s)
Definition: avfft.c:48
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:45
AVExpr ** real
Definition: af_afftfilt.c:45
static int config_input(AVFilterLink *inlink)
Definition: af_afftfilt.c:123
static const char *const var_names[]
Definition: af_afftfilt.c:57
static double realf(void *priv, double x, double ch)
Definition: af_afftfilt.c:117
int av_log2(unsigned v)
Definition: intmath.c:26
#define OFFSET(x)
Definition: af_afftfilt.c:60
FFTSample re
Definition: avfft.h:38
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
Definition: avfft.c:38
static void generate_window_func(float *lut, int N, int win_func, float *overlap)
Definition: window_func.h:36
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:685
return FFERROR_NOT_READY
#define src
Definition: vp8dsp.c:254
static int filter_frame(AVFilterLink *inlink)
Definition: af_afftfilt.c:234
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_afftfilt.c:432
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
AVFilter ff_af_afftfilt
Definition: af_afftfilt.c:479
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1075
FFTComplex ** fft_data
Definition: af_afftfilt.c:40
#define av_cold
Definition: attributes.h:82
AVOptions.
#define f(width, name)
Definition: cbs_vp9.c:255
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
Definition: eval.c:157
FFTComplex ** fft_temp
Definition: af_afftfilt.c:41
#define A
Definition: af_afftfilt.c:61
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
A filter pad used for either input or output.
Definition: internal.h:54
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1431
static double imagf(void *priv, double x, double ch)
Definition: af_afftfilt.c:118
AVS_FilterInfo ** fi
Definition: avisynth_c.h:807
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:569
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void * priv
private data for use by the filter
Definition: avfilter.h:353
const char * arg
Definition: jacosubdec.c:66
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
Definition: avfft.c:28
#define fail()
Definition: checkasm.h:122
Context for an Audio FIFO Buffer.
Definition: audio_fifo.c:34
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition: audio_fifo.c:228
Definition: fft.h:88
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return values
static int query_formats(AVFilterContext *ctx)
Definition: af_afftfilt.c:402
AVS_Value args
Definition: avisynth_c.h:775
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
int n
Definition: avisynth_c.h:760
static const AVFilterPad outputs[]
Definition: af_afftfilt.c:471
A list of supported channel layouts.
Definition: formats.h:85
static double getreal(void *priv, double x, double ch)
Definition: af_afftfilt.c:95
static const AVFilterPad inputs[]
Definition: af_afftfilt.c:462
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
FFT functions.
float * window_func_lut
Definition: af_afftfilt.c:54
double(* func2[])(void *, double, double)
Definition: af_afftfilt.c:121
void * buf
Definition: avisynth_c.h:766
AVExpr ** imag
Definition: af_afftfilt.c:46
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
FFTContext * ifft
Definition: af_afftfilt.c:39
Rational number (pair of numerator and denominator).
Definition: rational.h:58
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
static const AVOption afftfilt_options[]
Definition: af_afftfilt.c:63
const char * name
Filter name.
Definition: avfilter.h:148
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0f/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(UINT64_C(1)<< 63)))#define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};static void cpy1(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, len);}static void cpy2(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 2 *len);}static void cpy4(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 4 *len);}static void cpy8(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;}void swri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len){int ch;int off=0;const int os=(out->planar?1:out->ch_count)*out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){int planes=in->planar?in->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){int planes=out->planar?out->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){int planes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:394
AVFrame * buffer
Definition: af_afftfilt.c:51
int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples)
Write data to an AVAudioFifo.
Definition: audio_fifo.c:112
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
Drain data from an AVAudioFifo.
Definition: audio_fifo.c:201
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok()...
Definition: avstring.c:184
FFTSample im
Definition: avfft.h:38
common internal and external API header
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:193
AVFILTER_DEFINE_CLASS(afftfilt)
FF_FILTER_FORWARD_WANTED(outlink, inlink)
static const char *const func2_names[]
Definition: af_afftfilt.c:120
static double getimag(void *priv, double x, double ch)
Definition: af_afftfilt.c:106
Audio FIFO Buffer.
static int activate(AVFilterContext *ctx)
Definition: af_afftfilt.c:345
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:766
A list of supported formats for one end of a filter link.
Definition: formats.h:64
int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples)
Peek data from an AVAudioFifo.
Definition: audio_fifo.c:138
An instance of a filter.
Definition: avfilter.h:338
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
FILE * out
Definition: movenc.c:54
#define av_freep(p)
formats
Definition: signature.h:48
internal API functions
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
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition...
Definition: formats.c:409
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:342
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
Definition: avfft.c:43
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:361
for(j=16;j >0;--j)
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:557
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
simple arithmetic expression evaluator