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;
47  int64_t pts;
48  int hop_size;
49  float overlap;
51  int eof;
52  int win_func;
55 
56 static const char *const var_names[] = { "sr", "b", "nb", "ch", "chs", "pts", "re", "im", NULL };
58 
59 #define OFFSET(x) offsetof(AFFTFiltContext, x)
60 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
61 
62 static const AVOption afftfilt_options[] = {
63  { "real", "set channels real expressions", OFFSET(real_str), AV_OPT_TYPE_STRING, {.str = "re" }, 0, 0, A },
64  { "imag", "set channels imaginary expressions", OFFSET(img_str), AV_OPT_TYPE_STRING, {.str = "im" }, 0, 0, A },
65  { "win_size", "set window size", OFFSET(fft_size), AV_OPT_TYPE_INT, {.i64=4096}, 16, 131072, A },
66  { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64 = WFUNC_HANNING}, 0, NB_WFUNC-1, A, "win_func" },
67  { "rect", "Rectangular", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_RECT}, 0, 0, A, "win_func" },
68  { "bartlett", "Bartlett", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BARTLETT}, 0, 0, A, "win_func" },
69  { "hann", "Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, A, "win_func" },
70  { "hanning", "Hanning", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, A, "win_func" },
71  { "hamming", "Hamming", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HAMMING}, 0, 0, A, "win_func" },
72  { "blackman", "Blackman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BLACKMAN}, 0, 0, A, "win_func" },
73  { "welch", "Welch", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_WELCH}, 0, 0, A, "win_func" },
74  { "flattop", "Flat-top", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_FLATTOP}, 0, 0, A, "win_func" },
75  { "bharris", "Blackman-Harris", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHARRIS}, 0, 0, A, "win_func" },
76  { "bnuttall", "Blackman-Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BNUTTALL}, 0, 0, A, "win_func" },
77  { "bhann", "Bartlett-Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHANN}, 0, 0, A, "win_func" },
78  { "sine", "Sine", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_SINE}, 0, 0, A, "win_func" },
79  { "nuttall", "Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_NUTTALL}, 0, 0, A, "win_func" },
80  { "lanczos", "Lanczos", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_LANCZOS}, 0, 0, A, "win_func" },
81  { "gauss", "Gauss", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_GAUSS}, 0, 0, A, "win_func" },
82  { "tukey", "Tukey", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_TUKEY}, 0, 0, A, "win_func" },
83  { "dolph", "Dolph-Chebyshev", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_DOLPH}, 0, 0, A, "win_func" },
84  { "cauchy", "Cauchy", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_CAUCHY}, 0, 0, A, "win_func" },
85  { "parzen", "Parzen", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_PARZEN}, 0, 0, A, "win_func" },
86  { "poisson", "Poisson", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_POISSON}, 0, 0, A, "win_func" },
87  { "bohman", "Bohman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BOHMAN}, 0, 0, A, "win_func" },
88  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, A },
89  { NULL },
90 };
91 
92 AVFILTER_DEFINE_CLASS(afftfilt);
93 
94 static inline double getreal(void *priv, double x, double ch)
95 {
96  AFFTFiltContext *s = priv;
97  int ich, ix;
98 
99  ich = av_clip(ch, 0, s->nb_exprs - 1);
100  ix = av_clip(x, 0, s->window_size / 2);
101 
102  return s->fft_data[ich][ix].re;
103 }
104 
105 static inline double getimag(void *priv, double x, double ch)
106 {
107  AFFTFiltContext *s = priv;
108  int ich, ix;
109 
110  ich = av_clip(ch, 0, s->nb_exprs - 1);
111  ix = av_clip(x, 0, s->window_size / 2);
112 
113  return s->fft_data[ich][ix].im;
114 }
115 
116 static double realf(void *priv, double x, double ch) { return getreal(priv, x, ch); }
117 static double imagf(void *priv, double x, double ch) { return getimag(priv, x, ch); }
118 
119 static const char *const func2_names[] = { "real", "imag", NULL };
120 double (*func2[])(void *, double, double) = { realf, imagf, NULL };
121 
123 {
124  AVFilterContext *ctx = inlink->dst;
125  AFFTFiltContext *s = ctx->priv;
126  char *saveptr = NULL;
127  int ret = 0, ch;
128  float overlap;
129  char *args;
130  const char *last_expr = "1";
131 
132  s->pts = AV_NOPTS_VALUE;
133  s->fft_bits = av_log2(s->fft_size);
134  s->fft = av_fft_init(s->fft_bits, 0);
135  s->ifft = av_fft_init(s->fft_bits, 1);
136  if (!s->fft || !s->ifft)
137  return AVERROR(ENOMEM);
138 
139  s->window_size = 1 << s->fft_bits;
140 
141  s->fft_data = av_calloc(inlink->channels, sizeof(*s->fft_data));
142  if (!s->fft_data)
143  return AVERROR(ENOMEM);
144 
145  s->fft_temp = av_calloc(inlink->channels, sizeof(*s->fft_temp));
146  if (!s->fft_temp)
147  return AVERROR(ENOMEM);
148 
149  for (ch = 0; ch < inlink->channels; ch++) {
150  s->fft_data[ch] = av_calloc(s->window_size, sizeof(**s->fft_data));
151  if (!s->fft_data[ch])
152  return AVERROR(ENOMEM);
153  }
154 
155  for (ch = 0; ch < inlink->channels; ch++) {
156  s->fft_temp[ch] = av_calloc(s->window_size, sizeof(**s->fft_temp));
157  if (!s->fft_temp[ch])
158  return AVERROR(ENOMEM);
159  }
160 
161  s->real = av_calloc(inlink->channels, sizeof(*s->real));
162  if (!s->real)
163  return AVERROR(ENOMEM);
164 
165  s->imag = av_calloc(inlink->channels, sizeof(*s->imag));
166  if (!s->imag)
167  return AVERROR(ENOMEM);
168 
169  args = av_strdup(s->real_str);
170  if (!args)
171  return AVERROR(ENOMEM);
172 
173  for (ch = 0; ch < inlink->channels; ch++) {
174  char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr);
175 
176  ret = av_expr_parse(&s->real[ch], arg ? arg : last_expr, var_names,
177  NULL, NULL, func2_names, func2, 0, ctx);
178  if (ret < 0)
179  break;
180  if (arg)
181  last_expr = arg;
182  s->nb_exprs++;
183  }
184 
185  av_free(args);
186 
187  args = av_strdup(s->img_str ? s->img_str : s->real_str);
188  if (!args)
189  return AVERROR(ENOMEM);
190 
191  saveptr = NULL;
192  last_expr = "1";
193  for (ch = 0; ch < inlink->channels; ch++) {
194  char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr);
195 
196  ret = av_expr_parse(&s->imag[ch], arg ? arg : last_expr, var_names,
197  NULL, NULL, func2_names, func2, 0, ctx);
198  if (ret < 0)
199  break;
200  if (arg)
201  last_expr = arg;
202  }
203 
204  av_free(args);
205 
206  s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size);
207  if (!s->fifo)
208  return AVERROR(ENOMEM);
209 
211  sizeof(*s->window_func_lut));
212  if (!s->window_func_lut)
213  return AVERROR(ENOMEM);
215  if (s->overlap == 1)
216  s->overlap = overlap;
217 
218  s->hop_size = s->window_size * (1 - s->overlap);
219  if (s->hop_size <= 0)
220  return AVERROR(EINVAL);
221 
222  s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2);
223  if (!s->buffer)
224  return AVERROR(ENOMEM);
225 
226  return ret;
227 }
228 
230 {
231  AVFilterContext *ctx = inlink->dst;
232  AVFilterLink *outlink = ctx->outputs[0];
233  AFFTFiltContext *s = ctx->priv;
234  const int window_size = s->window_size;
235  const float f = 1. / (s->window_size / 2);
236  double values[VAR_VARS_NB];
237  AVFrame *out, *in = NULL;
238  int ch, n, ret, i;
239 
240  if (!in) {
241  in = ff_get_audio_buffer(outlink, window_size);
242  if (!in)
243  return AVERROR(ENOMEM);
244  }
245 
246  ret = av_audio_fifo_peek(s->fifo, (void **)in->extended_data, window_size);
247  if (ret < 0)
248  goto fail;
249 
250  for (ch = 0; ch < inlink->channels; ch++) {
251  const float *src = (float *)in->extended_data[ch];
252  FFTComplex *fft_data = s->fft_data[ch];
253 
254  for (n = 0; n < in->nb_samples; n++) {
255  fft_data[n].re = src[n] * s->window_func_lut[n];
256  fft_data[n].im = 0;
257  }
258 
259  for (; n < window_size; n++) {
260  fft_data[n].re = 0;
261  fft_data[n].im = 0;
262  }
263  }
264 
265  values[VAR_PTS] = s->pts;
266  values[VAR_SAMPLE_RATE] = inlink->sample_rate;
267  values[VAR_NBBINS] = window_size / 2;
268  values[VAR_CHANNELS] = inlink->channels;
269 
270  for (ch = 0; ch < inlink->channels; ch++) {
272 
273  av_fft_permute(s->fft, fft_data);
274  av_fft_calc(s->fft, fft_data);
275  }
276 
277  for (ch = 0; ch < inlink->channels; ch++) {
280  float *buf = (float *)s->buffer->extended_data[ch];
281  int x;
282  values[VAR_CHANNEL] = ch;
283 
284  for (n = 0; n <= window_size / 2; n++) {
285  float fr, fi;
286 
287  values[VAR_BIN] = n;
288  values[VAR_REAL] = fft_data[n].re;
289  values[VAR_IMAG] = fft_data[n].im;
290 
291  fr = av_expr_eval(s->real[ch], values, s);
292  fi = av_expr_eval(s->imag[ch], values, s);
293 
294  fft_temp[n].re = fr;
295  fft_temp[n].im = fi;
296  }
297 
298  for (n = window_size / 2 + 1, x = window_size / 2 - 1; n < window_size; n++, x--) {
299  fft_temp[n].re = fft_temp[x].re;
300  fft_temp[n].im = -fft_temp[x].im;
301  }
302 
303  av_fft_permute(s->ifft, fft_temp);
304  av_fft_calc(s->ifft, fft_temp);
305 
306  for (i = 0; i < window_size; i++) {
307  buf[i] += s->fft_temp[ch][i].re * f;
308  }
309  }
310 
311  out = ff_get_audio_buffer(outlink, s->hop_size);
312  if (!out) {
313  ret = AVERROR(ENOMEM);
314  goto fail;
315  }
316 
317  out->pts = s->pts;
318  s->pts += s->hop_size;
319 
320  for (ch = 0; ch < inlink->channels; ch++) {
321  float *dst = (float *)out->extended_data[ch];
322  float *buf = (float *)s->buffer->extended_data[ch];
323 
324  for (n = 0; n < s->hop_size; n++)
325  dst[n] = buf[n] * (1.f - s->overlap);
326  memmove(buf, buf + s->hop_size, window_size * 4);
327  }
328 
329  ret = ff_filter_frame(outlink, out);
330  if (ret < 0)
331  goto fail;
332 
334 
335 fail:
336  av_frame_free(&in);
337  return ret < 0 ? ret : 0;
338 }
339 
341 {
342  AVFilterLink *inlink = ctx->inputs[0];
343  AVFilterLink *outlink = ctx->outputs[0];
344  AFFTFiltContext *s = ctx->priv;
345  AVFrame *in = NULL;
346  int ret = 0, status;
347  int64_t pts;
348 
349  FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
350 
351  if (!s->eof && av_audio_fifo_size(s->fifo) < s->window_size) {
352  ret = ff_inlink_consume_frame(inlink, &in);
353  if (ret < 0)
354  return ret;
355 
356  if (ret > 0) {
357  ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
358  in->nb_samples);
359  if (ret >= 0 && s->pts == AV_NOPTS_VALUE)
360  s->pts = in->pts;
361 
362  av_frame_free(&in);
363  if (ret < 0)
364  return ret;
365  }
366  }
367 
368  if ((av_audio_fifo_size(s->fifo) >= s->window_size) ||
369  (av_audio_fifo_size(s->fifo) > 0 && s->eof)) {
370  ret = filter_frame(inlink);
371  if (av_audio_fifo_size(s->fifo) >= s->window_size)
372  ff_filter_set_ready(ctx, 100);
373  return ret;
374  }
375 
376  if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
377  if (status == AVERROR_EOF) {
378  s->eof = 1;
379  if (av_audio_fifo_size(s->fifo) >= 0) {
380  ff_filter_set_ready(ctx, 100);
381  return 0;
382  }
383  }
384  }
385 
386  if (s->eof && av_audio_fifo_size(s->fifo) <= 0) {
387  ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
388  return 0;
389  }
390 
391  if (!s->eof)
392  FF_FILTER_FORWARD_WANTED(outlink, inlink);
393 
394  return FFERROR_NOT_READY;
395 }
396 
398 {
401  static const enum AVSampleFormat sample_fmts[] = {
404  };
405  int ret;
406 
407  layouts = ff_all_channel_counts();
408  if (!layouts)
409  return AVERROR(ENOMEM);
410  ret = ff_set_common_channel_layouts(ctx, layouts);
411  if (ret < 0)
412  return ret;
413 
414  formats = ff_make_format_list(sample_fmts);
415  if (!formats)
416  return AVERROR(ENOMEM);
417  ret = ff_set_common_formats(ctx, formats);
418  if (ret < 0)
419  return ret;
420 
421  formats = ff_all_samplerates();
422  if (!formats)
423  return AVERROR(ENOMEM);
424  return ff_set_common_samplerates(ctx, formats);
425 }
426 
428 {
429  AFFTFiltContext *s = ctx->priv;
430  int i;
431 
432  av_fft_end(s->fft);
433  av_fft_end(s->ifft);
434 
435  for (i = 0; i < s->nb_exprs; i++) {
436  if (s->fft_data)
437  av_freep(&s->fft_data[i]);
438  if (s->fft_temp)
439  av_freep(&s->fft_temp[i]);
440  }
441  av_freep(&s->fft_data);
442  av_freep(&s->fft_temp);
443 
444  for (i = 0; i < s->nb_exprs; i++) {
445  av_expr_free(s->real[i]);
446  av_expr_free(s->imag[i]);
447  }
448 
449  av_freep(&s->real);
450  av_freep(&s->imag);
451  av_frame_free(&s->buffer);
453 
455 }
456 
457 static const AVFilterPad inputs[] = {
458  {
459  .name = "default",
460  .type = AVMEDIA_TYPE_AUDIO,
461  .config_props = config_input,
462  },
463  { NULL }
464 };
465 
466 static const AVFilterPad outputs[] = {
467  {
468  .name = "default",
469  .type = AVMEDIA_TYPE_AUDIO,
470  },
471  { NULL }
472 };
473 
475  .name = "afftfilt",
476  .description = NULL_IF_CONFIG_SMALL("Apply arbitrary expressions to samples in frequency domain."),
477  .priv_size = sizeof(AFFTFiltContext),
478  .priv_class = &afftfilt_class,
479  .inputs = inputs,
480  .outputs = outputs,
481  .activate = activate,
483  .uninit = uninit,
484 };
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:1494
#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:46
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:44
static int config_input(AVFilterLink *inlink)
Definition: af_afftfilt.c:122
static const char *const var_names[]
Definition: af_afftfilt.c:56
static double realf(void *priv, double x, double ch)
Definition: af_afftfilt.c:116
int av_log2(unsigned v)
Definition: intmath.c:26
#define OFFSET(x)
Definition: af_afftfilt.c:59
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:683
return FFERROR_NOT_READY
#define src
Definition: vp8dsp.c:254
static int filter_frame(AVFilterLink *inlink)
Definition: af_afftfilt.c:229
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:427
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:474
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1093
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:60
#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
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:1449
static double imagf(void *priv, double x, double ch)
Definition: af_afftfilt.c:117
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:397
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:466
A list of supported channel layouts.
Definition: formats.h:85
static double getreal(void *priv, double x, double ch)
Definition: af_afftfilt.c:94
static const AVFilterPad inputs[]
Definition: af_afftfilt.c:457
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:53
double(* func2[])(void *, double, double)
Definition: af_afftfilt.c:120
void * buf
Definition: avisynth_c.h:766
AVExpr ** imag
Definition: af_afftfilt.c:45
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
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:62
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:50
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:119
static double getimag(void *priv, double x, double ch)
Definition: af_afftfilt.c:105
#define av_free(p)
Audio FIFO Buffer.
static int activate(AVFilterContext *ctx)
Definition: af_afftfilt.c:340
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:738
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