FFmpeg
af_compand.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1999 Chris Bagwell
3  * Copyright (c) 1999 Nick Bailey
4  * Copyright (c) 2007 Rob Sykes <robs@users.sourceforge.net>
5  * Copyright (c) 2013 Paul B Mahol
6  * Copyright (c) 2014 Andrew Kelley
7  *
8  * This file is part of FFmpeg.
9  *
10  * FFmpeg is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * FFmpeg is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with FFmpeg; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 /**
26  * @file
27  * audio compand filter
28  */
29 
30 #include "libavutil/avassert.h"
31 #include "libavutil/avstring.h"
32 #include "libavutil/ffmath.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/samplefmt.h"
35 #include "audio.h"
36 #include "avfilter.h"
37 #include "internal.h"
38 
39 typedef struct ChanParam {
40  double attack;
41  double decay;
42  double volume;
43 } ChanParam;
44 
45 typedef struct CompandSegment {
46  double x, y;
47  double a, b;
49 
50 typedef struct CompandContext {
51  const AVClass *class;
53  char *attacks, *decays, *points;
56  double in_min_lin;
57  double out_min_lin;
58  double curve_dB;
59  double gain_dB;
61  double delay;
66  int64_t pts;
67 
70 
71 #define OFFSET(x) offsetof(CompandContext, x)
72 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
73 
74 static const AVOption compand_options[] = {
75  { "attacks", "set time over which increase of volume is determined", OFFSET(attacks), AV_OPT_TYPE_STRING, { .str = "0" }, 0, 0, A },
76  { "decays", "set time over which decrease of volume is determined", OFFSET(decays), AV_OPT_TYPE_STRING, { .str = "0.8" }, 0, 0, A },
77  { "points", "set points of transfer function", OFFSET(points), AV_OPT_TYPE_STRING, { .str = "-70/-70|-60/-20|1/0" }, 0, 0, A },
78  { "soft-knee", "set soft-knee", OFFSET(curve_dB), AV_OPT_TYPE_DOUBLE, { .dbl = 0.01 }, 0.01, 900, A },
79  { "gain", "set output gain", OFFSET(gain_dB), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -900, 900, A },
80  { "volume", "set initial volume", OFFSET(initial_volume), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -900, 0, A },
81  { "delay", "set delay for samples before sending them to volume adjuster", OFFSET(delay), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, 0, 20, A },
82  { NULL }
83 };
84 
85 AVFILTER_DEFINE_CLASS(compand);
86 
88 {
89  CompandContext *s = ctx->priv;
90  s->pts = AV_NOPTS_VALUE;
91  return 0;
92 }
93 
95 {
96  CompandContext *s = ctx->priv;
97 
98  av_freep(&s->channels);
99  av_freep(&s->segments);
100  av_frame_free(&s->delay_frame);
101 }
102 
104 {
107  static const enum AVSampleFormat sample_fmts[] = {
110  };
111  int ret;
112 
114  if (!layouts)
115  return AVERROR(ENOMEM);
117  if (ret < 0)
118  return ret;
119 
121  if (!formats)
122  return AVERROR(ENOMEM);
124  if (ret < 0)
125  return ret;
126 
128  if (!formats)
129  return AVERROR(ENOMEM);
131 }
132 
133 static void count_items(char *item_str, int *nb_items)
134 {
135  char *p;
136 
137  *nb_items = 1;
138  for (p = item_str; *p; p++) {
139  if (*p == ' ' || *p == '|')
140  (*nb_items)++;
141  }
142 }
143 
144 static void update_volume(ChanParam *cp, double in)
145 {
146  double delta = in - cp->volume;
147 
148  if (delta > 0.0)
149  cp->volume += delta * cp->attack;
150  else
151  cp->volume += delta * cp->decay;
152 }
153 
154 static double get_volume(CompandContext *s, double in_lin)
155 {
156  CompandSegment *cs;
157  double in_log, out_log;
158  int i;
159 
160  if (in_lin < s->in_min_lin)
161  return s->out_min_lin;
162 
163  in_log = log(in_lin);
164 
165  for (i = 1; i < s->nb_segments; i++)
166  if (in_log <= s->segments[i].x)
167  break;
168  cs = &s->segments[i - 1];
169  in_log -= cs->x;
170  out_log = cs->y + in_log * (cs->a * in_log + cs->b);
171 
172  return exp(out_log);
173 }
174 
176 {
177  CompandContext *s = ctx->priv;
178  AVFilterLink *inlink = ctx->inputs[0];
179  const int channels = inlink->channels;
180  const int nb_samples = frame->nb_samples;
181  AVFrame *out_frame;
182  int chan, i;
183  int err;
184 
186  out_frame = frame;
187  } else {
188  out_frame = ff_get_audio_buffer(ctx->outputs[0], nb_samples);
189  if (!out_frame) {
191  return AVERROR(ENOMEM);
192  }
193  err = av_frame_copy_props(out_frame, frame);
194  if (err < 0) {
195  av_frame_free(&out_frame);
197  return err;
198  }
199  }
200 
201  for (chan = 0; chan < channels; chan++) {
202  const double *src = (double *)frame->extended_data[chan];
203  double *dst = (double *)out_frame->extended_data[chan];
204  ChanParam *cp = &s->channels[chan];
205 
206  for (i = 0; i < nb_samples; i++) {
207  update_volume(cp, fabs(src[i]));
208 
209  dst[i] = src[i] * get_volume(s, cp->volume);
210  }
211  }
212 
213  if (frame != out_frame)
215 
216  return ff_filter_frame(ctx->outputs[0], out_frame);
217 }
218 
219 #define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a))
220 
222 {
223  CompandContext *s = ctx->priv;
224  AVFilterLink *inlink = ctx->inputs[0];
225  const int channels = inlink->channels;
226  const int nb_samples = frame->nb_samples;
227  int chan, i, av_uninit(dindex), oindex, av_uninit(count);
228  AVFrame *out_frame = NULL;
229  int err;
230 
231  if (s->pts == AV_NOPTS_VALUE) {
232  s->pts = (frame->pts == AV_NOPTS_VALUE) ? 0 : frame->pts;
233  }
234 
235  av_assert1(channels > 0); /* would corrupt delay_count and delay_index */
236 
237  for (chan = 0; chan < channels; chan++) {
238  AVFrame *delay_frame = s->delay_frame;
239  const double *src = (double *)frame->extended_data[chan];
240  double *dbuf = (double *)delay_frame->extended_data[chan];
241  ChanParam *cp = &s->channels[chan];
242  double *dst;
243 
244  count = s->delay_count;
245  dindex = s->delay_index;
246  for (i = 0, oindex = 0; i < nb_samples; i++) {
247  const double in = src[i];
248  update_volume(cp, fabs(in));
249 
250  if (count >= s->delay_samples) {
251  if (!out_frame) {
252  out_frame = ff_get_audio_buffer(ctx->outputs[0], nb_samples - i);
253  if (!out_frame) {
255  return AVERROR(ENOMEM);
256  }
257  err = av_frame_copy_props(out_frame, frame);
258  if (err < 0) {
259  av_frame_free(&out_frame);
261  return err;
262  }
263  out_frame->pts = s->pts;
264  s->pts += av_rescale_q(nb_samples - i,
265  (AVRational){ 1, inlink->sample_rate },
266  inlink->time_base);
267  }
268 
269  dst = (double *)out_frame->extended_data[chan];
270  dst[oindex++] = dbuf[dindex] * get_volume(s, cp->volume);
271  } else {
272  count++;
273  }
274 
275  dbuf[dindex] = in;
276  dindex = MOD(dindex + 1, s->delay_samples);
277  }
278  }
279 
280  s->delay_count = count;
281  s->delay_index = dindex;
282 
284 
285  if (out_frame) {
286  err = ff_filter_frame(ctx->outputs[0], out_frame);
287  return err;
288  }
289 
290  return 0;
291 }
292 
293 static int compand_drain(AVFilterLink *outlink)
294 {
295  AVFilterContext *ctx = outlink->src;
296  CompandContext *s = ctx->priv;
297  const int channels = outlink->channels;
298  AVFrame *frame = NULL;
299  int chan, i, dindex;
300 
301  /* 2048 is to limit output frame size during drain */
302  frame = ff_get_audio_buffer(outlink, FFMIN(2048, s->delay_count));
303  if (!frame)
304  return AVERROR(ENOMEM);
305  frame->pts = s->pts;
306  s->pts += av_rescale_q(frame->nb_samples,
307  (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
308 
309  av_assert0(channels > 0);
310  for (chan = 0; chan < channels; chan++) {
311  AVFrame *delay_frame = s->delay_frame;
312  double *dbuf = (double *)delay_frame->extended_data[chan];
313  double *dst = (double *)frame->extended_data[chan];
314  ChanParam *cp = &s->channels[chan];
315 
316  dindex = s->delay_index;
317  for (i = 0; i < frame->nb_samples; i++) {
318  dst[i] = dbuf[dindex] * get_volume(s, cp->volume);
319  dindex = MOD(dindex + 1, s->delay_samples);
320  }
321  }
322  s->delay_count -= frame->nb_samples;
323  s->delay_index = dindex;
324 
325  return ff_filter_frame(outlink, frame);
326 }
327 
328 static int config_output(AVFilterLink *outlink)
329 {
330  AVFilterContext *ctx = outlink->src;
331  CompandContext *s = ctx->priv;
332  const int sample_rate = outlink->sample_rate;
333  double radius = s->curve_dB * M_LN10 / 20.0;
334  char *p, *saveptr = NULL;
335  const int channels = outlink->channels;
336  int nb_attacks, nb_decays, nb_points;
337  int new_nb_items, num;
338  int i;
339  int err;
340 
341 
342  count_items(s->attacks, &nb_attacks);
343  count_items(s->decays, &nb_decays);
344  count_items(s->points, &nb_points);
345 
346  if (channels <= 0) {
347  av_log(ctx, AV_LOG_ERROR, "Invalid number of channels: %d\n", channels);
348  return AVERROR(EINVAL);
349  }
350 
351  if (nb_attacks > channels || nb_decays > channels) {
353  "Number of attacks/decays bigger than number of channels. Ignoring rest of entries.\n");
354  nb_attacks = FFMIN(nb_attacks, channels);
355  nb_decays = FFMIN(nb_decays, channels);
356  }
357 
358  uninit(ctx);
359 
360  s->channels = av_mallocz_array(channels, sizeof(*s->channels));
361  s->nb_segments = (nb_points + 4) * 2;
362  s->segments = av_mallocz_array(s->nb_segments, sizeof(*s->segments));
363 
364  if (!s->channels || !s->segments) {
365  uninit(ctx);
366  return AVERROR(ENOMEM);
367  }
368 
369  p = s->attacks;
370  for (i = 0, new_nb_items = 0; i < nb_attacks; i++) {
371  char *tstr = av_strtok(p, " |", &saveptr);
372  if (!tstr) {
373  uninit(ctx);
374  return AVERROR(EINVAL);
375  }
376  p = NULL;
377  new_nb_items += sscanf(tstr, "%lf", &s->channels[i].attack) == 1;
378  if (s->channels[i].attack < 0) {
379  uninit(ctx);
380  return AVERROR(EINVAL);
381  }
382  }
383  nb_attacks = new_nb_items;
384 
385  p = s->decays;
386  for (i = 0, new_nb_items = 0; i < nb_decays; i++) {
387  char *tstr = av_strtok(p, " |", &saveptr);
388  if (!tstr) {
389  uninit(ctx);
390  return AVERROR(EINVAL);
391  }
392  p = NULL;
393  new_nb_items += sscanf(tstr, "%lf", &s->channels[i].decay) == 1;
394  if (s->channels[i].decay < 0) {
395  uninit(ctx);
396  return AVERROR(EINVAL);
397  }
398  }
399  nb_decays = new_nb_items;
400 
401  if (nb_attacks != nb_decays) {
403  "Number of attacks %d differs from number of decays %d.\n",
404  nb_attacks, nb_decays);
405  uninit(ctx);
406  return AVERROR(EINVAL);
407  }
408 
409  for (i = nb_decays; i < channels; i++) {
410  s->channels[i].attack = s->channels[nb_decays - 1].attack;
411  s->channels[i].decay = s->channels[nb_decays - 1].decay;
412  }
413 
414 #define S(x) s->segments[2 * ((x) + 1)]
415  p = s->points;
416  for (i = 0, new_nb_items = 0; i < nb_points; i++) {
417  char *tstr = av_strtok(p, " |", &saveptr);
418  p = NULL;
419  if (!tstr || sscanf(tstr, "%lf/%lf", &S(i).x, &S(i).y) != 2) {
421  "Invalid and/or missing input/output value.\n");
422  uninit(ctx);
423  return AVERROR(EINVAL);
424  }
425  if (i && S(i - 1).x > S(i).x) {
427  "Transfer function input values must be increasing.\n");
428  uninit(ctx);
429  return AVERROR(EINVAL);
430  }
431  S(i).y -= S(i).x;
432  av_log(ctx, AV_LOG_DEBUG, "%d: x=%f y=%f\n", i, S(i).x, S(i).y);
433  new_nb_items++;
434  }
435  num = new_nb_items;
436 
437  /* Add 0,0 if necessary */
438  if (num == 0 || S(num - 1).x)
439  num++;
440 
441 #undef S
442 #define S(x) s->segments[2 * (x)]
443  /* Add a tail off segment at the start */
444  S(0).x = S(1).x - 2 * s->curve_dB;
445  S(0).y = S(1).y;
446  num++;
447 
448  /* Join adjacent colinear segments */
449  for (i = 2; i < num; i++) {
450  double g1 = (S(i - 1).y - S(i - 2).y) * (S(i - 0).x - S(i - 1).x);
451  double g2 = (S(i - 0).y - S(i - 1).y) * (S(i - 1).x - S(i - 2).x);
452  int j;
453 
454  if (fabs(g1 - g2))
455  continue;
456  num--;
457  for (j = --i; j < num; j++)
458  S(j) = S(j + 1);
459  }
460 
461  for (i = 0; i < s->nb_segments; i += 2) {
462  s->segments[i].y += s->gain_dB;
463  s->segments[i].x *= M_LN10 / 20;
464  s->segments[i].y *= M_LN10 / 20;
465  }
466 
467 #define L(x) s->segments[i - (x)]
468  for (i = 4; i < s->nb_segments; i += 2) {
469  double x, y, cx, cy, in1, in2, out1, out2, theta, len, r;
470 
471  L(4).a = 0;
472  L(4).b = (L(2).y - L(4).y) / (L(2).x - L(4).x);
473 
474  L(2).a = 0;
475  L(2).b = (L(0).y - L(2).y) / (L(0).x - L(2).x);
476 
477  theta = atan2(L(2).y - L(4).y, L(2).x - L(4).x);
478  len = hypot(L(2).x - L(4).x, L(2).y - L(4).y);
479  r = FFMIN(radius, len);
480  L(3).x = L(2).x - r * cos(theta);
481  L(3).y = L(2).y - r * sin(theta);
482 
483  theta = atan2(L(0).y - L(2).y, L(0).x - L(2).x);
484  len = hypot(L(0).x - L(2).x, L(0).y - L(2).y);
485  r = FFMIN(radius, len / 2);
486  x = L(2).x + r * cos(theta);
487  y = L(2).y + r * sin(theta);
488 
489  cx = (L(3).x + L(2).x + x) / 3;
490  cy = (L(3).y + L(2).y + y) / 3;
491 
492  L(2).x = x;
493  L(2).y = y;
494 
495  in1 = cx - L(3).x;
496  out1 = cy - L(3).y;
497  in2 = L(2).x - L(3).x;
498  out2 = L(2).y - L(3).y;
499  L(3).a = (out2 / in2 - out1 / in1) / (in2 - in1);
500  L(3).b = out1 / in1 - L(3).a * in1;
501  }
502  L(3).x = 0;
503  L(3).y = L(2).y;
504 
505  s->in_min_lin = exp(s->segments[1].x);
506  s->out_min_lin = exp(s->segments[1].y);
507 
508  for (i = 0; i < channels; i++) {
509  ChanParam *cp = &s->channels[i];
510 
511  if (cp->attack > 1.0 / sample_rate)
512  cp->attack = 1.0 - exp(-1.0 / (sample_rate * cp->attack));
513  else
514  cp->attack = 1.0;
515  if (cp->decay > 1.0 / sample_rate)
516  cp->decay = 1.0 - exp(-1.0 / (sample_rate * cp->decay));
517  else
518  cp->decay = 1.0;
519  cp->volume = ff_exp10(s->initial_volume / 20);
520  }
521 
522  s->delay_samples = s->delay * sample_rate;
523  if (s->delay_samples <= 0) {
524  s->compand = compand_nodelay;
525  return 0;
526  }
527 
528  s->delay_frame = av_frame_alloc();
529  if (!s->delay_frame) {
530  uninit(ctx);
531  return AVERROR(ENOMEM);
532  }
533 
534  s->delay_frame->format = outlink->format;
535  s->delay_frame->nb_samples = s->delay_samples;
536  s->delay_frame->channel_layout = outlink->channel_layout;
537 
538  err = av_frame_get_buffer(s->delay_frame, 0);
539  if (err)
540  return err;
541 
542  s->compand = compand_delay;
543  return 0;
544 }
545 
547 {
548  AVFilterContext *ctx = inlink->dst;
549  CompandContext *s = ctx->priv;
550 
551  return s->compand(ctx, frame);
552 }
553 
554 static int request_frame(AVFilterLink *outlink)
555 {
556  AVFilterContext *ctx = outlink->src;
557  CompandContext *s = ctx->priv;
558  int ret = 0;
559 
560  ret = ff_request_frame(ctx->inputs[0]);
561 
562  if (ret == AVERROR_EOF && !ctx->is_disabled && s->delay_count)
563  ret = compand_drain(outlink);
564 
565  return ret;
566 }
567 
568 static const AVFilterPad compand_inputs[] = {
569  {
570  .name = "default",
571  .type = AVMEDIA_TYPE_AUDIO,
572  .filter_frame = filter_frame,
573  },
574  { NULL }
575 };
576 
577 static const AVFilterPad compand_outputs[] = {
578  {
579  .name = "default",
580  .request_frame = request_frame,
581  .config_props = config_output,
582  .type = AVMEDIA_TYPE_AUDIO,
583  },
584  { NULL }
585 };
586 
587 
589  .name = "compand",
590  .description = NULL_IF_CONFIG_SMALL(
591  "Compress or expand audio dynamic range."),
592  .query_formats = query_formats,
593  .priv_size = sizeof(CompandContext),
594  .priv_class = &compand_class,
595  .init = init,
596  .uninit = uninit,
599 };
CompandContext::delay
double delay
Definition: af_compand.c:61
formats
formats
Definition: signature.h:48
ff_get_audio_buffer
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
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: af_compand.c:103
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:86
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
ff_exp10
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
Definition: ffmath.h:42
r
const char * r
Definition: vf_curves.c:116
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
compand_delay
static int compand_delay(AVFilterContext *ctx, AVFrame *frame)
Definition: af_compand.c:221
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
av_frame_get_buffer
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:337
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1096
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:925
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
CompandSegment::b
double b
Definition: af_compand.c:47
inlink
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
Definition: filter_design.txt:212
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
ff_all_channel_counts
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:436
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:411
AVOption
AVOption.
Definition: opt.h:248
ff_request_frame
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:408
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:190
OFFSET
#define OFFSET(x)
Definition: af_compand.c:71
CompandContext::out_min_lin
double out_min_lin
Definition: af_compand.c:57
init
static av_cold int init(AVFilterContext *ctx)
Definition: af_compand.c:87
CompandSegment::x
double x
Definition: af_compand.c:46
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:149
CompandSegment
Definition: af_compand.c:45
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(compand)
sample_rate
sample_rate
Definition: ffmpeg_filter.c:170
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:65
CompandContext
Definition: af_compand.c:50
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: af_compand.c:554
samplefmt.h
config_output
static int config_output(AVFilterLink *outlink)
Definition: af_compand.c:328
CompandContext::attacks
char * attacks
Definition: af_compand.c:53
ChanParam::attack
double attack
Definition: af_compand.c:40
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
compand_options
static const AVOption compand_options[]
Definition: af_compand.c:74
CompandContext::delay_frame
AVFrame * delay_frame
Definition: af_compand.c:62
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
CompandContext::curve_dB
double curve_dB
Definition: af_compand.c:58
av_cold
#define av_cold
Definition: attributes.h:90
ff_set_common_formats
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:587
s
#define s(width, name)
Definition: cbs_vp9.c:257
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:227
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
av_strtok
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:186
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
ctx
AVFormatContext * ctx
Definition: movenc.c:48
channels
channels
Definition: aptx.h:33
CompandContext::delay_samples
int delay_samples
Definition: af_compand.c:63
av_rescale_q
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
compand_nodelay
static int compand_nodelay(AVFilterContext *ctx, AVFrame *frame)
Definition: af_compand.c:175
compand_inputs
static const AVFilterPad compand_inputs[]
Definition: af_compand.c:568
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
CompandContext::channels
ChanParam * channels
Definition: af_compand.c:55
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:658
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
get_volume
static double get_volume(CompandContext *s, double in_lin)
Definition: af_compand.c:154
src
#define src
Definition: vp8dsp.c:255
CompandContext::decays
char * decays
Definition: af_compand.c:53
update_volume
static void update_volume(ChanParam *cp, double in)
Definition: af_compand.c:144
CompandContext::compand
int(* compand)(AVFilterContext *ctx, AVFrame *frame)
Definition: af_compand.c:68
inputs
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 inputs
Definition: filter_design.txt:243
exp
int8_t exp
Definition: eval.c:72
CompandContext::segments
CompandSegment * segments
Definition: af_compand.c:54
ff_af_compand
AVFilter ff_af_compand
Definition: af_compand.c:588
compand_drain
static int compand_drain(AVFilterLink *outlink)
Definition: af_compand.c:293
CompandContext::in_min_lin
double in_min_lin
Definition: af_compand.c:56
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
L
#define L(x)
MOD
#define MOD(a, b)
Definition: af_compand.c:219
CompandContext::nb_segments
int nb_segments
Definition: af_compand.c:52
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:366
CompandContext::delay_index
int delay_index
Definition: af_compand.c:65
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: af_compand.c:546
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:594
CompandContext::delay_count
int delay_count
Definition: af_compand.c:64
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
CompandContext::points
char * points
Definition: af_compand.c:53
A
#define A
Definition: af_compand.c:72
CompandContext::gain_dB
double gain_dB
Definition: af_compand.c:59
internal.h
in
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
Definition: audio_convert.c:326
i
int i
Definition: input.c:407
CompandContext::pts
int64_t pts
Definition: af_compand.c:66
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:365
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
delta
float delta
Definition: vorbis_enc_data.h:457
len
int len
Definition: vorbis_enc_data.h:452
CompandSegment::y
double y
Definition: af_compand.c:46
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
AVFilter
Filter definition.
Definition: avfilter.h:145
av_uninit
#define av_uninit(x)
Definition: attributes.h:154
ret
ret
Definition: filter_design.txt:187
frame
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 or at least make progress towards producing a frame
Definition: filter_design.txt:264
S
#define S(x)
ff_all_samplerates
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:421
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_compand.c:94
avfilter.h
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
ffmath.h
AVFilterContext
An instance of a filter.
Definition: avfilter.h:341
count_items
static void count_items(char *item_str, int *nb_items)
Definition: af_compand.c:133
audio.h
M_LN10
#define M_LN10
Definition: mathematics.h:43
ChanParam
Definition: af_compand.c:39
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
ff_set_common_samplerates
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:575
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
int
int
Definition: ffmpeg_filter.c:170
ChanParam::decay
double decay
Definition: af_compand.c:41
CompandSegment::a
double a
Definition: af_compand.c:47
CompandContext::initial_volume
double initial_volume
Definition: af_compand.c:60
ChanParam::volume
double volume
Definition: af_compand.c:42
compand_outputs
static const AVFilterPad compand_outputs[]
Definition: af_compand.c:577
ff_set_common_channel_layouts
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *channel_layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates.
Definition: formats.c:568