FFmpeg
af_aiir.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Paul B Mahol
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 #include <float.h>
22 
23 #include "libavutil/avassert.h"
24 #include "libavutil/avstring.h"
25 #include "libavutil/intreadwrite.h"
26 #include "libavutil/opt.h"
28 #include "audio.h"
29 #include "avfilter.h"
30 #include "internal.h"
31 
32 typedef struct ThreadData {
33  AVFrame *in, *out;
34 } ThreadData;
35 
36 typedef struct Pair {
37  int a, b;
38 } Pair;
39 
40 typedef struct BiquadContext {
41  double a0, a1, a2;
42  double b0, b1, b2;
43  double i1, i2;
44  double o1, o2;
46 
47 typedef struct IIRChannel {
48  int nb_ab[2];
49  double *ab[2];
50  double g;
51  double *cache[2];
53  int clippings;
54 } IIRChannel;
55 
56 typedef struct AudioIIRContext {
57  const AVClass *class;
58  char *a_str, *b_str, *g_str;
59  double dry_gain, wet_gain;
60  double mix;
61  int format;
62  int process;
63  int precision;
64  int response;
65  int w, h;
68 
70 
72  int channels;
73  enum AVSampleFormat sample_format;
74 
75  int (*iir_channel)(AVFilterContext *ctx, void *arg, int ch, int nb_jobs);
77 
79 {
80  AudioIIRContext *s = ctx->priv;
83  enum AVSampleFormat sample_fmts[] = {
86  };
87  static const enum AVPixelFormat pix_fmts[] = {
90  };
91  int ret;
92 
93  if (s->response) {
94  AVFilterLink *videolink = ctx->outputs[1];
95 
96  formats = ff_make_format_list(pix_fmts);
97  if ((ret = ff_formats_ref(formats, &videolink->in_formats)) < 0)
98  return ret;
99  }
100 
101  layouts = ff_all_channel_counts();
102  if (!layouts)
103  return AVERROR(ENOMEM);
104  ret = ff_set_common_channel_layouts(ctx, layouts);
105  if (ret < 0)
106  return ret;
107 
108  sample_fmts[0] = s->sample_format;
109  formats = ff_make_format_list(sample_fmts);
110  if (!formats)
111  return AVERROR(ENOMEM);
112  ret = ff_set_common_formats(ctx, formats);
113  if (ret < 0)
114  return ret;
115 
116  formats = ff_all_samplerates();
117  if (!formats)
118  return AVERROR(ENOMEM);
119  return ff_set_common_samplerates(ctx, formats);
120 }
121 
122 #define IIR_CH(name, type, min, max, need_clipping) \
123 static int iir_ch_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \
124 { \
125  AudioIIRContext *s = ctx->priv; \
126  const double ig = s->dry_gain; \
127  const double og = s->wet_gain; \
128  const double mix = s->mix; \
129  ThreadData *td = arg; \
130  AVFrame *in = td->in, *out = td->out; \
131  const type *src = (const type *)in->extended_data[ch]; \
132  double *ic = (double *)s->iir[ch].cache[0]; \
133  double *oc = (double *)s->iir[ch].cache[1]; \
134  const int nb_a = s->iir[ch].nb_ab[0]; \
135  const int nb_b = s->iir[ch].nb_ab[1]; \
136  const double *a = s->iir[ch].ab[0]; \
137  const double *b = s->iir[ch].ab[1]; \
138  const double g = s->iir[ch].g; \
139  int *clippings = &s->iir[ch].clippings; \
140  type *dst = (type *)out->extended_data[ch]; \
141  int n; \
142  \
143  for (n = 0; n < in->nb_samples; n++) { \
144  double sample = 0.; \
145  int x; \
146  \
147  memmove(&ic[1], &ic[0], (nb_b - 1) * sizeof(*ic)); \
148  memmove(&oc[1], &oc[0], (nb_a - 1) * sizeof(*oc)); \
149  ic[0] = src[n] * ig; \
150  for (x = 0; x < nb_b; x++) \
151  sample += b[x] * ic[x]; \
152  \
153  for (x = 1; x < nb_a; x++) \
154  sample -= a[x] * oc[x]; \
155  \
156  oc[0] = sample; \
157  sample *= og * g; \
158  sample = sample * mix + ic[0] * (1. - mix); \
159  if (need_clipping && sample < min) { \
160  (*clippings)++; \
161  dst[n] = min; \
162  } else if (need_clipping && sample > max) { \
163  (*clippings)++; \
164  dst[n] = max; \
165  } else { \
166  dst[n] = sample; \
167  } \
168  } \
169  \
170  return 0; \
171 }
172 
173 IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1)
174 IIR_CH(s32p, int32_t, INT32_MIN, INT32_MAX, 1)
175 IIR_CH(fltp, float, -1., 1., 0)
176 IIR_CH(dblp, double, -1., 1., 0)
177 
178 #define SERIAL_IIR_CH(name, type, min, max, need_clipping) \
179 static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \
180 { \
181  AudioIIRContext *s = ctx->priv; \
182  const double ig = s->dry_gain; \
183  const double og = s->wet_gain; \
184  const double mix = s->mix; \
185  ThreadData *td = arg; \
186  AVFrame *in = td->in, *out = td->out; \
187  const type *src = (const type *)in->extended_data[ch]; \
188  type *dst = (type *)out->extended_data[ch]; \
189  IIRChannel *iir = &s->iir[ch]; \
190  const double g = iir->g; \
191  int *clippings = &iir->clippings; \
192  int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
193  int n, i; \
194  \
195  for (i = 0; i < nb_biquads; i++) { \
196  const double a1 = -iir->biquads[i].a1; \
197  const double a2 = -iir->biquads[i].a2; \
198  const double b0 = iir->biquads[i].b0; \
199  const double b1 = iir->biquads[i].b1; \
200  const double b2 = iir->biquads[i].b2; \
201  double i1 = iir->biquads[i].i1; \
202  double i2 = iir->biquads[i].i2; \
203  double o1 = iir->biquads[i].o1; \
204  double o2 = iir->biquads[i].o2; \
205  \
206  for (n = 0; n < in->nb_samples; n++) { \
207  double sample = ig * (i ? dst[n] : src[n]); \
208  double o0 = sample * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
209  \
210  i2 = i1; \
211  i1 = src[n]; \
212  o2 = o1; \
213  o1 = o0; \
214  o0 *= og * g; \
215  \
216  o0 = o0 * mix + (1. - mix) * sample; \
217  if (need_clipping && o0 < min) { \
218  (*clippings)++; \
219  dst[n] = min; \
220  } else if (need_clipping && o0 > max) { \
221  (*clippings)++; \
222  dst[n] = max; \
223  } else { \
224  dst[n] = o0; \
225  } \
226  } \
227  iir->biquads[i].i1 = i1; \
228  iir->biquads[i].i2 = i2; \
229  iir->biquads[i].o1 = o1; \
230  iir->biquads[i].o2 = o2; \
231  } \
232  \
233  return 0; \
234 }
235 
236 SERIAL_IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1)
237 SERIAL_IIR_CH(s32p, int32_t, INT32_MIN, INT32_MAX, 1)
238 SERIAL_IIR_CH(fltp, float, -1., 1., 0)
239 SERIAL_IIR_CH(dblp, double, -1., 1., 0)
240 
241 static void count_coefficients(char *item_str, int *nb_items)
242 {
243  char *p;
244 
245  if (!item_str)
246  return;
247 
248  *nb_items = 1;
249  for (p = item_str; *p && *p != '|'; p++) {
250  if (*p == ' ')
251  (*nb_items)++;
252  }
253 }
254 
255 static int read_gains(AVFilterContext *ctx, char *item_str, int nb_items)
256 {
257  AudioIIRContext *s = ctx->priv;
258  char *p, *arg, *old_str, *prev_arg = NULL, *saveptr = NULL;
259  int i;
260 
261  p = old_str = av_strdup(item_str);
262  if (!p)
263  return AVERROR(ENOMEM);
264  for (i = 0; i < nb_items; i++) {
265  if (!(arg = av_strtok(p, "|", &saveptr)))
266  arg = prev_arg;
267 
268  if (!arg) {
269  av_freep(&old_str);
270  return AVERROR(EINVAL);
271  }
272 
273  p = NULL;
274  if (sscanf(arg, "%lf", &s->iir[i].g) != 1) {
275  av_log(ctx, AV_LOG_ERROR, "Invalid gains supplied: %s\n", arg);
276  av_freep(&old_str);
277  return AVERROR(EINVAL);
278  }
279 
280  prev_arg = arg;
281  }
282 
283  av_freep(&old_str);
284 
285  return 0;
286 }
287 
288 static int read_tf_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst)
289 {
290  char *p, *arg, *old_str, *saveptr = NULL;
291  int i;
292 
293  p = old_str = av_strdup(item_str);
294  if (!p)
295  return AVERROR(ENOMEM);
296  for (i = 0; i < nb_items; i++) {
297  if (!(arg = av_strtok(p, " ", &saveptr)))
298  break;
299 
300  p = NULL;
301  if (sscanf(arg, "%lf", &dst[i]) != 1) {
302  av_log(ctx, AV_LOG_ERROR, "Invalid coefficients supplied: %s\n", arg);
303  av_freep(&old_str);
304  return AVERROR(EINVAL);
305  }
306  }
307 
308  av_freep(&old_str);
309 
310  return 0;
311 }
312 
313 static int read_zp_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst, const char *format)
314 {
315  char *p, *arg, *old_str, *saveptr = NULL;
316  int i;
317 
318  p = old_str = av_strdup(item_str);
319  if (!p)
320  return AVERROR(ENOMEM);
321  for (i = 0; i < nb_items; i++) {
322  if (!(arg = av_strtok(p, " ", &saveptr)))
323  break;
324 
325  p = NULL;
326  if (sscanf(arg, format, &dst[i*2], &dst[i*2+1]) != 2) {
327  av_log(ctx, AV_LOG_ERROR, "Invalid coefficients supplied: %s\n", arg);
328  av_freep(&old_str);
329  return AVERROR(EINVAL);
330  }
331  }
332 
333  av_freep(&old_str);
334 
335  return 0;
336 }
337 
338 static const char *format[] = { "%lf", "%lf %lfi", "%lf %lfr", "%lf %lfd" };
339 
340 static int read_channels(AVFilterContext *ctx, int channels, uint8_t *item_str, int ab)
341 {
342  AudioIIRContext *s = ctx->priv;
343  char *p, *arg, *old_str, *prev_arg = NULL, *saveptr = NULL;
344  int i, ret;
345 
346  p = old_str = av_strdup(item_str);
347  if (!p)
348  return AVERROR(ENOMEM);
349  for (i = 0; i < channels; i++) {
350  IIRChannel *iir = &s->iir[i];
351 
352  if (!(arg = av_strtok(p, "|", &saveptr)))
353  arg = prev_arg;
354 
355  if (!arg) {
356  av_freep(&old_str);
357  return AVERROR(EINVAL);
358  }
359 
360  count_coefficients(arg, &iir->nb_ab[ab]);
361 
362  p = NULL;
363  iir->cache[ab] = av_calloc(iir->nb_ab[ab] + 1, sizeof(double));
364  iir->ab[ab] = av_calloc(iir->nb_ab[ab] * (!!s->format + 1), sizeof(double));
365  if (!iir->ab[ab] || !iir->cache[ab]) {
366  av_freep(&old_str);
367  return AVERROR(ENOMEM);
368  }
369 
370  if (s->format) {
371  ret = read_zp_coefficients(ctx, arg, iir->nb_ab[ab], iir->ab[ab], format[s->format]);
372  } else {
373  ret = read_tf_coefficients(ctx, arg, iir->nb_ab[ab], iir->ab[ab]);
374  }
375  if (ret < 0) {
376  av_freep(&old_str);
377  return ret;
378  }
379  prev_arg = arg;
380  }
381 
382  av_freep(&old_str);
383 
384  return 0;
385 }
386 
387 static void multiply(double wre, double wim, int npz, double *coeffs)
388 {
389  double nwre = -wre, nwim = -wim;
390  double cre, cim;
391  int i;
392 
393  for (i = npz; i >= 1; i--) {
394  cre = coeffs[2 * i + 0];
395  cim = coeffs[2 * i + 1];
396 
397  coeffs[2 * i + 0] = (nwre * cre - nwim * cim) + coeffs[2 * (i - 1) + 0];
398  coeffs[2 * i + 1] = (nwre * cim + nwim * cre) + coeffs[2 * (i - 1) + 1];
399  }
400 
401  cre = coeffs[0];
402  cim = coeffs[1];
403  coeffs[0] = nwre * cre - nwim * cim;
404  coeffs[1] = nwre * cim + nwim * cre;
405 }
406 
407 static int expand(AVFilterContext *ctx, double *pz, int nb, double *coeffs)
408 {
409  int i;
410 
411  coeffs[0] = 1.0;
412  coeffs[1] = 0.0;
413 
414  for (i = 0; i < nb; i++) {
415  coeffs[2 * (i + 1) ] = 0.0;
416  coeffs[2 * (i + 1) + 1] = 0.0;
417  }
418 
419  for (i = 0; i < nb; i++)
420  multiply(pz[2 * i], pz[2 * i + 1], nb, coeffs);
421 
422  for (i = 0; i < nb + 1; i++) {
423  if (fabs(coeffs[2 * i + 1]) > FLT_EPSILON) {
424  av_log(ctx, AV_LOG_ERROR, "coeff: %f of z^%d is not real; poles/zeros are not complex conjugates.\n",
425  coeffs[2 * i + 1], i);
426  return AVERROR(EINVAL);
427  }
428  }
429 
430  return 0;
431 }
432 
434 {
435  AudioIIRContext *s = ctx->priv;
436  int ch, i, j, ret = 0;
437 
438  for (ch = 0; ch < channels; ch++) {
439  IIRChannel *iir = &s->iir[ch];
440  double *topc, *botc;
441 
442  topc = av_calloc((iir->nb_ab[0] + 1) * 2, sizeof(*topc));
443  botc = av_calloc((iir->nb_ab[1] + 1) * 2, sizeof(*botc));
444  if (!topc || !botc) {
445  ret = AVERROR(ENOMEM);
446  goto fail;
447  }
448 
449  ret = expand(ctx, iir->ab[0], iir->nb_ab[0], botc);
450  if (ret < 0) {
451  goto fail;
452  }
453 
454  ret = expand(ctx, iir->ab[1], iir->nb_ab[1], topc);
455  if (ret < 0) {
456  goto fail;
457  }
458 
459  for (j = 0, i = iir->nb_ab[1]; i >= 0; j++, i--) {
460  iir->ab[1][j] = topc[2 * i];
461  }
462  iir->nb_ab[1]++;
463 
464  for (j = 0, i = iir->nb_ab[0]; i >= 0; j++, i--) {
465  iir->ab[0][j] = botc[2 * i];
466  }
467  iir->nb_ab[0]++;
468 
469 fail:
470  av_free(topc);
471  av_free(botc);
472  if (ret < 0)
473  break;
474  }
475 
476  return ret;
477 }
478 
480 {
481  AudioIIRContext *s = ctx->priv;
482  int ch, ret;
483 
484  for (ch = 0; ch < channels; ch++) {
485  IIRChannel *iir = &s->iir[ch];
486  int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2;
487  int current_biquad = 0;
488 
489  iir->biquads = av_calloc(nb_biquads, sizeof(BiquadContext));
490  if (!iir->biquads)
491  return AVERROR(ENOMEM);
492 
493  while (nb_biquads--) {
494  Pair outmost_pole = { -1, -1 };
495  Pair nearest_zero = { -1, -1 };
496  double zeros[4] = { 0 };
497  double poles[4] = { 0 };
498  double b[6] = { 0 };
499  double a[6] = { 0 };
500  double min_distance = DBL_MAX;
501  double max_mag = 0;
502  int i;
503 
504  for (i = 0; i < iir->nb_ab[0]; i++) {
505  double mag;
506 
507  if (isnan(iir->ab[0][2 * i]) || isnan(iir->ab[0][2 * i + 1]))
508  continue;
509  mag = hypot(iir->ab[0][2 * i], iir->ab[0][2 * i + 1]);
510 
511  if (mag > max_mag) {
512  max_mag = mag;
513  outmost_pole.a = i;
514  }
515  }
516 
517  for (i = 0; i < iir->nb_ab[1]; i++) {
518  if (isnan(iir->ab[0][2 * i]) || isnan(iir->ab[0][2 * i + 1]))
519  continue;
520 
521  if (iir->ab[0][2 * i ] == iir->ab[0][2 * outmost_pole.a ] &&
522  iir->ab[0][2 * i + 1] == -iir->ab[0][2 * outmost_pole.a + 1]) {
523  outmost_pole.b = i;
524  break;
525  }
526  }
527 
528  av_log(ctx, AV_LOG_VERBOSE, "outmost_pole is %d.%d\n", outmost_pole.a, outmost_pole.b);
529 
530  if (outmost_pole.a < 0 || outmost_pole.b < 0)
531  return AVERROR(EINVAL);
532 
533  for (i = 0; i < iir->nb_ab[1]; i++) {
534  double distance;
535 
536  if (isnan(iir->ab[1][2 * i]) || isnan(iir->ab[1][2 * i + 1]))
537  continue;
538  distance = hypot(iir->ab[0][2 * outmost_pole.a ] - iir->ab[1][2 * i ],
539  iir->ab[0][2 * outmost_pole.a + 1] - iir->ab[1][2 * i + 1]);
540 
541  if (distance < min_distance) {
542  min_distance = distance;
543  nearest_zero.a = i;
544  }
545  }
546 
547  for (i = 0; i < iir->nb_ab[1]; i++) {
548  if (isnan(iir->ab[1][2 * i]) || isnan(iir->ab[1][2 * i + 1]))
549  continue;
550 
551  if (iir->ab[1][2 * i ] == iir->ab[1][2 * nearest_zero.a ] &&
552  iir->ab[1][2 * i + 1] == -iir->ab[1][2 * nearest_zero.a + 1]) {
553  nearest_zero.b = i;
554  break;
555  }
556  }
557 
558  av_log(ctx, AV_LOG_VERBOSE, "nearest_zero is %d.%d\n", nearest_zero.a, nearest_zero.b);
559 
560  if (nearest_zero.a < 0 || nearest_zero.b < 0)
561  return AVERROR(EINVAL);
562 
563  poles[0] = iir->ab[0][2 * outmost_pole.a ];
564  poles[1] = iir->ab[0][2 * outmost_pole.a + 1];
565 
566  zeros[0] = iir->ab[1][2 * nearest_zero.a ];
567  zeros[1] = iir->ab[1][2 * nearest_zero.a + 1];
568 
569  if (nearest_zero.a == nearest_zero.b && outmost_pole.a == outmost_pole.b) {
570  zeros[2] = 0;
571  zeros[3] = 0;
572 
573  poles[2] = 0;
574  poles[3] = 0;
575  } else {
576  poles[2] = iir->ab[0][2 * outmost_pole.b ];
577  poles[3] = iir->ab[0][2 * outmost_pole.b + 1];
578 
579  zeros[2] = iir->ab[1][2 * nearest_zero.b ];
580  zeros[3] = iir->ab[1][2 * nearest_zero.b + 1];
581  }
582 
583  ret = expand(ctx, zeros, 2, b);
584  if (ret < 0)
585  return ret;
586 
587  ret = expand(ctx, poles, 2, a);
588  if (ret < 0)
589  return ret;
590 
591  iir->ab[0][2 * outmost_pole.a] = iir->ab[0][2 * outmost_pole.a + 1] = NAN;
592  iir->ab[0][2 * outmost_pole.b] = iir->ab[0][2 * outmost_pole.b + 1] = NAN;
593  iir->ab[1][2 * nearest_zero.a] = iir->ab[1][2 * nearest_zero.a + 1] = NAN;
594  iir->ab[1][2 * nearest_zero.b] = iir->ab[1][2 * nearest_zero.b + 1] = NAN;
595 
596  iir->biquads[current_biquad].a0 = 1.0;
597  iir->biquads[current_biquad].a1 = a[2] / a[4];
598  iir->biquads[current_biquad].a2 = a[0] / a[4];
599  iir->biquads[current_biquad].b0 = b[4] / a[4] * (current_biquad ? 1.0 : iir->g);
600  iir->biquads[current_biquad].b1 = b[2] / a[4] * (current_biquad ? 1.0 : iir->g);
601  iir->biquads[current_biquad].b2 = b[0] / a[4] * (current_biquad ? 1.0 : iir->g);
602 
603  av_log(ctx, AV_LOG_VERBOSE, "a=%f %f %f:b=%f %f %f\n",
604  iir->biquads[current_biquad].a0,
605  iir->biquads[current_biquad].a1,
606  iir->biquads[current_biquad].a2,
607  iir->biquads[current_biquad].b0,
608  iir->biquads[current_biquad].b1,
609  iir->biquads[current_biquad].b2);
610 
611  current_biquad++;
612  }
613  }
614 
615  return 0;
616 }
617 
619 {
620  AudioIIRContext *s = ctx->priv;
621  int ch;
622 
623  for (ch = 0; ch < channels; ch++) {
624  IIRChannel *iir = &s->iir[ch];
625  int n;
626 
627  for (n = 0; n < iir->nb_ab[0]; n++) {
628  double r = iir->ab[0][2*n];
629  double angle = iir->ab[0][2*n+1];
630 
631  iir->ab[0][2*n] = r * cos(angle);
632  iir->ab[0][2*n+1] = r * sin(angle);
633  }
634 
635  for (n = 0; n < iir->nb_ab[1]; n++) {
636  double r = iir->ab[1][2*n];
637  double angle = iir->ab[1][2*n+1];
638 
639  iir->ab[1][2*n] = r * cos(angle);
640  iir->ab[1][2*n+1] = r * sin(angle);
641  }
642  }
643 }
644 
646 {
647  AudioIIRContext *s = ctx->priv;
648  int ch;
649 
650  for (ch = 0; ch < channels; ch++) {
651  IIRChannel *iir = &s->iir[ch];
652  int n;
653 
654  for (n = 0; n < iir->nb_ab[0]; n++) {
655  double r = iir->ab[0][2*n];
656  double angle = M_PI*iir->ab[0][2*n+1]/180.;
657 
658  iir->ab[0][2*n] = r * cos(angle);
659  iir->ab[0][2*n+1] = r * sin(angle);
660  }
661 
662  for (n = 0; n < iir->nb_ab[1]; n++) {
663  double r = iir->ab[1][2*n];
664  double angle = M_PI*iir->ab[1][2*n+1]/180.;
665 
666  iir->ab[1][2*n] = r * cos(angle);
667  iir->ab[1][2*n+1] = r * sin(angle);
668  }
669  }
670 }
671 
672 static void drawtext(AVFrame *pic, int x, int y, const char *txt, uint32_t color)
673 {
674  const uint8_t *font;
675  int font_height;
676  int i;
677 
678  font = avpriv_cga_font, font_height = 8;
679 
680  for (i = 0; txt[i]; i++) {
681  int char_y, mask;
682 
683  uint8_t *p = pic->data[0] + y * pic->linesize[0] + (x + i * 8) * 4;
684  for (char_y = 0; char_y < font_height; char_y++) {
685  for (mask = 0x80; mask; mask >>= 1) {
686  if (font[txt[i] * font_height + char_y] & mask)
687  AV_WL32(p, color);
688  p += 4;
689  }
690  p += pic->linesize[0] - 8 * 4;
691  }
692  }
693 }
694 
695 static void draw_line(AVFrame *out, int x0, int y0, int x1, int y1, uint32_t color)
696 {
697  int dx = FFABS(x1-x0);
698  int dy = FFABS(y1-y0), sy = y0 < y1 ? 1 : -1;
699  int err = (dx>dy ? dx : -dy) / 2, e2;
700 
701  for (;;) {
702  AV_WL32(out->data[0] + y0 * out->linesize[0] + x0 * 4, color);
703 
704  if (x0 == x1 && y0 == y1)
705  break;
706 
707  e2 = err;
708 
709  if (e2 >-dx) {
710  err -= dy;
711  x0--;
712  }
713 
714  if (e2 < dy) {
715  err += dx;
716  y0 += sy;
717  }
718  }
719 }
720 
722 {
723  AudioIIRContext *s = ctx->priv;
724  float *mag, *phase, *delay, min = FLT_MAX, max = FLT_MIN;
725  float min_delay = FLT_MAX, max_delay = FLT_MIN;
726  int prev_ymag = -1, prev_yphase = -1, prev_ydelay = -1;
727  char text[32];
728  int ch, i, x;
729 
730  memset(out->data[0], 0, s->h * out->linesize[0]);
731 
732  phase = av_malloc_array(s->w, sizeof(*phase));
733  mag = av_malloc_array(s->w, sizeof(*mag));
734  delay = av_malloc_array(s->w, sizeof(*delay));
735  if (!mag || !phase || !delay)
736  goto end;
737 
738  ch = av_clip(s->ir_channel, 0, s->channels - 1);
739  for (i = 0; i < s->w; i++) {
740  const double *b = s->iir[ch].ab[0];
741  const double *a = s->iir[ch].ab[1];
742  double w = i * M_PI / (s->w - 1);
743  double realz, realp;
744  double imagz, imagp;
745  double real, imag, div;
746 
747  if (s->format == 0) {
748  realz = 0., realp = 0.;
749  imagz = 0., imagp = 0.;
750  for (x = 0; x < s->iir[ch].nb_ab[1]; x++) {
751  realz += cos(-x * w) * a[x];
752  imagz += sin(-x * w) * a[x];
753  }
754 
755  for (x = 0; x < s->iir[ch].nb_ab[0]; x++) {
756  realp += cos(-x * w) * b[x];
757  imagp += sin(-x * w) * b[x];
758  }
759 
760  div = realp * realp + imagp * imagp;
761  real = (realz * realp + imagz * imagp) / div;
762  imag = (imagz * realp - imagp * realz) / div;
763  } else {
764  real = 1;
765  imag = 0;
766  for (x = 0; x < s->iir[ch].nb_ab[1]; x++) {
767  double ore, oim, re, im;
768 
769  re = cos(w) - a[2 * x];
770  im = sin(w) - a[2 * x + 1];
771 
772  ore = real;
773  oim = imag;
774 
775  real = ore * re - oim * im;
776  imag = ore * im + oim * re;
777  }
778 
779  for (x = 0; x < s->iir[ch].nb_ab[0]; x++) {
780  double ore, oim, re, im;
781 
782  re = cos(w) - b[2 * x];
783  im = sin(w) - b[2 * x + 1];
784 
785  ore = real;
786  oim = imag;
787  div = re * re + im * im;
788 
789  real = (ore * re + oim * im) / div;
790  imag = (oim * re - ore * im) / div;
791  }
792  }
793 
794  mag[i] = s->iir[ch].g * hypot(real, imag);
795  phase[i] = atan2(imag, real);
796  min = fminf(min, mag[i]);
797  max = fmaxf(max, mag[i]);
798  }
799 
800  for (i = 0; i < s->w - 1; i++) {
801  float dw = M_PI / (s->w - 1);
802 
803  delay[i] = -(phase[i + 1] - phase[i]) / dw;
804  min_delay = fminf(min_delay, delay[i]);
805  max_delay = fmaxf(max_delay, delay[i]);
806  }
807 
808  delay[i] = delay[i - 1];
809 
810  for (i = 0; i < s->w; i++) {
811  int ymag = mag[i] / max * (s->h - 1);
812  int ydelay = (delay[i] - min_delay) / (max_delay - min_delay) * (s->h - 1);
813  int yphase = (0.5 * (1. + phase[i] / M_PI)) * (s->h - 1);
814 
815  ymag = s->h - 1 - av_clip(ymag, 0, s->h - 1);
816  yphase = s->h - 1 - av_clip(yphase, 0, s->h - 1);
817  ydelay = s->h - 1 - av_clip(ydelay, 0, s->h - 1);
818 
819  if (prev_ymag < 0)
820  prev_ymag = ymag;
821  if (prev_yphase < 0)
822  prev_yphase = yphase;
823  if (prev_ydelay < 0)
824  prev_ydelay = ydelay;
825 
826  draw_line(out, i, ymag, FFMAX(i - 1, 0), prev_ymag, 0xFFFF00FF);
827  draw_line(out, i, yphase, FFMAX(i - 1, 0), prev_yphase, 0xFF00FF00);
828  draw_line(out, i, ydelay, FFMAX(i - 1, 0), prev_ydelay, 0xFF00FFFF);
829 
830  prev_ymag = ymag;
831  prev_yphase = yphase;
832  prev_ydelay = ydelay;
833  }
834 
835  if (s->w > 400 && s->h > 100) {
836  drawtext(out, 2, 2, "Max Magnitude:", 0xDDDDDDDD);
837  snprintf(text, sizeof(text), "%.2f", max);
838  drawtext(out, 15 * 8 + 2, 2, text, 0xDDDDDDDD);
839 
840  drawtext(out, 2, 12, "Min Magnitude:", 0xDDDDDDDD);
841  snprintf(text, sizeof(text), "%.2f", min);
842  drawtext(out, 15 * 8 + 2, 12, text, 0xDDDDDDDD);
843 
844  drawtext(out, 2, 22, "Max Delay:", 0xDDDDDDDD);
845  snprintf(text, sizeof(text), "%.2f", max_delay);
846  drawtext(out, 11 * 8 + 2, 22, text, 0xDDDDDDDD);
847 
848  drawtext(out, 2, 32, "Min Delay:", 0xDDDDDDDD);
849  snprintf(text, sizeof(text), "%.2f", min_delay);
850  drawtext(out, 11 * 8 + 2, 32, text, 0xDDDDDDDD);
851  }
852 
853 end:
854  av_free(delay);
855  av_free(phase);
856  av_free(mag);
857 }
858 
859 static int config_output(AVFilterLink *outlink)
860 {
861  AVFilterContext *ctx = outlink->src;
862  AudioIIRContext *s = ctx->priv;
863  AVFilterLink *inlink = ctx->inputs[0];
864  int ch, ret, i;
865 
866  s->channels = inlink->channels;
867  s->iir = av_calloc(s->channels, sizeof(*s->iir));
868  if (!s->iir)
869  return AVERROR(ENOMEM);
870 
871  ret = read_gains(ctx, s->g_str, inlink->channels);
872  if (ret < 0)
873  return ret;
874 
875  ret = read_channels(ctx, inlink->channels, s->a_str, 0);
876  if (ret < 0)
877  return ret;
878 
879  ret = read_channels(ctx, inlink->channels, s->b_str, 1);
880  if (ret < 0)
881  return ret;
882 
883  if (s->format == 2) {
884  convert_pr2zp(ctx, inlink->channels);
885  } else if (s->format == 3) {
886  convert_pd2zp(ctx, inlink->channels);
887  }
888 
889  av_frame_free(&s->video);
890  if (s->response) {
891  s->video = ff_get_video_buffer(ctx->outputs[1], s->w, s->h);
892  if (!s->video)
893  return AVERROR(ENOMEM);
894 
895  draw_response(ctx, s->video);
896  }
897 
898  if (s->format == 0)
899  av_log(ctx, AV_LOG_WARNING, "tf coefficients format is not recommended for too high number of zeros/poles.\n");
900 
901  if (s->format > 0 && s->process == 0) {
902  av_log(ctx, AV_LOG_WARNING, "Direct processsing is not recommended for zp coefficients format.\n");
903 
904  ret = convert_zp2tf(ctx, inlink->channels);
905  if (ret < 0)
906  return ret;
907  } else if (s->format == 0 && s->process == 1) {
908  av_log(ctx, AV_LOG_ERROR, "Serial cascading is not implemented for transfer function.\n");
909  return AVERROR_PATCHWELCOME;
910  } else if (s->format > 0 && s->process == 1) {
911  if (inlink->format == AV_SAMPLE_FMT_S16P)
912  av_log(ctx, AV_LOG_WARNING, "Serial cascading is not recommended for i16 precision.\n");
913 
914  ret = decompose_zp2biquads(ctx, inlink->channels);
915  if (ret < 0)
916  return ret;
917  }
918 
919  for (ch = 0; s->format == 0 && ch < inlink->channels; ch++) {
920  IIRChannel *iir = &s->iir[ch];
921 
922  for (i = 1; i < iir->nb_ab[0]; i++) {
923  iir->ab[0][i] /= iir->ab[0][0];
924  }
925 
926  for (i = 0; i < iir->nb_ab[1]; i++) {
927  iir->ab[1][i] *= iir->g / iir->ab[0][0];
928  }
929  }
930 
931  switch (inlink->format) {
932  case AV_SAMPLE_FMT_DBLP: s->iir_channel = s->process == 1 ? iir_ch_serial_dblp : iir_ch_dblp; break;
933  case AV_SAMPLE_FMT_FLTP: s->iir_channel = s->process == 1 ? iir_ch_serial_fltp : iir_ch_fltp; break;
934  case AV_SAMPLE_FMT_S32P: s->iir_channel = s->process == 1 ? iir_ch_serial_s32p : iir_ch_s32p; break;
935  case AV_SAMPLE_FMT_S16P: s->iir_channel = s->process == 1 ? iir_ch_serial_s16p : iir_ch_s16p; break;
936  }
937 
938  return 0;
939 }
940 
942 {
943  AVFilterContext *ctx = inlink->dst;
944  AudioIIRContext *s = ctx->priv;
945  AVFilterLink *outlink = ctx->outputs[0];
946  ThreadData td;
947  AVFrame *out;
948  int ch, ret;
949 
950  if (av_frame_is_writable(in)) {
951  out = in;
952  } else {
953  out = ff_get_audio_buffer(outlink, in->nb_samples);
954  if (!out) {
955  av_frame_free(&in);
956  return AVERROR(ENOMEM);
957  }
958  av_frame_copy_props(out, in);
959  }
960 
961  td.in = in;
962  td.out = out;
963  ctx->internal->execute(ctx, s->iir_channel, &td, NULL, outlink->channels);
964 
965  for (ch = 0; ch < outlink->channels; ch++) {
966  if (s->iir[ch].clippings > 0)
967  av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n",
968  ch, s->iir[ch].clippings);
969  s->iir[ch].clippings = 0;
970  }
971 
972  if (in != out)
973  av_frame_free(&in);
974 
975  if (s->response) {
976  AVFilterLink *outlink = ctx->outputs[1];
977  int64_t old_pts = s->video->pts;
978  int64_t new_pts = av_rescale_q(out->pts, ctx->inputs[0]->time_base, outlink->time_base);
979 
980  if (new_pts > old_pts) {
981  s->video->pts = new_pts;
982  ret = ff_filter_frame(outlink, av_frame_clone(s->video));
983  if (ret < 0)
984  return ret;
985  }
986  }
987 
988  return ff_filter_frame(outlink, out);
989 }
990 
991 static int config_video(AVFilterLink *outlink)
992 {
993  AVFilterContext *ctx = outlink->src;
994  AudioIIRContext *s = ctx->priv;
995 
996  outlink->sample_aspect_ratio = (AVRational){1,1};
997  outlink->w = s->w;
998  outlink->h = s->h;
999  outlink->frame_rate = s->rate;
1000  outlink->time_base = av_inv_q(outlink->frame_rate);
1001 
1002  return 0;
1003 }
1004 
1006 {
1007  AudioIIRContext *s = ctx->priv;
1008  AVFilterPad pad, vpad;
1009  int ret;
1010 
1011  if (!s->a_str || !s->b_str || !s->g_str) {
1012  av_log(ctx, AV_LOG_ERROR, "Valid coefficients are mandatory.\n");
1013  return AVERROR(EINVAL);
1014  }
1015 
1016  switch (s->precision) {
1017  case 0: s->sample_format = AV_SAMPLE_FMT_DBLP; break;
1018  case 1: s->sample_format = AV_SAMPLE_FMT_FLTP; break;
1019  case 2: s->sample_format = AV_SAMPLE_FMT_S32P; break;
1020  case 3: s->sample_format = AV_SAMPLE_FMT_S16P; break;
1021  default: return AVERROR_BUG;
1022  }
1023 
1024  pad = (AVFilterPad){
1025  .name = av_strdup("default"),
1026  .type = AVMEDIA_TYPE_AUDIO,
1027  .config_props = config_output,
1028  };
1029 
1030  if (!pad.name)
1031  return AVERROR(ENOMEM);
1032 
1033  if (s->response) {
1034  vpad = (AVFilterPad){
1035  .name = av_strdup("filter_response"),
1036  .type = AVMEDIA_TYPE_VIDEO,
1037  .config_props = config_video,
1038  };
1039  if (!vpad.name)
1040  return AVERROR(ENOMEM);
1041  }
1042 
1043  ret = ff_insert_outpad(ctx, 0, &pad);
1044  if (ret < 0)
1045  return ret;
1046 
1047  if (s->response) {
1048  ret = ff_insert_outpad(ctx, 1, &vpad);
1049  if (ret < 0)
1050  return ret;
1051  }
1052 
1053  return 0;
1054 }
1055 
1057 {
1058  AudioIIRContext *s = ctx->priv;
1059  int ch;
1060 
1061  if (s->iir) {
1062  for (ch = 0; ch < s->channels; ch++) {
1063  IIRChannel *iir = &s->iir[ch];
1064  av_freep(&iir->ab[0]);
1065  av_freep(&iir->ab[1]);
1066  av_freep(&iir->cache[0]);
1067  av_freep(&iir->cache[1]);
1068  av_freep(&iir->biquads);
1069  }
1070  }
1071  av_freep(&s->iir);
1072 
1073  av_freep(&ctx->output_pads[0].name);
1074  if (s->response)
1075  av_freep(&ctx->output_pads[1].name);
1076  av_frame_free(&s->video);
1077 }
1078 
1079 static const AVFilterPad inputs[] = {
1080  {
1081  .name = "default",
1082  .type = AVMEDIA_TYPE_AUDIO,
1083  .filter_frame = filter_frame,
1084  },
1085  { NULL }
1086 };
1087 
1088 #define OFFSET(x) offsetof(AudioIIRContext, x)
1089 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1090 #define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1091 
1092 static const AVOption aiir_options[] = {
1093  { "z", "set B/numerator/zeros coefficients", OFFSET(b_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF },
1094  { "p", "set A/denominator/poles coefficients", OFFSET(a_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF },
1095  { "k", "set channels gains", OFFSET(g_str), AV_OPT_TYPE_STRING, {.str="1|1"}, 0, 0, AF },
1096  { "dry", "set dry gain", OFFSET(dry_gain), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, AF },
1097  { "wet", "set wet gain", OFFSET(wet_gain), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, AF },
1098  { "f", "set coefficients format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=1}, 0, 3, AF, "format" },
1099  { "tf", "transfer function", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "format" },
1100  { "zp", "Z-plane zeros/poles", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "format" },
1101  { "pr", "Z-plane zeros/poles (polar radians)", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "format" },
1102  { "pd", "Z-plane zeros/poles (polar degrees)", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "format" },
1103  { "r", "set kind of processing", OFFSET(process), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "process" },
1104  { "d", "direct", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "process" },
1105  { "s", "serial cascading", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "process" },
1106  { "e", "set precision", OFFSET(precision),AV_OPT_TYPE_INT, {.i64=0}, 0, 3, AF, "precision" },
1107  { "dbl", "double-precision floating-point", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision" },
1108  { "flt", "single-precision floating-point", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision" },
1109  { "i32", "32-bit integers", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision" },
1110  { "i16", "16-bit integers", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision" },
1111  { "mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, AF },
1112  { "response", "show IR frequency response", OFFSET(response), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, VF },
1113  { "channel", "set IR channel to display frequency response", OFFSET(ir_channel), AV_OPT_TYPE_INT, {.i64=0}, 0, 1024, VF },
1114  { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "hd720"}, 0, 0, VF },
1115  { "rate", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT32_MAX, VF },
1116  { NULL },
1117 };
1118 
1119 AVFILTER_DEFINE_CLASS(aiir);
1120 
1122  .name = "aiir",
1123  .description = NULL_IF_CONFIG_SMALL("Apply Infinite Impulse Response filter with supplied coefficients."),
1124  .priv_size = sizeof(AudioIIRContext),
1125  .priv_class = &aiir_class,
1126  .init = init,
1127  .uninit = uninit,
1129  .inputs = inputs,
1132 };
float, planar
Definition: samplefmt.h:69
#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:549
char * a_str
Definition: af_aiir.c:58
AVFrame * out
Definition: af_adeclick.c:488
static const char * format[]
Definition: af_aiir.c:338
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
enum AVSampleFormat sample_format
Definition: af_aiir.c:73
AVOption.
Definition: opt.h:246
BiquadContext * biquads
Definition: af_aiir.c:52
float re
Definition: fft.c:82
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
Main libavfilter public API header.
static int config_video(AVFilterLink *outlink)
Definition: af_aiir.c:991
#define a0
Definition: regdef.h:46
static void convert_pd2zp(AVFilterContext *ctx, int channels)
Definition: af_aiir.c:645
channels
Definition: aptx.c:30
static void drawtext(AVFrame *pic, int x, int y, const char *txt, uint32_t color)
Definition: af_aiir.c:672
float fminf(float, float)
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/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0/(INT64_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 *(INT64_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 *(INT64_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
int clippings
Definition: af_aiir.c:53
static int decompose_zp2biquads(AVFilterContext *ctx, int channels)
Definition: af_aiir.c:479
double, planar
Definition: samplefmt.h:70
#define SERIAL_IIR_CH(name, type, min, max, need_clipping)
Definition: af_aiir.c:178
#define a1
Definition: regdef.h:47
static void count_coefficients(char *item_str, int *nb_items)
Definition: af_aiir.c:241
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
static int config_output(AVFilterLink *outlink)
Definition: af_aiir.c:859
double b0
Definition: af_aiir.c:42
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 int process(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed)
Definition: soxr_resample.c:84
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
AVFilterPad * output_pads
array of output pads
Definition: avfilter.h:349
uint8_t
#define av_cold
Definition: attributes.h:82
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:238
AVOptions.
int ** delay
Definition: af_headphone.c:156
double * cache[2]
Definition: af_aiir.c:51
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
AVFilter ff_af_aiir
Definition: af_aiir.c:1121
static av_cold int init(AVFilterContext *ctx)
Definition: af_aiir.c:1005
static int expand(AVFilterContext *ctx, double *pz, int nb, double *coeffs)
Definition: af_aiir.c:407
AVFrame * dst
Definition: vf_blend.c:55
#define IIR_CH(name, type, min, max, need_clipping)
Definition: af_aiir.c:122
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
static int read_tf_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst)
Definition: af_aiir.c:288
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
Definition: avfilter.h:111
static int query_formats(AVFilterContext *ctx)
Definition: af_aiir.c:78
#define av_log(a,...)
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
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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:568
#define td
Definition: regdef.h:70
const uint8_t avpriv_cga_font[2048]
Definition: xga_font_data.c:29
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
static int read_channels(AVFilterContext *ctx, int channels, uint8_t *item_str, int ab)
Definition: af_aiir.c:340
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
const char * r
Definition: vf_curves.c:114
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:116
const char * arg
Definition: jacosubdec.c:66
simple assert() macros that are a bit more flexible than ISO C assert().
#define AF
Definition: af_aiir.c:1089
#define FFMAX(a, b)
Definition: common.h:94
char * g_str
Definition: af_aiir.c:58
#define fail()
Definition: checkasm.h:121
static float distance(float x, float y, int band)
double g
Definition: af_aiir.c:50
static av_const double hypot(double x, double y)
Definition: libm.h:366
#define NAN
Definition: mathematics.h:64
static int convert_zp2tf(AVFilterContext *ctx, int channels)
Definition: af_aiir.c:433
float fmaxf(float, float)
signed 32 bits, planar
Definition: samplefmt.h:68
char * b_str
Definition: af_aiir.c:58
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:440
int32_t
AVFormatContext * ctx
Definition: movenc.c:48
#define a2
Definition: regdef.h:48
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:540
A list of supported channel layouts.
Definition: formats.h:85
static void draw_response(AVFilterContext *ctx, AVFrame *out)
Definition: af_aiir.c:721
#define VF
Definition: af_aiir.c:1090
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
static int mix(int c0, int c1)
Definition: 4xm.c:710
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
double wet_gain
Definition: af_aiir.c:59
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:594
Used for passing data between threads.
Definition: dsddec.c:64
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
Describe the class of an AVClass context structure.
Definition: log.h:67
static int read_gains(AVFilterContext *ctx, char *item_str, int nb_items)
Definition: af_aiir.c:255
Filter definition.
Definition: avfilter.h:144
AVFrame * mask
static void convert_pr2zp(AVFilterContext *ctx, int channels)
Definition: af_aiir.c:618
Rational number (pair of numerator and denominator).
Definition: rational.h:58
#define isnan(x)
Definition: libm.h:340
AVFrame * b
float im
Definition: fft.c:82
int a
Definition: af_aiir.c:37
offset must point to AVRational
Definition: opt.h:236
int b
Definition: af_aiir.c:37
double mix
Definition: af_aiir.c:60
const char * name
Filter name.
Definition: avfilter.h:148
static int read_zp_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst, const char *format)
Definition: af_aiir.c:313
#define snprintf
Definition: snprintf.h:34
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_aiir.c:1056
offset must point to two consecutive integers
Definition: opt.h:233
static const AVFilterPad inputs[]
Definition: af_aiir.c:1079
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFrame * min
Definition: vf_threshold.c:74
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:395
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:378
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
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
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
int(* iir_channel)(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
Definition: af_aiir.c:75
static void draw_line(AVFrame *out, int x0, int y0, int x1, int y1, uint32_t color)
Definition: af_aiir.c:695
IIRChannel * iir
Definition: af_aiir.c:71
int
#define OFFSET(x)
Definition: af_aiir.c:1088
AVFrame * video
Definition: af_aiir.c:69
avfilter_execute_func * execute
Definition: internal.h:155
double * ab[2]
Definition: af_aiir.c:49
AVRational rate
Definition: af_aiir.c:67
#define av_free(p)
A list of supported formats for one end of a filter link.
Definition: formats.h:64
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_aiir.c:941
An instance of a filter.
Definition: avfilter.h:338
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
AVFILTER_DEFINE_CLASS(aiir)
#define av_freep(p)
signed 16 bits, planar
Definition: samplefmt.h:67
#define M_PI
Definition: mathematics.h:52
#define av_malloc_array(a, b)
int nb_ab[2]
Definition: af_aiir.c:48
AVFrame * in
Definition: af_afftdn.c:1082
formats
Definition: signature.h:48
AVFilterLink * inlink
Definition: vf_blend.c:56
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:410
static int ff_insert_outpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new output pad for the filter.
Definition: internal.h:285
AVFrame * a
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:361
Definition: af_aiir.c:36
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:556
int ir_channel
Definition: af_aiir.c:66
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
static const AVOption aiir_options[]
Definition: af_aiir.c:1092
CGA/EGA/VGA ROM font data.
AVFrame * max
Definition: vf_threshold.c:75
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
static void multiply(double wre, double wim, int npz, double *coeffs)
Definition: af_aiir.c:387