FFmpeg
af_loudnorm.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Kyle Swanson <k@ylo.ph>.
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 /* http://k.ylo.ph/2016/04/04/loudnorm.html */
22 
23 #include "libavutil/file_open.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/opt.h"
26 #include "avfilter.h"
27 #include "filters.h"
28 #include "formats.h"
29 #include "audio.h"
30 #include "ebur128.h"
31 
32 enum FrameType {
38 };
39 
41  OUT,
46 };
47 
53 };
54 
55 typedef struct LoudNormContext {
56  const AVClass *class;
57  double target_i;
58  double target_lra;
59  double target_tp;
60  double measured_i;
61  double measured_lra;
62  double measured_tp;
64  double offset;
65  int linear;
66  int dual_mono;
67  /* enum PrintFormat */
70 
71  double *buf;
72  int buf_size;
73  int buf_index;
75 
76  double delta[30];
77  double weights[21];
78  double prev_delta;
79  int index;
80 
81  double gain_reduction[2];
82  double *limiter_buf;
83  double *prev_smp;
88  int env_index;
89  int env_cnt;
92 
93  int64_t pts[30];
97  int channels;
98 
102 
103 #define OFFSET(x) offsetof(LoudNormContext, x)
104 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
105 
106 static const AVOption loudnorm_options[] = {
107  { "I", "set integrated loudness target", OFFSET(target_i), AV_OPT_TYPE_DOUBLE, {.dbl = -24.}, -70., -5., FLAGS },
108  { "i", "set integrated loudness target", OFFSET(target_i), AV_OPT_TYPE_DOUBLE, {.dbl = -24.}, -70., -5., FLAGS },
109  { "LRA", "set loudness range target", OFFSET(target_lra), AV_OPT_TYPE_DOUBLE, {.dbl = 7.}, 1., 50., FLAGS },
110  { "lra", "set loudness range target", OFFSET(target_lra), AV_OPT_TYPE_DOUBLE, {.dbl = 7.}, 1., 50., FLAGS },
111  { "TP", "set maximum true peak", OFFSET(target_tp), AV_OPT_TYPE_DOUBLE, {.dbl = -2.}, -9., 0., FLAGS },
112  { "tp", "set maximum true peak", OFFSET(target_tp), AV_OPT_TYPE_DOUBLE, {.dbl = -2.}, -9., 0., FLAGS },
113  { "measured_I", "measured IL of input file", OFFSET(measured_i), AV_OPT_TYPE_DOUBLE, {.dbl = 0.}, -99., 0., FLAGS },
114  { "measured_i", "measured IL of input file", OFFSET(measured_i), AV_OPT_TYPE_DOUBLE, {.dbl = 0.}, -99., 0., FLAGS },
115  { "measured_LRA", "measured LRA of input file", OFFSET(measured_lra), AV_OPT_TYPE_DOUBLE, {.dbl = 0.}, 0., 99., FLAGS },
116  { "measured_lra", "measured LRA of input file", OFFSET(measured_lra), AV_OPT_TYPE_DOUBLE, {.dbl = 0.}, 0., 99., FLAGS },
117  { "measured_TP", "measured true peak of input file", OFFSET(measured_tp), AV_OPT_TYPE_DOUBLE, {.dbl = 99.}, -99., 99., FLAGS },
118  { "measured_tp", "measured true peak of input file", OFFSET(measured_tp), AV_OPT_TYPE_DOUBLE, {.dbl = 99.}, -99., 99., FLAGS },
119  { "measured_thresh", "measured threshold of input file", OFFSET(measured_thresh), AV_OPT_TYPE_DOUBLE, {.dbl = -70.}, -99., 0., FLAGS },
120  { "offset", "set offset gain", OFFSET(offset), AV_OPT_TYPE_DOUBLE, {.dbl = 0.}, -99., 99., FLAGS },
121  { "linear", "normalize linearly if possible", OFFSET(linear), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS },
122  { "dual_mono", "treat mono input as dual-mono", OFFSET(dual_mono), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS },
123  { "print_format", "set print format for stats", OFFSET(print_format), AV_OPT_TYPE_INT, {.i64 = NONE}, NONE, PF_NB -1, FLAGS, .unit = "print_format" },
124  { "none", 0, 0, AV_OPT_TYPE_CONST, {.i64 = NONE}, 0, 0, FLAGS, .unit = "print_format" },
125  { "json", 0, 0, AV_OPT_TYPE_CONST, {.i64 = JSON}, 0, 0, FLAGS, .unit = "print_format" },
126  { "summary", 0, 0, AV_OPT_TYPE_CONST, {.i64 = SUMMARY}, 0, 0, FLAGS, .unit = "print_format" },
127  { "stats_file", "set stats output file", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
128  { NULL }
129 };
130 
131 AVFILTER_DEFINE_CLASS(loudnorm);
132 
133 static inline int frame_size(int sample_rate, int frame_len_msec)
134 {
135  const int frame_size = round((double)sample_rate * (frame_len_msec / 1000.0));
136  return frame_size + (frame_size % 2);
137 }
138 
140 {
141  double total_weight = 0.0;
142  const double sigma = 3.5;
143  double adjust;
144  int i;
145 
146  const int offset = 21 / 2;
147  const double c1 = 1.0 / (sigma * sqrt(2.0 * M_PI));
148  const double c2 = 2.0 * pow(sigma, 2.0);
149 
150  for (i = 0; i < 21; i++) {
151  const int x = i - offset;
152  s->weights[i] = c1 * exp(-(pow(x, 2.0) / c2));
153  total_weight += s->weights[i];
154  }
155 
156  adjust = 1.0 / total_weight;
157  for (i = 0; i < 21; i++)
158  s->weights[i] *= adjust;
159 }
160 
162 {
163  double result = 0.;
164  int i;
165 
166  index = index - 10 > 0 ? index - 10 : index + 20;
167  for (i = 0; i < 21; i++)
168  result += s->delta[((index + i) < 30) ? (index + i) : (index + i - 30)] * s->weights[i];
169 
170  return result;
171 }
172 
173 static void detect_peak(LoudNormContext *s, int offset, int nb_samples, int channels, int *peak_delta, double *peak_value)
174 {
175  int n, c, i, index;
176  double ceiling;
177  double *buf;
178 
179  *peak_delta = -1;
180  buf = s->limiter_buf;
181  ceiling = s->target_tp;
182 
183  index = s->limiter_buf_index + (offset * channels) + (1920 * channels);
184  if (index >= s->limiter_buf_size)
185  index -= s->limiter_buf_size;
186 
187  if (s->frame_type == FIRST_FRAME) {
188  for (c = 0; c < channels; c++)
189  s->prev_smp[c] = fabs(buf[index + c - channels]);
190  }
191 
192  for (n = 0; n < nb_samples; n++) {
193  for (c = 0; c < channels; c++) {
194  double this, next, max_peak;
195 
196  this = fabs(buf[(index + c) < s->limiter_buf_size ? (index + c) : (index + c - s->limiter_buf_size)]);
197  next = fabs(buf[(index + c + channels) < s->limiter_buf_size ? (index + c + channels) : (index + c + channels - s->limiter_buf_size)]);
198 
199  if ((s->prev_smp[c] <= this) && (next <= this) && (this > ceiling) && (n > 0)) {
200  int detected;
201 
202  detected = 1;
203  for (i = 2; i < 12; i++) {
204  next = fabs(buf[(index + c + (i * channels)) < s->limiter_buf_size ? (index + c + (i * channels)) : (index + c + (i * channels) - s->limiter_buf_size)]);
205  if (next > this) {
206  detected = 0;
207  break;
208  }
209  }
210 
211  if (!detected)
212  continue;
213 
214  for (c = 0; c < channels; c++) {
215  if (c == 0 || fabs(buf[index + c]) > max_peak)
216  max_peak = fabs(buf[index + c]);
217 
218  s->prev_smp[c] = fabs(buf[(index + c) < s->limiter_buf_size ? (index + c) : (index + c - s->limiter_buf_size)]);
219  }
220 
221  *peak_delta = n;
222  s->peak_index = index;
223  *peak_value = max_peak;
224  return;
225  }
226 
227  s->prev_smp[c] = this;
228  }
229 
230  index += channels;
231  if (index >= s->limiter_buf_size)
232  index -= s->limiter_buf_size;
233  }
234 }
235 
236 static void true_peak_limiter(LoudNormContext *s, double *out, int nb_samples, int channels)
237 {
238  int n, c, index, peak_delta, smp_cnt;
239  double ceiling, peak_value;
240  double *buf;
241 
242  buf = s->limiter_buf;
243  ceiling = s->target_tp;
244  index = s->limiter_buf_index;
245  smp_cnt = 0;
246 
247  if (s->frame_type == FIRST_FRAME) {
248  double max;
249 
250  max = 0.;
251  for (n = 0; n < 1920; n++) {
252  for (c = 0; c < channels; c++) {
253  max = fabs(buf[c]) > max ? fabs(buf[c]) : max;
254  }
255  buf += channels;
256  }
257 
258  if (max > ceiling) {
259  s->gain_reduction[1] = ceiling / max;
260  s->limiter_state = SUSTAIN;
261  buf = s->limiter_buf;
262 
263  for (n = 0; n < 1920; n++) {
264  for (c = 0; c < channels; c++) {
265  double env;
266  env = s->gain_reduction[1];
267  buf[c] *= env;
268  }
269  buf += channels;
270  }
271  }
272 
273  buf = s->limiter_buf;
274  }
275 
276  do {
277 
278  switch(s->limiter_state) {
279  case OUT:
280  detect_peak(s, smp_cnt, nb_samples - smp_cnt, channels, &peak_delta, &peak_value);
281  if (peak_delta != -1) {
282  s->env_cnt = 0;
283  smp_cnt += (peak_delta - s->attack_length);
284  s->gain_reduction[0] = 1.;
285  s->gain_reduction[1] = ceiling / peak_value;
286  s->limiter_state = ATTACK;
287 
288  s->env_index = s->peak_index - (s->attack_length * channels);
289  if (s->env_index < 0)
290  s->env_index += s->limiter_buf_size;
291 
292  s->env_index += (s->env_cnt * channels);
293  if (s->env_index > s->limiter_buf_size)
294  s->env_index -= s->limiter_buf_size;
295 
296  } else {
297  smp_cnt = nb_samples;
298  }
299  break;
300 
301  case ATTACK:
302  for (; s->env_cnt < s->attack_length; s->env_cnt++) {
303  for (c = 0; c < channels; c++) {
304  double env;
305  env = s->gain_reduction[0] - ((double) s->env_cnt / (s->attack_length - 1) * (s->gain_reduction[0] - s->gain_reduction[1]));
306  buf[s->env_index + c] *= env;
307  }
308 
309  s->env_index += channels;
310  if (s->env_index >= s->limiter_buf_size)
311  s->env_index -= s->limiter_buf_size;
312 
313  smp_cnt++;
314  if (smp_cnt >= nb_samples) {
315  s->env_cnt++;
316  break;
317  }
318  }
319 
320  if (smp_cnt < nb_samples) {
321  s->env_cnt = 0;
322  s->attack_length = 1920;
323  s->limiter_state = SUSTAIN;
324  }
325  break;
326 
327  case SUSTAIN:
328  detect_peak(s, smp_cnt, nb_samples, channels, &peak_delta, &peak_value);
329  if (peak_delta == -1) {
330  s->limiter_state = RELEASE;
331  s->gain_reduction[0] = s->gain_reduction[1];
332  s->gain_reduction[1] = 1.;
333  s->env_cnt = 0;
334  break;
335  } else {
336  double gain_reduction;
337  gain_reduction = ceiling / peak_value;
338 
339  if (gain_reduction < s->gain_reduction[1]) {
340  s->limiter_state = ATTACK;
341 
342  s->attack_length = peak_delta;
343  if (s->attack_length <= 1)
344  s->attack_length = 2;
345 
346  s->gain_reduction[0] = s->gain_reduction[1];
347  s->gain_reduction[1] = gain_reduction;
348  s->env_cnt = 0;
349  break;
350  }
351 
352  for (s->env_cnt = 0; s->env_cnt < peak_delta; s->env_cnt++) {
353  for (c = 0; c < channels; c++) {
354  double env;
355  env = s->gain_reduction[1];
356  buf[s->env_index + c] *= env;
357  }
358 
359  s->env_index += channels;
360  if (s->env_index >= s->limiter_buf_size)
361  s->env_index -= s->limiter_buf_size;
362 
363  smp_cnt++;
364  if (smp_cnt >= nb_samples) {
365  s->env_cnt++;
366  break;
367  }
368  }
369  }
370  break;
371 
372  case RELEASE:
373  for (; s->env_cnt < s->release_length; s->env_cnt++) {
374  for (c = 0; c < channels; c++) {
375  double env;
376  env = s->gain_reduction[0] + (((double) s->env_cnt / (s->release_length - 1)) * (s->gain_reduction[1] - s->gain_reduction[0]));
377  buf[s->env_index + c] *= env;
378  }
379 
380  s->env_index += channels;
381  if (s->env_index >= s->limiter_buf_size)
382  s->env_index -= s->limiter_buf_size;
383 
384  smp_cnt++;
385  if (smp_cnt >= nb_samples) {
386  s->env_cnt++;
387  break;
388  }
389  }
390 
391  if (smp_cnt < nb_samples) {
392  s->env_cnt = 0;
393  s->limiter_state = OUT;
394  }
395 
396  break;
397  }
398 
399  } while (smp_cnt < nb_samples);
400 
401  for (n = 0; n < nb_samples; n++) {
402  for (c = 0; c < channels; c++) {
403  out[c] = buf[index + c];
404  if (fabs(out[c]) > ceiling) {
405  out[c] = ceiling * (out[c] < 0 ? -1 : 1);
406  }
407  }
408  out += channels;
409  index += channels;
410  if (index >= s->limiter_buf_size)
411  index -= s->limiter_buf_size;
412  }
413 }
414 
416 {
417  AVFilterContext *ctx = inlink->dst;
418  LoudNormContext *s = ctx->priv;
419  AVFilterLink *outlink = ctx->outputs[0];
420  AVFrame *out;
421  const double *src;
422  double *dst;
423  double *buf;
424  double *limiter_buf;
425  int i, n, c, subframe_length, src_index;
426  double gain, gain_next, env_global, env_shortterm,
427  global, shortterm, lra, relative_threshold;
428 
429  if (av_frame_is_writable(in)) {
430  out = in;
431  } else {
432  out = ff_get_audio_buffer(outlink, in->nb_samples);
433  if (!out) {
434  av_frame_free(&in);
435  return AVERROR(ENOMEM);
436  }
438  }
439 
440  out->pts = s->pts[0];
441  memmove(s->pts, &s->pts[1], (FF_ARRAY_ELEMS(s->pts) - 1) * sizeof(s->pts[0]));
442 
443  src = (const double *)in->data[0];
444  dst = (double *)out->data[0];
445  buf = s->buf;
446  limiter_buf = s->limiter_buf;
447 
449 
450  if (s->frame_type == FIRST_FRAME && in->nb_samples < frame_size(inlink->sample_rate, 3000)) {
451  double offset, offset_tp, true_peak;
452 
453  ff_ebur128_loudness_global(s->r128_in, &global);
454  for (c = 0; c < inlink->ch_layout.nb_channels; c++) {
455  double tmp;
456  ff_ebur128_sample_peak(s->r128_in, c, &tmp);
457  if (c == 0 || tmp > true_peak)
458  true_peak = tmp;
459  }
460 
461  offset = pow(10., (s->target_i - global) / 20.);
462  offset_tp = true_peak * offset;
463  s->offset = offset_tp < s->target_tp ? offset : s->target_tp / true_peak;
464  s->frame_type = LINEAR_MODE;
465  }
466 
467  switch (s->frame_type) {
468  case FIRST_FRAME:
469  for (n = 0; n < in->nb_samples; n++) {
470  for (c = 0; c < inlink->ch_layout.nb_channels; c++) {
471  buf[s->buf_index + c] = src[c];
472  }
473  src += inlink->ch_layout.nb_channels;
474  s->buf_index += inlink->ch_layout.nb_channels;
475  }
476 
477  ff_ebur128_loudness_shortterm(s->r128_in, &shortterm);
478 
479  if (shortterm < s->measured_thresh) {
480  s->above_threshold = 0;
481  env_shortterm = shortterm <= -70. ? 0. : s->target_i - s->measured_i;
482  } else {
483  s->above_threshold = 1;
484  env_shortterm = shortterm <= -70. ? 0. : s->target_i - shortterm;
485  }
486 
487  for (n = 0; n < 30; n++)
488  s->delta[n] = pow(10., env_shortterm / 20.);
489  s->prev_delta = s->delta[s->index];
490 
491  s->buf_index =
492  s->limiter_buf_index = 0;
493 
494  for (n = 0; n < (s->limiter_buf_size / inlink->ch_layout.nb_channels); n++) {
495  for (c = 0; c < inlink->ch_layout.nb_channels; c++) {
496  limiter_buf[s->limiter_buf_index + c] = buf[s->buf_index + c] * s->delta[s->index] * s->offset;
497  }
498  s->limiter_buf_index += inlink->ch_layout.nb_channels;
499  if (s->limiter_buf_index >= s->limiter_buf_size)
500  s->limiter_buf_index -= s->limiter_buf_size;
501 
502  s->buf_index += inlink->ch_layout.nb_channels;
503  }
504 
505  subframe_length = frame_size(inlink->sample_rate, 100);
506  true_peak_limiter(s, dst, subframe_length, inlink->ch_layout.nb_channels);
507  ff_ebur128_add_frames_double(s->r128_out, dst, subframe_length);
508 
509  out->nb_samples = subframe_length;
510 
511  s->frame_type = INNER_FRAME;
512  break;
513 
514  case INNER_FRAME:
515  gain = gaussian_filter(s, s->index + 10 < 30 ? s->index + 10 : s->index + 10 - 30);
516  gain_next = gaussian_filter(s, s->index + 11 < 30 ? s->index + 11 : s->index + 11 - 30);
517 
518  for (n = 0; n < in->nb_samples; n++) {
519  for (c = 0; c < inlink->ch_layout.nb_channels; c++) {
520  buf[s->prev_buf_index + c] = src[c];
521  limiter_buf[s->limiter_buf_index + c] = buf[s->buf_index + c] * (gain + (((double) n / in->nb_samples) * (gain_next - gain))) * s->offset;
522  }
523  src += inlink->ch_layout.nb_channels;
524 
525  s->limiter_buf_index += inlink->ch_layout.nb_channels;
526  if (s->limiter_buf_index >= s->limiter_buf_size)
527  s->limiter_buf_index -= s->limiter_buf_size;
528 
529  s->prev_buf_index += inlink->ch_layout.nb_channels;
530  if (s->prev_buf_index >= s->buf_size)
531  s->prev_buf_index -= s->buf_size;
532 
533  s->buf_index += inlink->ch_layout.nb_channels;
534  if (s->buf_index >= s->buf_size)
535  s->buf_index -= s->buf_size;
536  }
537 
538  subframe_length = (frame_size(inlink->sample_rate, 100) - in->nb_samples) * inlink->ch_layout.nb_channels;
539  s->limiter_buf_index = s->limiter_buf_index + subframe_length < s->limiter_buf_size ? s->limiter_buf_index + subframe_length : s->limiter_buf_index + subframe_length - s->limiter_buf_size;
540 
541  true_peak_limiter(s, dst, in->nb_samples, inlink->ch_layout.nb_channels);
542  ff_ebur128_add_frames_double(s->r128_out, dst, in->nb_samples);
543 
544  ff_ebur128_loudness_range(s->r128_in, &lra);
545  ff_ebur128_loudness_global(s->r128_in, &global);
546  ff_ebur128_loudness_shortterm(s->r128_in, &shortterm);
547  ff_ebur128_relative_threshold(s->r128_in, &relative_threshold);
548 
549  if (s->above_threshold == 0) {
550  double shortterm_out;
551 
552  if (shortterm > s->measured_thresh)
553  s->prev_delta *= 1.0058;
554 
555  ff_ebur128_loudness_shortterm(s->r128_out, &shortterm_out);
556  if (shortterm_out >= s->target_i)
557  s->above_threshold = 1;
558  }
559 
560  if (shortterm < relative_threshold || shortterm <= -70. || s->above_threshold == 0) {
561  s->delta[s->index] = s->prev_delta;
562  } else {
563  env_global = fabs(shortterm - global) < (s->target_lra / 2.) ? shortterm - global : (s->target_lra / 2.) * ((shortterm - global) < 0 ? -1 : 1);
564  env_shortterm = s->target_i - shortterm;
565  s->delta[s->index] = pow(10., (env_global + env_shortterm) / 20.);
566  }
567 
568  s->prev_delta = s->delta[s->index];
569  s->index++;
570  if (s->index >= 30)
571  s->index -= 30;
572  s->prev_nb_samples = in->nb_samples;
573  break;
574 
575  case FINAL_FRAME:
576  gain = gaussian_filter(s, s->index + 10 < 30 ? s->index + 10 : s->index + 10 - 30);
577  s->limiter_buf_index = 0;
578  src_index = 0;
579 
580  for (n = 0; n < s->limiter_buf_size / inlink->ch_layout.nb_channels; n++) {
581  for (c = 0; c < inlink->ch_layout.nb_channels; c++) {
582  s->limiter_buf[s->limiter_buf_index + c] = src[src_index + c] * gain * s->offset;
583  }
584  src_index += inlink->ch_layout.nb_channels;
585 
586  s->limiter_buf_index += inlink->ch_layout.nb_channels;
587  if (s->limiter_buf_index >= s->limiter_buf_size)
588  s->limiter_buf_index -= s->limiter_buf_size;
589  }
590 
591  subframe_length = frame_size(inlink->sample_rate, 100);
592  for (i = 0; i < in->nb_samples / subframe_length; i++) {
593  true_peak_limiter(s, dst, subframe_length, inlink->ch_layout.nb_channels);
594 
595  for (n = 0; n < subframe_length; n++) {
596  for (c = 0; c < inlink->ch_layout.nb_channels; c++) {
597  if (src_index < (in->nb_samples * inlink->ch_layout.nb_channels)) {
598  limiter_buf[s->limiter_buf_index + c] = src[src_index + c] * gain * s->offset;
599  } else {
600  limiter_buf[s->limiter_buf_index + c] = 0.;
601  }
602  }
603 
604  if (src_index < (in->nb_samples * inlink->ch_layout.nb_channels))
605  src_index += inlink->ch_layout.nb_channels;
606 
607  s->limiter_buf_index += inlink->ch_layout.nb_channels;
608  if (s->limiter_buf_index >= s->limiter_buf_size)
609  s->limiter_buf_index -= s->limiter_buf_size;
610  }
611 
612  dst += (subframe_length * inlink->ch_layout.nb_channels);
613  }
614 
615  dst = (double *)out->data[0];
616  ff_ebur128_add_frames_double(s->r128_out, dst, in->nb_samples);
617  break;
618 
619  case LINEAR_MODE:
620  for (n = 0; n < in->nb_samples; n++) {
621  for (c = 0; c < inlink->ch_layout.nb_channels; c++) {
622  dst[c] = src[c] * s->offset;
623  }
624  src += inlink->ch_layout.nb_channels;
625  dst += inlink->ch_layout.nb_channels;
626  }
627 
628  dst = (double *)out->data[0];
629  ff_ebur128_add_frames_double(s->r128_out, dst, in->nb_samples);
630  break;
631  }
632 
633  if (in != out)
634  av_frame_free(&in);
635  return ff_filter_frame(outlink, out);
636 }
637 
638 static int flush_frame(AVFilterLink *outlink)
639 {
640  AVFilterContext *ctx = outlink->src;
641  AVFilterLink *inlink = ctx->inputs[0];
642  LoudNormContext *s = ctx->priv;
643  int ret = 0;
644 
645  if (s->frame_type == INNER_FRAME) {
646  double *src;
647  double *buf;
648  int nb_samples, n, c, offset;
649  AVFrame *frame;
650 
651  nb_samples = (s->buf_size / inlink->ch_layout.nb_channels) - s->prev_nb_samples;
652  nb_samples -= (frame_size(inlink->sample_rate, 100) - s->prev_nb_samples);
653 
654  frame = ff_get_audio_buffer(outlink, nb_samples);
655  if (!frame)
656  return AVERROR(ENOMEM);
657  frame->nb_samples = nb_samples;
658 
659  buf = s->buf;
660  src = (double *)frame->data[0];
661 
662  offset = ((s->limiter_buf_size / inlink->ch_layout.nb_channels) - s->prev_nb_samples) * inlink->ch_layout.nb_channels;
663  offset -= (frame_size(inlink->sample_rate, 100) - s->prev_nb_samples) * inlink->ch_layout.nb_channels;
664  s->buf_index = s->buf_index - offset < 0 ? s->buf_index - offset + s->buf_size : s->buf_index - offset;
665 
666  for (n = 0; n < nb_samples; n++) {
667  for (c = 0; c < inlink->ch_layout.nb_channels; c++) {
668  src[c] = buf[s->buf_index + c];
669  }
670  src += inlink->ch_layout.nb_channels;
671  s->buf_index += inlink->ch_layout.nb_channels;
672  if (s->buf_index >= s->buf_size)
673  s->buf_index -= s->buf_size;
674  }
675 
676  s->frame_type = FINAL_FRAME;
678  }
679  return ret;
680 }
681 
683 {
684  AVFilterLink *inlink = ctx->inputs[0];
685  AVFilterLink *outlink = ctx->outputs[0];
686  LoudNormContext *s = ctx->priv;
687  AVFrame *in = NULL;
688  int ret = 0, status;
689  int64_t pts;
690 
692 
693  if (s->frame_type != LINEAR_MODE) {
694  int nb_samples;
695 
696  if (s->frame_type == FIRST_FRAME) {
697  nb_samples = frame_size(inlink->sample_rate, 3000);
698  } else {
699  nb_samples = frame_size(inlink->sample_rate, 100);
700  }
701 
702  ret = ff_inlink_consume_samples(inlink, nb_samples, nb_samples, &in);
703  } else {
705  }
706 
707  if (ret < 0)
708  return ret;
709  if (ret > 0) {
710  if (s->frame_type == FIRST_FRAME) {
711  const int nb_samples = frame_size(inlink->sample_rate, 100);
712 
713  for (int i = 0; i < FF_ARRAY_ELEMS(s->pts); i++)
714  s->pts[i] = in->pts + i * nb_samples;
715  } else if (s->frame_type == LINEAR_MODE) {
716  s->pts[0] = in->pts;
717  } else {
718  s->pts[FF_ARRAY_ELEMS(s->pts) - 1] = in->pts;
719  }
720  ret = filter_frame(inlink, in);
721  }
722  if (ret < 0)
723  return ret;
724 
726  ff_outlink_set_status(outlink, status, pts);
727  return flush_frame(outlink);
728  }
729 
731 
732  return FFERROR_NOT_READY;
733 }
734 
736  AVFilterFormatsConfig **cfg_in,
737  AVFilterFormatsConfig **cfg_out)
738 {
739  LoudNormContext *s = ctx->priv;
740  static const int input_srate[] = {192000, -1};
741  static const enum AVSampleFormat sample_fmts[] = {
744  };
745  int ret;
746 
748  if (ret < 0)
749  return ret;
750 
751  if (s->frame_type != LINEAR_MODE) {
752  return ff_set_common_samplerates_from_list2(ctx, cfg_in, cfg_out, input_srate);
753  }
754  return 0;
755 }
756 
758 {
759  AVFilterContext *ctx = inlink->dst;
760  LoudNormContext *s = ctx->priv;
761 
762  s->r128_in = ff_ebur128_init(inlink->ch_layout.nb_channels, inlink->sample_rate, 0, FF_EBUR128_MODE_I | FF_EBUR128_MODE_S | FF_EBUR128_MODE_LRA | FF_EBUR128_MODE_SAMPLE_PEAK);
763  if (!s->r128_in)
764  return AVERROR(ENOMEM);
765 
766  s->r128_out = ff_ebur128_init(inlink->ch_layout.nb_channels, inlink->sample_rate, 0, FF_EBUR128_MODE_I | FF_EBUR128_MODE_S | FF_EBUR128_MODE_LRA | FF_EBUR128_MODE_SAMPLE_PEAK);
767  if (!s->r128_out)
768  return AVERROR(ENOMEM);
769 
770  if (inlink->ch_layout.nb_channels == 1 && s->dual_mono) {
773  }
774 
775  s->buf_size = frame_size(inlink->sample_rate, 3000) * inlink->ch_layout.nb_channels;
776  s->buf = av_malloc_array(s->buf_size, sizeof(*s->buf));
777  if (!s->buf)
778  return AVERROR(ENOMEM);
779 
780  s->limiter_buf_size = frame_size(inlink->sample_rate, 210) * inlink->ch_layout.nb_channels;
781  s->limiter_buf = av_malloc_array(s->limiter_buf_size, sizeof(*s->limiter_buf));
782  if (!s->limiter_buf)
783  return AVERROR(ENOMEM);
784 
785  s->prev_smp = av_malloc_array(inlink->ch_layout.nb_channels, sizeof(*s->prev_smp));
786  if (!s->prev_smp)
787  return AVERROR(ENOMEM);
788 
790 
791  s->buf_index =
792  s->prev_buf_index =
793  s->limiter_buf_index = 0;
794  s->channels = inlink->ch_layout.nb_channels;
795  s->index = 1;
796  s->limiter_state = OUT;
797  s->offset = pow(10., s->offset / 20.);
798  s->target_tp = pow(10., s->target_tp / 20.);
799  s->attack_length = frame_size(inlink->sample_rate, 10);
800  s->release_length = frame_size(inlink->sample_rate, 100);
801 
802  return 0;
803 }
804 
806 {
807  LoudNormContext *s = ctx->priv;
808  s->frame_type = FIRST_FRAME;
809 
810  if (s->stats_file_str && s->print_format == NONE) {
811  av_log(ctx, AV_LOG_ERROR, "stats_file requested but print_format not specified\n");
812  return AVERROR(EINVAL);
813  }
814 
815  if (s->linear) {
816  double offset, offset_tp;
817  offset = s->target_i - s->measured_i;
818  offset_tp = s->measured_tp + offset;
819 
820  if (s->measured_tp != 99 && s->measured_thresh != -70 && s->measured_lra != 0 && s->measured_i != 0) {
821  if ((offset_tp <= s->target_tp) && (s->measured_lra <= s->target_lra)) {
822  s->frame_type = LINEAR_MODE;
823  s->offset = offset;
824  }
825  }
826  }
827 
828  return 0;
829 }
830 
832 {
833  LoudNormContext *s = ctx->priv;
834  double i_in, i_out, lra_in, lra_out, thresh_in, thresh_out, tp_in, tp_out;
835  int c;
836  FILE *stats_file = NULL;
837 
838  if (!s->r128_in || !s->r128_out)
839  goto end;
840 
841  ff_ebur128_loudness_range(s->r128_in, &lra_in);
842  ff_ebur128_loudness_global(s->r128_in, &i_in);
843  ff_ebur128_relative_threshold(s->r128_in, &thresh_in);
844  for (c = 0; c < s->channels; c++) {
845  double tmp;
846  ff_ebur128_sample_peak(s->r128_in, c, &tmp);
847  if ((c == 0) || (tmp > tp_in))
848  tp_in = tmp;
849  }
850 
851  ff_ebur128_loudness_range(s->r128_out, &lra_out);
852  ff_ebur128_loudness_global(s->r128_out, &i_out);
853  ff_ebur128_relative_threshold(s->r128_out, &thresh_out);
854  for (c = 0; c < s->channels; c++) {
855  double tmp;
856  ff_ebur128_sample_peak(s->r128_out, c, &tmp);
857  if ((c == 0) || (tmp > tp_out))
858  tp_out = tmp;
859  }
860 
861 
862  if (s->stats_file_str) {
863  if (!strcmp(s->stats_file_str, "-")) {
864  stats_file = stdout;
865  } else {
866  stats_file = avpriv_fopen_utf8(s->stats_file_str, "w");
867  if (!stats_file) {
868  int err = AVERROR(errno);
869  av_log(ctx, AV_LOG_ERROR, "Could not open stats file %s: %s\n",
870  s->stats_file_str, av_err2str(err));
871  goto end;
872  }
873  }
874  }
875 
876  switch(s->print_format) {
877  case NONE:
878  break;
879 
880  case JSON:
881  case SUMMARY: {
882  char stats[1024];
883  const char *const format = s->print_format == JSON ?
884  "{\n"
885  "\t\"input_i\" : \"%.2f\",\n"
886  "\t\"input_tp\" : \"%.2f\",\n"
887  "\t\"input_lra\" : \"%.2f\",\n"
888  "\t\"input_thresh\" : \"%.2f\",\n"
889  "\t\"output_i\" : \"%.2f\",\n"
890  "\t\"output_tp\" : \"%+.2f\",\n"
891  "\t\"output_lra\" : \"%.2f\",\n"
892  "\t\"output_thresh\" : \"%.2f\",\n"
893  "\t\"normalization_type\" : \"%s\",\n"
894  "\t\"target_offset\" : \"%.2f\"\n"
895  "}\n" :
896  "Input Integrated: %+6.1f LUFS\n"
897  "Input True Peak: %+6.1f dBTP\n"
898  "Input LRA: %6.1f LU\n"
899  "Input Threshold: %+6.1f LUFS\n"
900  "\n"
901  "Output Integrated: %+6.1f LUFS\n"
902  "Output True Peak: %+6.1f dBTP\n"
903  "Output LRA: %6.1f LU\n"
904  "Output Threshold: %+6.1f LUFS\n"
905  "\n"
906  "Normalization Type: %s\n"
907  "Target Offset: %+6.1f LU\n";
908 
909  snprintf(stats, sizeof(stats), format,
910  i_in,
911  20. * log10(tp_in),
912  lra_in,
913  thresh_in,
914  i_out,
915  20. * log10(tp_out),
916  lra_out,
917  thresh_out,
918  s->frame_type == LINEAR_MODE ? (s->print_format == JSON ? "linear" : "Linear")
919  : (s->print_format == JSON ? "dynamic" : "Dynamic"),
920  s->target_i - i_out
921  );
922  av_log(ctx, AV_LOG_INFO, "\n%s", stats);
923  if (stats_file)
924  fprintf(stats_file, "%s", stats);
925  break;
926  }
927  }
928 
929 end:
930  if (stats_file && stats_file != stdout)
931  fclose(stats_file);
932  if (s->r128_in)
933  ff_ebur128_destroy(&s->r128_in);
934  if (s->r128_out)
935  ff_ebur128_destroy(&s->r128_out);
936  av_freep(&s->limiter_buf);
937  av_freep(&s->prev_smp);
938  av_freep(&s->buf);
939 }
940 
942  {
943  .name = "default",
944  .type = AVMEDIA_TYPE_AUDIO,
945  .config_props = config_input,
946  },
947 };
948 
950  .p.name = "loudnorm",
951  .p.description = NULL_IF_CONFIG_SMALL("EBU R128 loudness normalization"),
952  .p.priv_class = &loudnorm_class,
953  .priv_size = sizeof(LoudNormContext),
954  .init = init,
955  .activate = activate,
956  .uninit = uninit,
960 };
init
static av_cold int init(AVFilterContext *ctx)
Definition: af_loudnorm.c:805
STATE_NB
@ STATE_NB
Definition: af_loudnorm.c:45
LoudNormContext::pts
int64_t pts[30]
Definition: af_loudnorm.c:93
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:98
LoudNormContext::weights
double weights[21]
Definition: af_loudnorm.c:77
SUSTAIN
@ SUSTAIN
Definition: af_loudnorm.c:43
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
NONE
@ NONE
Definition: af_loudnorm.c:49
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_loudnorm.c:831
out
static FILE * out
Definition: movenc.c:55
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1067
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:931
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
frame_size
static int frame_size(int sample_rate, int frame_len_msec)
Definition: af_loudnorm.c:133
int64_t
long long int64_t
Definition: coverity.c:34
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:64
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:264
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:529
LoudNormContext::peak_index
int peak_index
Definition: af_loudnorm.c:87
AVOption
AVOption.
Definition: opt.h:429
LoudNormContext::prev_smp
double * prev_smp
Definition: af_loudnorm.c:83
linear
static int linear(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:135
FF_EBUR128_MODE_I
@ FF_EBUR128_MODE_I
can call ff_ebur128_loudness_global_* and ff_ebur128_relative_threshold
Definition: ebur128.h:89
LoudNormContext::r128_in
FFEBUR128State * r128_in
Definition: af_loudnorm.c:99
max
#define max(a, b)
Definition: cuda_runtime.h:33
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:220
c1
static const uint64_t c1
Definition: murmur3.c:52
FF_FILTER_FORWARD_STATUS_BACK
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:639
LoudNormContext::prev_nb_samples
int prev_nb_samples
Definition: af_loudnorm.c:96
ff_ebur128_loudness_range
int ff_ebur128_loudness_range(FFEBUR128State *st, double *out)
Get loudness range (LRA) of programme in LU.
Definition: ebur128.c:709
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:448
JSON
@ JSON
Definition: af_loudnorm.c:50
formats.h
LoudNormContext::target_tp
double target_tp
Definition: af_loudnorm.c:59
ff_inlink_consume_frame
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1515
INNER_FRAME
@ INNER_FRAME
Definition: af_loudnorm.c:34
LoudNormContext::above_threshold
int above_threshold
Definition: af_loudnorm.c:95
ff_ebur128_destroy
void ff_ebur128_destroy(FFEBUR128State **st)
Destroy library state.
Definition: ebur128.c:304
ATTACK
@ ATTACK
Definition: af_loudnorm.c:42
pts
static int64_t pts
Definition: transcode_aac.c:644
LoudNormContext::env_index
int env_index
Definition: af_loudnorm.c:88
RELEASE
@ RELEASE
Definition: af_loudnorm.c:44
true_peak_limiter
static void true_peak_limiter(LoudNormContext *s, double *out, int nb_samples, int channels)
Definition: af_loudnorm.c:236
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:40
FF_EBUR128_DUAL_MONO
@ FF_EBUR128_DUAL_MONO
a channel that is counted twice
Definition: ebur128.h:51
flush_frame
static int flush_frame(AVFilterLink *outlink)
Definition: af_loudnorm.c:638
FLAGS
#define FLAGS
Definition: af_loudnorm.c:104
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_loudnorm.c:415
av_cold
#define av_cold
Definition: attributes.h:106
LoudNormContext::index
int index
Definition: af_loudnorm.c:79
FFFilter
Definition: filters.h:267
ff_outlink_set_status
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:629
FF_EBUR128_MODE_LRA
@ FF_EBUR128_MODE_LRA
can call ff_ebur128_loudness_range
Definition: ebur128.h:91
SUMMARY
@ SUMMARY
Definition: af_loudnorm.c:51
s
#define s(width, name)
Definition: cbs_vp9.c:198
ff_ebur128_add_frames_double
void ff_ebur128_add_frames_double(FFEBUR128State *st, const double *src, size_t frames)
Add frames to be processed.
adjust
static int adjust(int x, int size)
Definition: mobiclip.c:514
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
Definition: opt.h:267
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
LoudNormContext::measured_tp
double measured_tp
Definition: af_loudnorm.c:62
filters.h
ff_set_common_samplerates_from_list2
int ff_set_common_samplerates_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *samplerates)
Definition: formats.c:1049
LoudNormContext::limiter_state
enum LimiterState limiter_state
Definition: af_loudnorm.c:86
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
channels
channels
Definition: aptx.h:31
LoudNormContext::env_cnt
int env_cnt
Definition: af_loudnorm.c:89
LoudNormContext::prev_delta
double prev_delta
Definition: af_loudnorm.c:78
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:265
file_open.h
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
FrameType
FrameType
G723.1 frame types.
Definition: g723_1.h:63
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
ff_inlink_consume_samples
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
Definition: avfilter.c:1535
NULL
#define NULL
Definition: coverity.c:32
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:599
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
FRAME_NB
@ FRAME_NB
Definition: af_loudnorm.c:37
LoudNormContext::measured_lra
double measured_lra
Definition: af_loudnorm.c:61
LoudNormContext::delta
double delta[30]
Definition: af_loudnorm.c:76
ff_ebur128_sample_peak
int ff_ebur128_sample_peak(FFEBUR128State *st, unsigned int channel_number, double *out)
Get maximum sample peak of selected channel in float format.
Definition: ebur128.c:714
loudnorm_options
static const AVOption loudnorm_options[]
Definition: af_loudnorm.c:106
ff_audio_default_filterpad
const AVFilterPad ff_audio_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_AUDIO.
Definition: audio.c:34
double
double
Definition: af_crystalizer.c:132
LoudNormContext::buf_index
int buf_index
Definition: af_loudnorm.c:73
LoudNormContext::attack_length
int attack_length
Definition: af_loudnorm.c:90
activate
static int activate(AVFilterContext *ctx)
Definition: af_loudnorm.c:682
LoudNormContext::limiter_buf_index
int limiter_buf_index
Definition: af_loudnorm.c:84
exp
int8_t exp
Definition: eval.c:73
ff_inlink_acknowledge_status
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:1462
stats
static void stats(AVPacket *const *in, int n_in, unsigned *_max, unsigned *_sum)
Definition: vp9_superframe.c:34
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:121
LoudNormContext::limiter_buf
double * limiter_buf
Definition: af_loudnorm.c:82
LoudNormContext::release_length
int release_length
Definition: af_loudnorm.c:91
LoudNormContext::measured_i
double measured_i
Definition: af_loudnorm.c:60
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(loudnorm)
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:94
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
ff_ebur128_loudness_shortterm
int ff_ebur128_loudness_shortterm(FFEBUR128State *st, double *out)
Get short-term loudness (last 3s) in LUFS.
Definition: ebur128.c:617
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
init_gaussian_filter
static void init_gaussian_filter(LoudNormContext *s)
Definition: af_loudnorm.c:139
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:535
PrintFormat
PrintFormat
Definition: af_loudnorm.c:48
FF_EBUR128_MODE_S
@ FF_EBUR128_MODE_S
can call ff_ebur128_loudness_shortterm
Definition: ebur128.h:87
ff_ebur128_init
FFEBUR128State * ff_ebur128_init(unsigned int channels, unsigned long samplerate, unsigned long window, int mode)
Initialize library state.
Definition: ebur128.c:219
LoudNormContext::prev_buf_index
int prev_buf_index
Definition: af_loudnorm.c:74
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
FF_FILTER_FORWARD_WANTED
FF_FILTER_FORWARD_WANTED(outlink, inlink)
OUT
@ OUT
Definition: af_loudnorm.c:41
LoudNormContext::target_i
double target_i
Definition: af_loudnorm.c:57
LoudNormContext
Definition: af_loudnorm.c:55
M_PI
#define M_PI
Definition: mathematics.h:67
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
LoudNormContext::frame_type
enum FrameType frame_type
Definition: af_loudnorm.c:94
LimiterState
LimiterState
Definition: af_loudnorm.c:40
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:507
LoudNormContext::measured_thresh
double measured_thresh
Definition: af_loudnorm.c:63
LoudNormContext::buf
double * buf
Definition: af_loudnorm.c:71
LoudNormContext::offset
double offset
Definition: af_loudnorm.c:64
LoudNormContext::limiter_buf_size
int limiter_buf_size
Definition: af_loudnorm.c:85
ff_ebur128_set_channel
int ff_ebur128_set_channel(FFEBUR128State *st, unsigned int channel_number, int value)
Set channel type.
Definition: ebur128.c:445
round
static av_always_inline av_const double round(double x)
Definition: libm.h:446
ff_af_loudnorm
const FFFilter ff_af_loudnorm
Definition: af_loudnorm.c:949
ebur128.h
libebur128 - a library for loudness measurement according to the EBU R128 standard.
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
LoudNormContext::print_format
int print_format
Definition: af_loudnorm.c:68
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
FILTER_QUERY_FUNC2
#define FILTER_QUERY_FUNC2(func)
Definition: filters.h:241
FFEBUR128State
Contains information about the state of a loudness measurement.
Definition: ebur128.h:103
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:46
avfilter_af_loudnorm_inputs
static const AVFilterPad avfilter_af_loudnorm_inputs[]
Definition: af_loudnorm.c:941
avpriv_fopen_utf8
FILE * avpriv_fopen_utf8(const char *path, const char *mode)
Open a file using a UTF-8 filename.
Definition: file_open.c:160
LoudNormContext::stats_file_str
char * stats_file_str
Definition: af_loudnorm.c:69
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:265
LoudNormContext::channels
int channels
Definition: af_loudnorm.c:97
ff_set_sample_formats_from_list2
int ff_set_sample_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const enum AVSampleFormat *fmts)
Definition: formats.c:1153
FINAL_FRAME
@ FINAL_FRAME
Definition: af_loudnorm.c:35
LoudNormContext::buf_size
int buf_size
Definition: af_loudnorm.c:72
c2
static const uint64_t c2
Definition: murmur3.c:53
status
ov_status_e status
Definition: dnn_backend_openvino.c:100
config_input
static int config_input(AVFilterLink *inlink)
Definition: af_loudnorm.c:757
LoudNormContext::gain_reduction
double gain_reduction[2]
Definition: af_loudnorm.c:81
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
PF_NB
@ PF_NB
Definition: af_loudnorm.c:52
AVFilterContext
An instance of a filter.
Definition: avfilter.h:274
LoudNormContext::linear
int linear
Definition: af_loudnorm.c:65
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:271
mem.h
audio.h
LINEAR_MODE
@ LINEAR_MODE
Definition: af_loudnorm.c:36
LoudNormContext::dual_mono
int dual_mono
Definition: af_loudnorm.c:66
OFFSET
#define OFFSET(x)
Definition: af_loudnorm.c:103
ff_ebur128_relative_threshold
int ff_ebur128_relative_threshold(FFEBUR128State *st, double *out)
Get relative threshold in LUFS.
Definition: ebur128.c:580
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
FF_EBUR128_MODE_SAMPLE_PEAK
@ FF_EBUR128_MODE_SAMPLE_PEAK
can call ff_ebur128_sample_peak
Definition: ebur128.h:93
detect_peak
static void detect_peak(LoudNormContext *s, int offset, int nb_samples, int channels, int *peak_delta, double *peak_value)
Definition: af_loudnorm.c:173
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
gaussian_filter
static double gaussian_filter(LoudNormContext *s, int index)
Definition: af_loudnorm.c:161
LoudNormContext::r128_out
FFEBUR128State * r128_out
Definition: af_loudnorm.c:100
AV_SAMPLE_FMT_DBL
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:61
FIRST_FRAME
@ FIRST_FRAME
Definition: af_loudnorm.c:33
ff_ebur128_loudness_global
int ff_ebur128_loudness_global(FFEBUR128State *st, double *out)
Get global integrated loudness in LUFS.
Definition: ebur128.c:596
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
query_formats
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: af_loudnorm.c:735
snprintf
#define snprintf
Definition: snprintf.h:34
LoudNormContext::target_lra
double target_lra
Definition: af_loudnorm.c:58
src
#define src
Definition: vp8dsp.c:248