FFmpeg
f_ebur128.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Clément Bœsch
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 /**
22  * @file
23  * EBU R.128 implementation
24  * @see http://tech.ebu.ch/loudness
25  * @see https://www.youtube.com/watch?v=iuEtQqC-Sqo "EBU R128 Introduction - Florian Camerer"
26  * @todo implement start/stop/reset through filter command injection
27  */
28 
29 #include <float.h>
30 #include <math.h>
31 
32 #include "libavutil/avassert.h"
34 #include "libavutil/dict.h"
35 #include "libavutil/ffmath.h"
36 #include "libavutil/mem.h"
38 #include "libavutil/opt.h"
39 #include "libavutil/timestamp.h"
41 #include "avfilter.h"
42 #include "filters.h"
43 #include "formats.h"
44 #include "internal.h"
45 #include "video.h"
46 
47 #define ABS_THRES -70 ///< silence gate: we discard anything below this absolute (LUFS) threshold
48 #define ABS_UP_THRES 10 ///< upper loud limit to consider (ABS_THRES being the minimum)
49 #define HIST_GRAIN 100 ///< defines histogram precision
50 #define HIST_SIZE ((ABS_UP_THRES - ABS_THRES) * HIST_GRAIN + 1)
51 
52 /**
53  * A histogram is an array of HIST_SIZE hist_entry storing all the energies
54  * recorded (with an accuracy of 1/HIST_GRAIN) of the loudnesses from ABS_THRES
55  * (at 0) to ABS_UP_THRES (at HIST_SIZE-1).
56  * This fixed-size system avoids the need of a list of energies growing
57  * infinitely over the time and is thus more scalable.
58  */
59 struct hist_entry {
60  unsigned count; ///< how many times the corresponding value occurred
61  double energy; ///< E = 10^((L + 0.691) / 10)
62  double loudness; ///< L = -0.691 + 10 * log10(E)
63 };
64 
65 struct integrator {
66  double **cache; ///< window of filtered samples (N ms)
67  int cache_pos; ///< focus on the last added bin in the cache array
69  double *sum; ///< sum of the last N ms filtered samples (cache content)
70  int filled; ///< 1 if the cache is completely filled, 0 otherwise
71  double rel_threshold; ///< relative threshold
72  double sum_kept_powers; ///< sum of the powers (weighted sums) above absolute threshold
73  int nb_kept_powers; ///< number of sum above absolute threshold
74  struct hist_entry *histogram; ///< histogram of the powers, used to compute LRA and I
75 };
76 
77 struct rect { int x, y, w, h; };
78 
79 typedef struct EBUR128Context {
80  const AVClass *class; ///< AVClass context for log and options purpose
81 
82  /* peak metering */
83  int peak_mode; ///< enabled peak modes
84  double true_peak; ///< global true peak
85  double *true_peaks; ///< true peaks per channel
86  double sample_peak; ///< global sample peak
87  double *sample_peaks; ///< sample peaks per channel
88  double *true_peaks_per_frame; ///< true peaks in a frame per channel
89 #if CONFIG_SWRESAMPLE
90  SwrContext *swr_ctx; ///< over-sampling context for true peak metering
91  double *swr_buf; ///< resampled audio data for true peak metering
92  int swr_linesize;
93 #endif
94 
95  /* video */
96  int do_video; ///< 1 if video output enabled, 0 otherwise
97  int w, h; ///< size of the video output
98  struct rect text; ///< rectangle for the LU legend on the left
99  struct rect graph; ///< rectangle for the main graph in the center
100  struct rect gauge; ///< rectangle for the gauge on the right
101  AVFrame *outpicref; ///< output picture reference, updated regularly
102  int meter; ///< select a EBU mode between +9 and +18
103  int scale_range; ///< the range of LU values according to the meter
104  int y_zero_lu; ///< the y value (pixel position) for 0 LU
105  int y_opt_max; ///< the y value (pixel position) for 1 LU
106  int y_opt_min; ///< the y value (pixel position) for -1 LU
107  int *y_line_ref; ///< y reference values for drawing the LU lines in the graph and the gauge
108 
109  /* audio */
110  int nb_channels; ///< number of channels in the input
111  double *ch_weighting; ///< channel weighting mapping
112  int sample_count; ///< sample count used for refresh frequency, reset at refresh
113  int nb_samples; ///< number of samples to consume per single input frame
114  int idx_insample; ///< current sample position of processed samples in single input frame
115  AVFrame *insamples; ///< input samples reference, updated regularly
116 
117  /* Filter caches.
118  * The mult by 3 in the following is for X[i], X[i-1] and X[i-2] */
119  double *x; ///< 3 input samples cache for each channel
120  double *y; ///< 3 pre-filter samples cache for each channel
121  double *z; ///< 3 RLB-filter samples cache for each channel
122  double pre_b[3]; ///< pre-filter numerator coefficients
123  double pre_a[3]; ///< pre-filter denominator coefficients
124  double rlb_b[3]; ///< rlb-filter numerator coefficients
125  double rlb_a[3]; ///< rlb-filter denominator coefficients
126 
127  struct integrator i400; ///< 400ms integrator, used for Momentary loudness (M), and Integrated loudness (I)
128  struct integrator i3000; ///< 3s integrator, used for Short term loudness (S), and Loudness Range (LRA)
129 
130  /* I and LRA specific */
131  double integrated_loudness; ///< integrated loudness in LUFS (I)
132  double loudness_range; ///< loudness range in LU (LRA)
133  double lra_low, lra_high; ///< low and high LRA values
134 
135  /* misc */
136  int loglevel; ///< log level for frame logging
137  int metadata; ///< whether or not to inject loudness results in frames
138  int dual_mono; ///< whether or not to treat single channel input files as dual-mono
139  double pan_law; ///< pan law value used to calculate dual-mono measurements
140  int target; ///< target level in LUFS used to set relative zero LU in visualization
141  int gauge_type; ///< whether gauge shows momentary or short
142  int scale; ///< display scale type of statistics
144 
145 enum {
149 };
150 
151 enum {
154 };
155 
156 enum {
159 };
160 
161 #define OFFSET(x) offsetof(EBUR128Context, x)
162 #define A AV_OPT_FLAG_AUDIO_PARAM
163 #define V AV_OPT_FLAG_VIDEO_PARAM
164 #define F AV_OPT_FLAG_FILTERING_PARAM
165 #define X AV_OPT_FLAG_EXPORT
166 #define R AV_OPT_FLAG_READONLY
167 static const AVOption ebur128_options[] = {
168  { "video", "set video output", OFFSET(do_video), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, V|F },
169  { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x480"}, 0, 0, V|F },
170  { "meter", "set scale meter (+9 to +18)", OFFSET(meter), AV_OPT_TYPE_INT, {.i64 = 9}, 9, 18, V|F },
171  { "framelog", "force frame logging level", OFFSET(loglevel), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, A|V|F, .unit = "level" },
172  { "quiet", "logging disabled", 0, AV_OPT_TYPE_CONST, {.i64 = AV_LOG_QUIET}, INT_MIN, INT_MAX, A|V|F, .unit = "level" },
173  { "info", "information logging level", 0, AV_OPT_TYPE_CONST, {.i64 = AV_LOG_INFO}, INT_MIN, INT_MAX, A|V|F, .unit = "level" },
174  { "verbose", "verbose logging level", 0, AV_OPT_TYPE_CONST, {.i64 = AV_LOG_VERBOSE}, INT_MIN, INT_MAX, A|V|F, .unit = "level" },
175  { "metadata", "inject metadata in the filtergraph", OFFSET(metadata), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, A|V|F },
176  { "peak", "set peak mode", OFFSET(peak_mode), AV_OPT_TYPE_FLAGS, {.i64 = PEAK_MODE_NONE}, 0, INT_MAX, A|F, .unit = "mode" },
177  { "none", "disable any peak mode", 0, AV_OPT_TYPE_CONST, {.i64 = PEAK_MODE_NONE}, INT_MIN, INT_MAX, A|F, .unit = "mode" },
178  { "sample", "enable peak-sample mode", 0, AV_OPT_TYPE_CONST, {.i64 = PEAK_MODE_SAMPLES_PEAKS}, INT_MIN, INT_MAX, A|F, .unit = "mode" },
179  { "true", "enable true-peak mode", 0, AV_OPT_TYPE_CONST, {.i64 = PEAK_MODE_TRUE_PEAKS}, INT_MIN, INT_MAX, A|F, .unit = "mode" },
180  { "dualmono", "treat mono input files as dual-mono", OFFSET(dual_mono), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, A|F },
181  { "panlaw", "set a specific pan law for dual-mono files", OFFSET(pan_law), AV_OPT_TYPE_DOUBLE, {.dbl = -3.01029995663978}, -10.0, 0.0, A|F },
182  { "target", "set a specific target level in LUFS (-23 to 0)", OFFSET(target), AV_OPT_TYPE_INT, {.i64 = -23}, -23, 0, V|F },
183  { "gauge", "set gauge display type", OFFSET(gauge_type), AV_OPT_TYPE_INT, {.i64 = 0 }, GAUGE_TYPE_MOMENTARY, GAUGE_TYPE_SHORTTERM, V|F, .unit = "gaugetype" },
184  { "momentary", "display momentary value", 0, AV_OPT_TYPE_CONST, {.i64 = GAUGE_TYPE_MOMENTARY}, INT_MIN, INT_MAX, V|F, .unit = "gaugetype" },
185  { "m", "display momentary value", 0, AV_OPT_TYPE_CONST, {.i64 = GAUGE_TYPE_MOMENTARY}, INT_MIN, INT_MAX, V|F, .unit = "gaugetype" },
186  { "shortterm", "display short-term value", 0, AV_OPT_TYPE_CONST, {.i64 = GAUGE_TYPE_SHORTTERM}, INT_MIN, INT_MAX, V|F, .unit = "gaugetype" },
187  { "s", "display short-term value", 0, AV_OPT_TYPE_CONST, {.i64 = GAUGE_TYPE_SHORTTERM}, INT_MIN, INT_MAX, V|F, .unit = "gaugetype" },
188  { "scale", "sets display method for the stats", OFFSET(scale), AV_OPT_TYPE_INT, {.i64 = 0}, SCALE_TYPE_ABSOLUTE, SCALE_TYPE_RELATIVE, V|F, .unit = "scaletype" },
189  { "absolute", "display absolute values (LUFS)", 0, AV_OPT_TYPE_CONST, {.i64 = SCALE_TYPE_ABSOLUTE}, INT_MIN, INT_MAX, V|F, .unit = "scaletype" },
190  { "LUFS", "display absolute values (LUFS)", 0, AV_OPT_TYPE_CONST, {.i64 = SCALE_TYPE_ABSOLUTE}, INT_MIN, INT_MAX, V|F, .unit = "scaletype" },
191  { "relative", "display values relative to target (LU)", 0, AV_OPT_TYPE_CONST, {.i64 = SCALE_TYPE_RELATIVE}, INT_MIN, INT_MAX, V|F, .unit = "scaletype" },
192  { "LU", "display values relative to target (LU)", 0, AV_OPT_TYPE_CONST, {.i64 = SCALE_TYPE_RELATIVE}, INT_MIN, INT_MAX, V|F, .unit = "scaletype" },
193  { "integrated", "integrated loudness (LUFS)", OFFSET(integrated_loudness), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, -DBL_MAX, DBL_MAX, A|F|X|R },
194  { "range", "loudness range (LU)", OFFSET(loudness_range), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, -DBL_MAX, DBL_MAX, A|F|X|R },
195  { "lra_low", "LRA low (LUFS)", OFFSET(lra_low), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, -DBL_MAX, DBL_MAX, A|F|X|R },
196  { "lra_high", "LRA high (LUFS)", OFFSET(lra_high), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, -DBL_MAX, DBL_MAX, A|F|X|R },
197  { "sample_peak", "sample peak (dBFS)", OFFSET(sample_peak), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, -DBL_MAX, DBL_MAX, A|F|X|R },
198  { "true_peak", "true peak (dBFS)", OFFSET(true_peak), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, -DBL_MAX, DBL_MAX, A|F|X|R },
199  { NULL },
200 };
201 
202 AVFILTER_DEFINE_CLASS(ebur128);
203 
204 static const uint8_t graph_colors[] = {
205  0xdd, 0x66, 0x66, // value above 1LU non reached below -1LU (impossible)
206  0x66, 0x66, 0xdd, // value below 1LU non reached below -1LU
207  0x96, 0x33, 0x33, // value above 1LU reached below -1LU (impossible)
208  0x33, 0x33, 0x96, // value below 1LU reached below -1LU
209  0xdd, 0x96, 0x96, // value above 1LU line non reached below -1LU (impossible)
210  0x96, 0x96, 0xdd, // value below 1LU line non reached below -1LU
211  0xdd, 0x33, 0x33, // value above 1LU line reached below -1LU (impossible)
212  0x33, 0x33, 0xdd, // value below 1LU line reached below -1LU
213  0xdd, 0x66, 0x66, // value above 1LU non reached above -1LU
214  0x66, 0xdd, 0x66, // value below 1LU non reached above -1LU
215  0x96, 0x33, 0x33, // value above 1LU reached above -1LU
216  0x33, 0x96, 0x33, // value below 1LU reached above -1LU
217  0xdd, 0x96, 0x96, // value above 1LU line non reached above -1LU
218  0x96, 0xdd, 0x96, // value below 1LU line non reached above -1LU
219  0xdd, 0x33, 0x33, // value above 1LU line reached above -1LU
220  0x33, 0xdd, 0x33, // value below 1LU line reached above -1LU
221 };
222 
223 static const uint8_t *get_graph_color(const EBUR128Context *ebur128, int v, int y)
224 {
225  const int above_opt_max = y > ebur128->y_opt_max;
226  const int below_opt_min = y < ebur128->y_opt_min;
227  const int reached = y >= v;
228  const int line = ebur128->y_line_ref[y] || y == ebur128->y_zero_lu;
229  const int colorid = 8*below_opt_min+ 4*line + 2*reached + above_opt_max;
230  return graph_colors + 3*colorid;
231 }
232 
233 static inline int lu_to_y(const EBUR128Context *ebur128, double v)
234 {
235  v += 2 * ebur128->meter; // make it in range [0;...]
236  v = av_clipf(v, 0, ebur128->scale_range); // make sure it's in the graph scale
237  v = ebur128->scale_range - v; // invert value (y=0 is on top)
238  return v * ebur128->graph.h / ebur128->scale_range; // rescale from scale range to px height
239 }
240 
241 #define FONT8 0
242 #define FONT16 1
243 
244 static const uint8_t font_colors[] = {
245  0xdd, 0xdd, 0x00,
246  0x00, 0x96, 0x96,
247 };
248 
249 static void drawtext(AVFrame *pic, int x, int y, int ftid, const uint8_t *color, const char *fmt, ...)
250 {
251  int i;
252  char buf[128] = {0};
253  const uint8_t *font;
254  int font_height;
255  va_list vl;
256 
257  if (ftid == FONT16) font = avpriv_vga16_font, font_height = 16;
258  else if (ftid == FONT8) font = avpriv_cga_font, font_height = 8;
259  else return;
260 
261  va_start(vl, fmt);
262  vsnprintf(buf, sizeof(buf), fmt, vl);
263  va_end(vl);
264 
265  for (i = 0; buf[i]; i++) {
266  int char_y, mask;
267  uint8_t *p = pic->data[0] + y*pic->linesize[0] + (x + i*8)*3;
268 
269  for (char_y = 0; char_y < font_height; char_y++) {
270  for (mask = 0x80; mask; mask >>= 1) {
271  if (font[buf[i] * font_height + char_y] & mask)
272  memcpy(p, color, 3);
273  else
274  memcpy(p, "\x00\x00\x00", 3);
275  p += 3;
276  }
277  p += pic->linesize[0] - 8*3;
278  }
279  }
280 }
281 
282 static void drawline(AVFrame *pic, int x, int y, int len, int step)
283 {
284  int i;
285  uint8_t *p = pic->data[0] + y*pic->linesize[0] + x*3;
286 
287  for (i = 0; i < len; i++) {
288  memcpy(p, "\x00\xff\x00", 3);
289  p += step;
290  }
291 }
292 
293 static int config_video_output(AVFilterLink *outlink)
294 {
295  int i, x, y;
296  uint8_t *p;
297  AVFilterContext *ctx = outlink->src;
298  EBUR128Context *ebur128 = ctx->priv;
299  AVFrame *outpicref;
300 
301  /* check if there is enough space to represent everything decently */
302  if (ebur128->w < 640 || ebur128->h < 480) {
303  av_log(ctx, AV_LOG_ERROR, "Video size %dx%d is too small, "
304  "minimum size is 640x480\n", ebur128->w, ebur128->h);
305  return AVERROR(EINVAL);
306  }
307  outlink->w = ebur128->w;
308  outlink->h = ebur128->h;
309  outlink->sample_aspect_ratio = (AVRational){1,1};
310  outlink->frame_rate = av_make_q(10, 1);
311  outlink->time_base = av_inv_q(outlink->frame_rate);
312 
313 #define PAD 8
314 
315  /* configure text area position and size */
316  ebur128->text.x = PAD;
317  ebur128->text.y = 40;
318  ebur128->text.w = 3 * 8; // 3 characters
319  ebur128->text.h = ebur128->h - PAD - ebur128->text.y;
320 
321  /* configure gauge position and size */
322  ebur128->gauge.w = 20;
323  ebur128->gauge.h = ebur128->text.h;
324  ebur128->gauge.x = ebur128->w - PAD - ebur128->gauge.w;
325  ebur128->gauge.y = ebur128->text.y;
326 
327  /* configure graph position and size */
328  ebur128->graph.x = ebur128->text.x + ebur128->text.w + PAD;
329  ebur128->graph.y = ebur128->gauge.y;
330  ebur128->graph.w = ebur128->gauge.x - ebur128->graph.x - PAD;
331  ebur128->graph.h = ebur128->gauge.h;
332 
333  /* graph and gauge share the LU-to-pixel code */
334  av_assert0(ebur128->graph.h == ebur128->gauge.h);
335 
336  /* prepare the initial picref buffer */
337  av_frame_free(&ebur128->outpicref);
338  ebur128->outpicref = outpicref =
339  ff_get_video_buffer(outlink, outlink->w, outlink->h);
340  if (!outpicref)
341  return AVERROR(ENOMEM);
342  outpicref->sample_aspect_ratio = (AVRational){1,1};
343 
344  /* init y references values (to draw LU lines) */
345  ebur128->y_line_ref = av_calloc(ebur128->graph.h + 1, sizeof(*ebur128->y_line_ref));
346  if (!ebur128->y_line_ref)
347  return AVERROR(ENOMEM);
348 
349  /* black background */
350  for (int y = 0; y < ebur128->h; y++)
351  memset(outpicref->data[0] + y * outpicref->linesize[0], 0, ebur128->w * 3);
352 
353  /* draw LU legends */
354  drawtext(outpicref, PAD, PAD+16, FONT8, font_colors+3, " LU");
355  for (i = ebur128->meter; i >= -ebur128->meter * 2; i--) {
356  y = lu_to_y(ebur128, i);
357  x = PAD + (i < 10 && i > -10) * 8;
358  ebur128->y_line_ref[y] = i;
359  y -= 4; // -4 to center vertically
360  drawtext(outpicref, x, y + ebur128->graph.y, FONT8, font_colors+3,
361  "%c%d", i < 0 ? '-' : i > 0 ? '+' : ' ', FFABS(i));
362  }
363 
364  /* draw graph */
365  ebur128->y_zero_lu = lu_to_y(ebur128, 0);
366  ebur128->y_opt_max = lu_to_y(ebur128, 1);
367  ebur128->y_opt_min = lu_to_y(ebur128, -1);
368  p = outpicref->data[0] + ebur128->graph.y * outpicref->linesize[0]
369  + ebur128->graph.x * 3;
370  for (y = 0; y < ebur128->graph.h; y++) {
371  const uint8_t *c = get_graph_color(ebur128, INT_MAX, y);
372 
373  for (x = 0; x < ebur128->graph.w; x++)
374  memcpy(p + x*3, c, 3);
375  p += outpicref->linesize[0];
376  }
377 
378  /* draw fancy rectangles around the graph and the gauge */
379 #define DRAW_RECT(r) do { \
380  drawline(outpicref, r.x, r.y - 1, r.w, 3); \
381  drawline(outpicref, r.x, r.y + r.h, r.w, 3); \
382  drawline(outpicref, r.x - 1, r.y, r.h, outpicref->linesize[0]); \
383  drawline(outpicref, r.x + r.w, r.y, r.h, outpicref->linesize[0]); \
384 } while (0)
385  DRAW_RECT(ebur128->graph);
386  DRAW_RECT(ebur128->gauge);
387 
388  return 0;
389 }
390 
392 {
393  AVFilterContext *ctx = inlink->dst;
394  EBUR128Context *ebur128 = ctx->priv;
395 
396  /* Unofficial reversed parametrization of PRE
397  * and RLB from 48kHz */
398 
399  double f0 = 1681.974450955533;
400  double G = 3.999843853973347;
401  double Q = 0.7071752369554196;
402 
403  double K = tan(M_PI * f0 / (double)inlink->sample_rate);
404  double Vh = pow(10.0, G / 20.0);
405  double Vb = pow(Vh, 0.4996667741545416);
406 
407  double a0 = 1.0 + K / Q + K * K;
408 
409  ebur128->pre_b[0] = (Vh + Vb * K / Q + K * K) / a0;
410  ebur128->pre_b[1] = 2.0 * (K * K - Vh) / a0;
411  ebur128->pre_b[2] = (Vh - Vb * K / Q + K * K) / a0;
412  ebur128->pre_a[1] = 2.0 * (K * K - 1.0) / a0;
413  ebur128->pre_a[2] = (1.0 - K / Q + K * K) / a0;
414 
415  f0 = 38.13547087602444;
416  Q = 0.5003270373238773;
417  K = tan(M_PI * f0 / (double)inlink->sample_rate);
418 
419  ebur128->rlb_b[0] = 1.0;
420  ebur128->rlb_b[1] = -2.0;
421  ebur128->rlb_b[2] = 1.0;
422  ebur128->rlb_a[1] = 2.0 * (K * K - 1.0) / (1.0 + K / Q + K * K);
423  ebur128->rlb_a[2] = (1.0 - K / Q + K * K) / (1.0 + K / Q + K * K);
424 
425  /* Force 100ms framing in case of metadata injection: the frames must have
426  * a granularity of the window overlap to be accurately exploited.
427  * As for the true peaks mode, it just simplifies the resampling buffer
428  * allocation and the lookup in it (since sample buffers differ in size, it
429  * can be more complex to integrate in the one-sample loop of
430  * filter_frame()). */
431  if (ebur128->metadata || (ebur128->peak_mode & PEAK_MODE_TRUE_PEAKS))
432  ebur128->nb_samples = FFMAX(inlink->sample_rate / 10, 1);
433  return 0;
434 }
435 
436 static int config_audio_output(AVFilterLink *outlink)
437 {
438  int i;
439  AVFilterContext *ctx = outlink->src;
440  EBUR128Context *ebur128 = ctx->priv;
441  const int nb_channels = outlink->ch_layout.nb_channels;
442 
443 #define BACK_MASK (AV_CH_BACK_LEFT |AV_CH_BACK_CENTER |AV_CH_BACK_RIGHT| \
444  AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_BACK_RIGHT| \
445  AV_CH_SIDE_LEFT |AV_CH_SIDE_RIGHT| \
446  AV_CH_SURROUND_DIRECT_LEFT |AV_CH_SURROUND_DIRECT_RIGHT)
447 
448  ebur128->nb_channels = nb_channels;
449  ebur128->x = av_calloc(nb_channels, 3 * sizeof(*ebur128->x));
450  ebur128->y = av_calloc(nb_channels, 3 * sizeof(*ebur128->y));
451  ebur128->z = av_calloc(nb_channels, 3 * sizeof(*ebur128->z));
452  ebur128->ch_weighting = av_calloc(nb_channels, sizeof(*ebur128->ch_weighting));
453  if (!ebur128->ch_weighting || !ebur128->x || !ebur128->y || !ebur128->z)
454  return AVERROR(ENOMEM);
455 
456 #define I400_BINS(x) ((x) * 4 / 10)
457 #define I3000_BINS(x) ((x) * 3)
458 
459  ebur128->i400.sum = av_calloc(nb_channels, sizeof(*ebur128->i400.sum));
460  ebur128->i3000.sum = av_calloc(nb_channels, sizeof(*ebur128->i3000.sum));
461  ebur128->i400.cache = av_calloc(nb_channels, sizeof(*ebur128->i400.cache));
462  ebur128->i3000.cache = av_calloc(nb_channels, sizeof(*ebur128->i3000.cache));
463  if (!ebur128->i400.sum || !ebur128->i3000.sum ||
464  !ebur128->i400.cache || !ebur128->i3000.cache)
465  return AVERROR(ENOMEM);
466 
467  for (i = 0; i < nb_channels; i++) {
468  /* channel weighting */
469  const enum AVChannel chl = av_channel_layout_channel_from_index(&outlink->ch_layout, i);
470  if (chl == AV_CHAN_LOW_FREQUENCY || chl == AV_CHAN_LOW_FREQUENCY_2) {
471  ebur128->ch_weighting[i] = 0;
472  } else if (chl < 64 && (1ULL << chl) & BACK_MASK) {
473  ebur128->ch_weighting[i] = 1.41;
474  } else {
475  ebur128->ch_weighting[i] = 1.0;
476  }
477 
478  if (!ebur128->ch_weighting[i])
479  continue;
480 
481  /* bins buffer for the two integration window (400ms and 3s) */
482  ebur128->i400.cache_size = I400_BINS(outlink->sample_rate);
483  ebur128->i3000.cache_size = I3000_BINS(outlink->sample_rate);
484  ebur128->i400.cache[i] = av_calloc(ebur128->i400.cache_size, sizeof(*ebur128->i400.cache[0]));
485  ebur128->i3000.cache[i] = av_calloc(ebur128->i3000.cache_size, sizeof(*ebur128->i3000.cache[0]));
486  if (!ebur128->i400.cache[i] || !ebur128->i3000.cache[i])
487  return AVERROR(ENOMEM);
488  }
489 
490 #if CONFIG_SWRESAMPLE
491  if (ebur128->peak_mode & PEAK_MODE_TRUE_PEAKS) {
492  int ret;
493 
494  ebur128->swr_buf = av_malloc_array(nb_channels, 19200 * sizeof(double));
495  ebur128->true_peaks = av_calloc(nb_channels, sizeof(*ebur128->true_peaks));
496  ebur128->true_peaks_per_frame = av_calloc(nb_channels, sizeof(*ebur128->true_peaks_per_frame));
497  ebur128->swr_ctx = swr_alloc();
498  if (!ebur128->swr_buf || !ebur128->true_peaks ||
499  !ebur128->true_peaks_per_frame || !ebur128->swr_ctx)
500  return AVERROR(ENOMEM);
501 
502  av_opt_set_chlayout(ebur128->swr_ctx, "in_chlayout", &outlink->ch_layout, 0);
503  av_opt_set_int(ebur128->swr_ctx, "in_sample_rate", outlink->sample_rate, 0);
504  av_opt_set_sample_fmt(ebur128->swr_ctx, "in_sample_fmt", outlink->format, 0);
505 
506  av_opt_set_chlayout(ebur128->swr_ctx, "out_chlayout", &outlink->ch_layout, 0);
507  av_opt_set_int(ebur128->swr_ctx, "out_sample_rate", 192000, 0);
508  av_opt_set_sample_fmt(ebur128->swr_ctx, "out_sample_fmt", outlink->format, 0);
509 
510  ret = swr_init(ebur128->swr_ctx);
511  if (ret < 0)
512  return ret;
513  }
514 #endif
515 
516  if (ebur128->peak_mode & PEAK_MODE_SAMPLES_PEAKS) {
517  ebur128->sample_peaks = av_calloc(nb_channels, sizeof(*ebur128->sample_peaks));
518  if (!ebur128->sample_peaks)
519  return AVERROR(ENOMEM);
520  }
521 
522  return 0;
523 }
524 
525 #define ENERGY(loudness) (ff_exp10(((loudness) + 0.691) / 10.))
526 #define LOUDNESS(energy) (-0.691 + 10 * log10(energy))
527 #define DBFS(energy) (20 * log10(energy))
528 
529 static struct hist_entry *get_histogram(void)
530 {
531  int i;
532  struct hist_entry *h = av_calloc(HIST_SIZE, sizeof(*h));
533 
534  if (!h)
535  return NULL;
536  for (i = 0; i < HIST_SIZE; i++) {
537  h[i].loudness = i / (double)HIST_GRAIN + ABS_THRES;
538  h[i].energy = ENERGY(h[i].loudness);
539  }
540  return h;
541 }
542 
544 {
545  EBUR128Context *ebur128 = ctx->priv;
546  AVFilterPad pad;
547  int ret;
548 
549  if (ebur128->loglevel != AV_LOG_INFO &&
550  ebur128->loglevel != AV_LOG_QUIET &&
551  ebur128->loglevel != AV_LOG_VERBOSE) {
552  if (ebur128->do_video || ebur128->metadata)
553  ebur128->loglevel = AV_LOG_VERBOSE;
554  else
555  ebur128->loglevel = AV_LOG_INFO;
556  }
557 
558  if (!CONFIG_SWRESAMPLE && (ebur128->peak_mode & PEAK_MODE_TRUE_PEAKS)) {
560  "True-peak mode requires libswresample to be performed\n");
561  return AVERROR(EINVAL);
562  }
563 
564  // if meter is +9 scale, scale range is from -18 LU to +9 LU (or 3*9)
565  // if meter is +18 scale, scale range is from -36 LU to +18 LU (or 3*18)
566  ebur128->scale_range = 3 * ebur128->meter;
567 
568  ebur128->i400.histogram = get_histogram();
569  ebur128->i3000.histogram = get_histogram();
570  if (!ebur128->i400.histogram || !ebur128->i3000.histogram)
571  return AVERROR(ENOMEM);
572 
573  ebur128->integrated_loudness = ABS_THRES;
574  ebur128->loudness_range = 0;
575 
576  /* insert output pads */
577  if (ebur128->do_video) {
578  pad = (AVFilterPad){
579  .name = "out0",
580  .type = AVMEDIA_TYPE_VIDEO,
581  .config_props = config_video_output,
582  };
583  ret = ff_append_outpad(ctx, &pad);
584  if (ret < 0)
585  return ret;
586  }
587  pad = (AVFilterPad){
588  .name = ebur128->do_video ? "out1" : "out0",
589  .type = AVMEDIA_TYPE_AUDIO,
590  .config_props = config_audio_output,
591  };
592  ret = ff_append_outpad(ctx, &pad);
593  if (ret < 0)
594  return ret;
595 
596  /* summary */
597  av_log(ctx, AV_LOG_VERBOSE, "EBU +%d scale\n", ebur128->meter);
598 
599  return 0;
600 }
601 
602 #define HIST_POS(power) (int)(((power) - ABS_THRES) * HIST_GRAIN)
603 
604 /* loudness and power should be set such as loudness = -0.691 +
605  * 10*log10(power), we just avoid doing that calculus two times */
606 static int gate_update(struct integrator *integ, double power,
607  double loudness, int gate_thres)
608 {
609  int ipower;
610  double relative_threshold;
611  int gate_hist_pos;
612 
613  /* update powers histograms by incrementing current power count */
614  ipower = av_clip(HIST_POS(loudness), 0, HIST_SIZE - 1);
615  integ->histogram[ipower].count++;
616 
617  /* compute relative threshold and get its position in the histogram */
618  integ->sum_kept_powers += power;
619  integ->nb_kept_powers++;
620  relative_threshold = integ->sum_kept_powers / integ->nb_kept_powers;
621  if (!relative_threshold)
622  relative_threshold = 1e-12;
623  integ->rel_threshold = LOUDNESS(relative_threshold) + gate_thres;
624  gate_hist_pos = av_clip(HIST_POS(integ->rel_threshold), 0, HIST_SIZE - 1);
625 
626  return gate_hist_pos;
627 }
628 
629 static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
630 {
631  int i, ch, idx_insample, ret;
632  AVFilterContext *ctx = inlink->dst;
633  EBUR128Context *ebur128 = ctx->priv;
634  const int nb_channels = ebur128->nb_channels;
635  const int nb_samples = insamples->nb_samples;
636  const double *samples = (double *)insamples->data[0];
637  AVFrame *pic;
638 
639 #if CONFIG_SWRESAMPLE
640  if (ebur128->peak_mode & PEAK_MODE_TRUE_PEAKS && ebur128->idx_insample == 0) {
641  const double *swr_samples = ebur128->swr_buf;
642  int ret = swr_convert(ebur128->swr_ctx, (uint8_t**)&ebur128->swr_buf, 19200,
643  (const uint8_t **)insamples->data, nb_samples);
644  if (ret < 0)
645  return ret;
646  for (ch = 0; ch < nb_channels; ch++)
647  ebur128->true_peaks_per_frame[ch] = 0.0;
648  for (idx_insample = 0; idx_insample < ret; idx_insample++) {
649  for (ch = 0; ch < nb_channels; ch++) {
650  ebur128->true_peaks[ch] = FFMAX(ebur128->true_peaks[ch], fabs(*swr_samples));
651  ebur128->true_peaks_per_frame[ch] = FFMAX(ebur128->true_peaks_per_frame[ch],
652  fabs(*swr_samples));
653  swr_samples++;
654  }
655  }
656  }
657 #endif
658 
659  for (idx_insample = ebur128->idx_insample; idx_insample < nb_samples; idx_insample++) {
660  const int bin_id_400 = ebur128->i400.cache_pos;
661  const int bin_id_3000 = ebur128->i3000.cache_pos;
662 
663 #define MOVE_TO_NEXT_CACHED_ENTRY(time) do { \
664  ebur128->i##time.cache_pos++; \
665  if (ebur128->i##time.cache_pos == \
666  ebur128->i##time.cache_size) { \
667  ebur128->i##time.filled = 1; \
668  ebur128->i##time.cache_pos = 0; \
669  } \
670 } while (0)
671 
674 
675  for (ch = 0; ch < nb_channels; ch++) {
676  double bin;
677 
678  if (ebur128->peak_mode & PEAK_MODE_SAMPLES_PEAKS)
679  ebur128->sample_peaks[ch] = FFMAX(ebur128->sample_peaks[ch], fabs(samples[idx_insample * nb_channels + ch]));
680 
681  ebur128->x[ch * 3] = samples[idx_insample * nb_channels + ch]; // set X[i]
682 
683  if (!ebur128->ch_weighting[ch])
684  continue;
685 
686  /* Y[i] = X[i]*b0 + X[i-1]*b1 + X[i-2]*b2 - Y[i-1]*a1 - Y[i-2]*a2 */
687 #define FILTER(Y, X, NUM, DEN) do { \
688  double *dst = ebur128->Y + ch*3; \
689  double *src = ebur128->X + ch*3; \
690  dst[2] = dst[1]; \
691  dst[1] = dst[0]; \
692  dst[0] = src[0]*NUM[0] + src[1]*NUM[1] + src[2]*NUM[2] \
693  - dst[1]*DEN[1] - dst[2]*DEN[2]; \
694 } while (0)
695 
696  // TODO: merge both filters in one?
697  FILTER(y, x, ebur128->pre_b, ebur128->pre_a); // apply pre-filter
698  ebur128->x[ch * 3 + 2] = ebur128->x[ch * 3 + 1];
699  ebur128->x[ch * 3 + 1] = ebur128->x[ch * 3 ];
700  FILTER(z, y, ebur128->rlb_b, ebur128->rlb_a); // apply RLB-filter
701 
702  bin = ebur128->z[ch * 3] * ebur128->z[ch * 3];
703 
704  /* add the new value, and limit the sum to the cache size (400ms or 3s)
705  * by removing the oldest one */
706  ebur128->i400.sum [ch] = ebur128->i400.sum [ch] + bin - ebur128->i400.cache [ch][bin_id_400];
707  ebur128->i3000.sum[ch] = ebur128->i3000.sum[ch] + bin - ebur128->i3000.cache[ch][bin_id_3000];
708 
709  /* override old cache entry with the new value */
710  ebur128->i400.cache [ch][bin_id_400 ] = bin;
711  ebur128->i3000.cache[ch][bin_id_3000] = bin;
712  }
713 
714 #define FIND_PEAK(global, sp, ptype) do { \
715  int ch; \
716  double maxpeak; \
717  maxpeak = 0.0; \
718  if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
719  for (ch = 0; ch < ebur128->nb_channels; ch++) \
720  maxpeak = FFMAX(maxpeak, sp[ch]); \
721  global = DBFS(maxpeak); \
722  } \
723 } while (0)
724 
725  FIND_PEAK(ebur128->sample_peak, ebur128->sample_peaks, SAMPLES);
726  FIND_PEAK(ebur128->true_peak, ebur128->true_peaks, TRUE);
727 
728  /* For integrated loudness, gating blocks are 400ms long with 75%
729  * overlap (see BS.1770-2 p5), so a re-computation is needed each 100ms
730  * (4800 samples at 48kHz). */
731  if (++ebur128->sample_count == inlink->sample_rate / 10) {
732  double loudness_400, loudness_3000;
733  double power_400 = 1e-12, power_3000 = 1e-12;
734  AVFilterLink *outlink = ctx->outputs[0];
735  const int64_t pts = insamples->pts +
736  av_rescale_q(idx_insample, (AVRational){ 1, inlink->sample_rate },
737  ctx->outputs[ebur128->do_video]->time_base);
738 
739  ebur128->sample_count = 0;
740 
741 #define COMPUTE_LOUDNESS(m, time) do { \
742  if (ebur128->i##time.filled) { \
743  /* weighting sum of the last <time> ms */ \
744  for (ch = 0; ch < nb_channels; ch++) \
745  power_##time += ebur128->ch_weighting[ch] * ebur128->i##time.sum[ch]; \
746  power_##time /= I##time##_BINS(inlink->sample_rate); \
747  } \
748  loudness_##time = LOUDNESS(power_##time); \
749 } while (0)
750 
751  COMPUTE_LOUDNESS(M, 400);
752  COMPUTE_LOUDNESS(S, 3000);
753 
754  /* Integrated loudness */
755 #define I_GATE_THRES -10 // initially defined to -8 LU in the first EBU standard
756 
757  if (loudness_400 >= ABS_THRES) {
758  double integrated_sum = 0.0;
759  uint64_t nb_integrated = 0;
760  int gate_hist_pos = gate_update(&ebur128->i400, power_400,
761  loudness_400, I_GATE_THRES);
762 
763  /* compute integrated loudness by summing the histogram values
764  * above the relative threshold */
765  for (i = gate_hist_pos; i < HIST_SIZE; i++) {
766  const unsigned nb_v = ebur128->i400.histogram[i].count;
767  nb_integrated += nb_v;
768  integrated_sum += nb_v * ebur128->i400.histogram[i].energy;
769  }
770  if (nb_integrated) {
771  ebur128->integrated_loudness = LOUDNESS(integrated_sum / nb_integrated);
772  /* dual-mono correction */
773  if (nb_channels == 1 && ebur128->dual_mono) {
774  ebur128->integrated_loudness -= ebur128->pan_law;
775  }
776  }
777  }
778 
779  /* LRA */
780 #define LRA_GATE_THRES -20
781 #define LRA_LOWER_PRC 10
782 #define LRA_HIGHER_PRC 95
783 
784  /* XXX: example code in EBU 3342 is ">=" but formula in BS.1770
785  * specs is ">" */
786  if (loudness_3000 >= ABS_THRES) {
787  uint64_t nb_powers = 0;
788  int gate_hist_pos = gate_update(&ebur128->i3000, power_3000,
789  loudness_3000, LRA_GATE_THRES);
790 
791  for (i = gate_hist_pos; i < HIST_SIZE; i++)
792  nb_powers += ebur128->i3000.histogram[i].count;
793  if (nb_powers) {
794  uint64_t n, nb_pow;
795 
796  /* get lower loudness to consider */
797  n = 0;
798  nb_pow = LRA_LOWER_PRC * nb_powers * 0.01 + 0.5;
799  for (i = gate_hist_pos; i < HIST_SIZE; i++) {
800  n += ebur128->i3000.histogram[i].count;
801  if (n >= nb_pow) {
802  ebur128->lra_low = ebur128->i3000.histogram[i].loudness;
803  break;
804  }
805  }
806 
807  /* get higher loudness to consider */
808  n = nb_powers;
809  nb_pow = LRA_HIGHER_PRC * nb_powers * 0.01 + 0.5;
810  for (i = HIST_SIZE - 1; i >= 0; i--) {
811  n -= FFMIN(n, ebur128->i3000.histogram[i].count);
812  if (n < nb_pow) {
813  ebur128->lra_high = ebur128->i3000.histogram[i].loudness;
814  break;
815  }
816  }
817 
818  // XXX: show low & high on the graph?
819  ebur128->loudness_range = ebur128->lra_high - ebur128->lra_low;
820  }
821  }
822 
823  /* dual-mono correction */
824  if (nb_channels == 1 && ebur128->dual_mono) {
825  loudness_400 -= ebur128->pan_law;
826  loudness_3000 -= ebur128->pan_law;
827  }
828 
829 #define LOG_FMT "TARGET:%d LUFS M:%6.1f S:%6.1f I:%6.1f %s LRA:%6.1f LU"
830 
831  /* push one video frame */
832  if (ebur128->do_video) {
833  AVFrame *clone;
834  int x, y;
835  uint8_t *p;
836  double gauge_value;
837  int y_loudness_lu_graph, y_loudness_lu_gauge;
838 
839  if (ebur128->gauge_type == GAUGE_TYPE_MOMENTARY) {
840  gauge_value = loudness_400 - ebur128->target;
841  } else {
842  gauge_value = loudness_3000 - ebur128->target;
843  }
844 
845  y_loudness_lu_graph = lu_to_y(ebur128, loudness_3000 - ebur128->target);
846  y_loudness_lu_gauge = lu_to_y(ebur128, gauge_value);
847 
848  ret = ff_inlink_make_frame_writable(outlink, &ebur128->outpicref);
849  if (ret < 0) {
850  av_frame_free(&insamples);
851  ebur128->insamples = NULL;
852  return ret;
853  }
854  pic = ebur128->outpicref;
855  /* draw the graph using the short-term loudness */
856  p = pic->data[0] + ebur128->graph.y*pic->linesize[0] + ebur128->graph.x*3;
857  for (y = 0; y < ebur128->graph.h; y++) {
858  const uint8_t *c = get_graph_color(ebur128, y_loudness_lu_graph, y);
859 
860  memmove(p, p + 3, (ebur128->graph.w - 1) * 3);
861  memcpy(p + (ebur128->graph.w - 1) * 3, c, 3);
862  p += pic->linesize[0];
863  }
864 
865  /* draw the gauge using either momentary or short-term loudness */
866  p = pic->data[0] + ebur128->gauge.y*pic->linesize[0] + ebur128->gauge.x*3;
867  for (y = 0; y < ebur128->gauge.h; y++) {
868  const uint8_t *c = get_graph_color(ebur128, y_loudness_lu_gauge, y);
869 
870  for (x = 0; x < ebur128->gauge.w; x++)
871  memcpy(p + x*3, c, 3);
872  p += pic->linesize[0];
873  }
874 
875  /* draw textual info */
876  if (ebur128->scale == SCALE_TYPE_ABSOLUTE) {
877  drawtext(pic, PAD, PAD - PAD/2, FONT16, font_colors,
878  LOG_FMT " ", // padding to erase trailing characters
879  ebur128->target, loudness_400, loudness_3000,
880  ebur128->integrated_loudness, "LUFS", ebur128->loudness_range);
881  } else {
882  drawtext(pic, PAD, PAD - PAD/2, FONT16, font_colors,
883  LOG_FMT " ", // padding to erase trailing characters
884  ebur128->target, loudness_400-ebur128->target, loudness_3000-ebur128->target,
885  ebur128->integrated_loudness-ebur128->target, "LU", ebur128->loudness_range);
886  }
887 
888  /* set pts and push frame */
889  pic->pts = av_rescale_q(pts, inlink->time_base, outlink->time_base);
890  pic->duration = 1;
891  clone = av_frame_clone(pic);
892  if (!clone)
893  return AVERROR(ENOMEM);
894  ebur128->idx_insample = idx_insample + 1;
895  ff_filter_set_ready(ctx, 100);
896  return ff_filter_frame(outlink, clone);
897  }
898 
899  if (ebur128->metadata) { /* happens only once per filter_frame call */
900  char metabuf[128];
901 #define META_PREFIX "lavfi.r128."
902 
903 #define SET_META(name, var) do { \
904  snprintf(metabuf, sizeof(metabuf), "%.3f", var); \
905  av_dict_set(&insamples->metadata, name, metabuf, 0); \
906 } while (0)
907 
908 #define SET_META_PEAK(name, ptype) do { \
909  if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
910  double max_peak = 0.0; \
911  char key[64]; \
912  for (ch = 0; ch < nb_channels; ch++) { \
913  snprintf(key, sizeof(key), \
914  META_PREFIX AV_STRINGIFY(name) "_peaks_ch%d", ch); \
915  max_peak = fmax(max_peak, ebur128->name##_peaks[ch]); \
916  SET_META(key, ebur128->name##_peaks[ch]); \
917  } \
918  snprintf(key, sizeof(key), \
919  META_PREFIX AV_STRINGIFY(name) "_peak"); \
920  SET_META(key, max_peak); \
921  } \
922 } while (0)
923 
924  SET_META(META_PREFIX "M", loudness_400);
925  SET_META(META_PREFIX "S", loudness_3000);
927  SET_META(META_PREFIX "LRA", ebur128->loudness_range);
928  SET_META(META_PREFIX "LRA.low", ebur128->lra_low);
929  SET_META(META_PREFIX "LRA.high", ebur128->lra_high);
930 
932  SET_META_PEAK(true, TRUE);
933  }
934 
935  if (ebur128->loglevel != AV_LOG_QUIET) {
936  if (ebur128->scale == SCALE_TYPE_ABSOLUTE) {
937  av_log(ctx, ebur128->loglevel, "t: %-10s " LOG_FMT,
938  av_ts2timestr(pts, &outlink->time_base),
939  ebur128->target, loudness_400, loudness_3000,
940  ebur128->integrated_loudness, "LUFS", ebur128->loudness_range);
941  } else {
942  av_log(ctx, ebur128->loglevel, "t: %-10s " LOG_FMT,
943  av_ts2timestr(pts, &outlink->time_base),
944  ebur128->target, loudness_400-ebur128->target, loudness_3000-ebur128->target,
945  ebur128->integrated_loudness-ebur128->target, "LU", ebur128->loudness_range);
946  }
947 
948 #define PRINT_PEAKS(str, sp, ptype) do { \
949  if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
950  av_log(ctx, ebur128->loglevel, " " str ":"); \
951  for (ch = 0; ch < nb_channels; ch++) \
952  av_log(ctx, ebur128->loglevel, " %5.1f", DBFS(sp[ch])); \
953  av_log(ctx, ebur128->loglevel, " dBFS"); \
954  } \
955 } while (0)
956 
957  PRINT_PEAKS("SPK", ebur128->sample_peaks, SAMPLES);
958  PRINT_PEAKS("FTPK", ebur128->true_peaks_per_frame, TRUE);
959  PRINT_PEAKS("TPK", ebur128->true_peaks, TRUE);
960  av_log(ctx, ebur128->loglevel, "\n");
961  }
962  }
963  }
964 
965  ebur128->idx_insample = 0;
966  ebur128->insamples = NULL;
967 
968  return ff_filter_frame(ctx->outputs[ebur128->do_video], insamples);
969 }
970 
972 {
973  AVFilterLink *inlink = ctx->inputs[0];
974  EBUR128Context *ebur128 = ctx->priv;
975  AVFilterLink *voutlink = ctx->outputs[0];
976  AVFilterLink *outlink = ctx->outputs[ebur128->do_video];
977  int ret;
978 
980  if (ebur128->do_video)
982 
983  if (!ebur128->insamples) {
984  AVFrame *in;
985 
986  if (ebur128->nb_samples > 0) {
987  ret = ff_inlink_consume_samples(inlink, ebur128->nb_samples, ebur128->nb_samples, &in);
988  } else {
990  }
991  if (ret < 0)
992  return ret;
993  if (ret > 0)
994  ebur128->insamples = in;
995  }
996 
997  if (ebur128->insamples)
998  ret = filter_frame(inlink, ebur128->insamples);
999 
1001  FF_FILTER_FORWARD_WANTED(outlink, inlink);
1002  if (ebur128->do_video)
1003  FF_FILTER_FORWARD_WANTED(voutlink, inlink);
1004 
1005  return ret;
1006 }
1007 
1009 {
1010  EBUR128Context *ebur128 = ctx->priv;
1013  AVFilterLink *inlink = ctx->inputs[0];
1014  AVFilterLink *outlink = ctx->outputs[0];
1015  int ret;
1016 
1018  static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE };
1019 
1020  /* set optional output video format */
1021  if (ebur128->do_video) {
1023  if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
1024  return ret;
1025  outlink = ctx->outputs[1];
1026  }
1027 
1028  /* set input and output audio formats
1029  * Note: ff_set_common_* functions are not used because they affect all the
1030  * links, and thus break the video format negotiation */
1032  if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0 ||
1033  (ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
1034  return ret;
1035 
1037  if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0 ||
1039  return ret;
1040 
1042  if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0 ||
1043  (ret = ff_formats_ref(formats, &outlink->incfg.samplerates)) < 0)
1044  return ret;
1045 
1046  return 0;
1047 }
1048 
1050 {
1051  EBUR128Context *ebur128 = ctx->priv;
1052 
1053  /* dual-mono correction */
1054  if (ebur128->nb_channels == 1 && ebur128->dual_mono) {
1055  ebur128->i400.rel_threshold -= ebur128->pan_law;
1056  ebur128->i3000.rel_threshold -= ebur128->pan_law;
1057  ebur128->lra_low -= ebur128->pan_law;
1058  ebur128->lra_high -= ebur128->pan_law;
1059  }
1060 
1061  if (ebur128->nb_channels > 0) {
1062  av_log(ctx, AV_LOG_INFO, "Summary:\n\n"
1063  " Integrated loudness:\n"
1064  " I: %5.1f LUFS\n"
1065  " Threshold: %5.1f LUFS\n\n"
1066  " Loudness range:\n"
1067  " LRA: %5.1f LU\n"
1068  " Threshold: %5.1f LUFS\n"
1069  " LRA low: %5.1f LUFS\n"
1070  " LRA high: %5.1f LUFS",
1071  ebur128->integrated_loudness, ebur128->i400.rel_threshold,
1072  ebur128->loudness_range, ebur128->i3000.rel_threshold,
1073  ebur128->lra_low, ebur128->lra_high);
1074 
1075 #define PRINT_PEAK_SUMMARY(str, value, ptype) do { \
1076  if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
1077  av_log(ctx, AV_LOG_INFO, "\n\n " str " peak:\n" \
1078  " Peak: %5.1f dBFS", value); \
1079  } \
1080 } while (0)
1081 
1082  PRINT_PEAK_SUMMARY("Sample", ebur128->sample_peak, SAMPLES);
1083  PRINT_PEAK_SUMMARY("True", ebur128->true_peak, TRUE);
1084  av_log(ctx, AV_LOG_INFO, "\n");
1085  }
1086 
1087  av_freep(&ebur128->y_line_ref);
1088  av_freep(&ebur128->x);
1089  av_freep(&ebur128->y);
1090  av_freep(&ebur128->z);
1091  av_freep(&ebur128->ch_weighting);
1092  av_freep(&ebur128->true_peaks);
1093  av_freep(&ebur128->sample_peaks);
1094  av_freep(&ebur128->true_peaks_per_frame);
1095  av_freep(&ebur128->i400.sum);
1096  av_freep(&ebur128->i3000.sum);
1097  av_freep(&ebur128->i400.histogram);
1098  av_freep(&ebur128->i3000.histogram);
1099  for (int i = 0; i < ebur128->nb_channels; i++) {
1100  if (ebur128->i400.cache)
1101  av_freep(&ebur128->i400.cache[i]);
1102  if (ebur128->i3000.cache)
1103  av_freep(&ebur128->i3000.cache[i]);
1104  }
1105  av_freep(&ebur128->i400.cache);
1106  av_freep(&ebur128->i3000.cache);
1107  av_frame_free(&ebur128->outpicref);
1108 #if CONFIG_SWRESAMPLE
1109  av_freep(&ebur128->swr_buf);
1110  swr_free(&ebur128->swr_ctx);
1111 #endif
1112 }
1113 
1114 static const AVFilterPad ebur128_inputs[] = {
1115  {
1116  .name = "default",
1117  .type = AVMEDIA_TYPE_AUDIO,
1118  .config_props = config_audio_input,
1119  },
1120 };
1121 
1123  .name = "ebur128",
1124  .description = NULL_IF_CONFIG_SMALL("EBU R128 scanner."),
1125  .priv_size = sizeof(EBUR128Context),
1126  .init = init,
1127  .uninit = uninit,
1128  .activate = activate,
1130  .outputs = NULL,
1132  .priv_class = &ebur128_class,
1134 };
M
#define M(a, b)
Definition: vp3dsp.c:48
formats
formats
Definition: signature.h:48
rect::w
int w
Definition: f_ebur128.c:77
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:112
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:85
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
AVFilterFormatsConfig::samplerates
AVFilterFormats * samplerates
Lists of supported sample rates, only for audio.
Definition: avfilter.h:515
EBUR128Context::dual_mono
int dual_mono
whether or not to treat single channel input files as dual-mono
Definition: f_ebur128.c:138
EBUR128Context::z
double * z
3 RLB-filter samples cache for each channel
Definition: f_ebur128.c:121
av_clip
#define av_clip
Definition: common.h:99
V
#define V
Definition: f_ebur128.c:163
EBUR128Context::ch_weighting
double * ch_weighting
channel weighting mapping
Definition: f_ebur128.c:111
EBUR128Context::y_opt_min
int y_opt_min
the y value (pixel position) for -1 LU
Definition: f_ebur128.c:106
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
integrator::filled
int filled
1 if the cache is completely filled, 0 otherwise
Definition: f_ebur128.c:70
integrator
Definition: f_ebur128.c:65
EBUR128Context::gauge_type
int gauge_type
whether gauge shows momentary or short
Definition: f_ebur128.c:141
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:436
EBUR128Context::y_opt_max
int y_opt_max
the y value (pixel position) for 1 LU
Definition: f_ebur128.c:105
SET_META_PEAK
#define SET_META_PEAK(name, ptype)
AVFilterFormatsConfig::channel_layouts
AVFilterChannelLayouts * channel_layouts
Lists of supported channel layouts, only for audio.
Definition: avfilter.h:520
PRINT_PEAKS
#define PRINT_PEAKS(str, sp, ptype)
get_graph_color
static const uint8_t * get_graph_color(const EBUR128Context *ebur128, int v, int y)
Definition: f_ebur128.c:223
A
#define A
Definition: f_ebur128.c:162
color
Definition: vf_paletteuse.c:512
AV_LOG_QUIET
#define AV_LOG_QUIET
Print no output.
Definition: log.h:162
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1015
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:948
ff_channel_layouts_ref
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:674
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:337
EBUR128Context::do_video
int do_video
1 if video output enabled, 0 otherwise
Definition: f_ebur128.c:96
rect
Definition: f_ebur128.c:77
HIST_SIZE
#define HIST_SIZE
Definition: f_ebur128.c:50
EBUR128Context::sample_count
int sample_count
sample count used for refresh frequency, reset at refresh
Definition: f_ebur128.c:112
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
rect::y
int y
Definition: f_ebur128.c:77
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:486
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
w
uint8_t w
Definition: llviddspenc.c:38
av_channel_layout_channel_from_index
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
Definition: channel_layout.c:665
AVOption
AVOption.
Definition: opt.h:357
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(ebur128)
I_GATE_THRES
#define I_GATE_THRES
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:159
ebur128_options
static const AVOption ebur128_options[]
Definition: f_ebur128.c:167
F
#define F
Definition: f_ebur128.c:164
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
float.h
FIND_PEAK
#define FIND_PEAK(global, sp, ptype)
init
static av_cold int init(AVFilterContext *ctx)
Definition: f_ebur128.c:543
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
config_audio_output
static int config_audio_output(AVFilterLink *outlink)
Definition: f_ebur128.c:436
integrator::sum_kept_powers
double sum_kept_powers
sum of the powers (weighted sums) above absolute threshold
Definition: f_ebur128.c:72
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
SCALE_TYPE_RELATIVE
@ SCALE_TYPE_RELATIVE
Definition: f_ebur128.c:158
video.h
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:199
LRA_HIGHER_PRC
#define LRA_HIGHER_PRC
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:395
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
formats.h
S
#define S(s, c, i)
Definition: flacdsp_template.c:46
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: f_ebur128.c:1049
FONT8
#define FONT8
Definition: f_ebur128.c:241
EBUR128Context::pan_law
double pan_law
pan law value used to calculate dual-mono measurements
Definition: f_ebur128.c:139
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:1442
EBUR128Context::rlb_b
double rlb_b[3]
rlb-filter numerator coefficients
Definition: f_ebur128.c:124
drawline
static void drawline(AVFrame *pic, int x, int y, int len, int step)
Definition: f_ebur128.c:282
get_histogram
static struct hist_entry * get_histogram(void)
Definition: f_ebur128.c:529
R
#define R
Definition: f_ebur128.c:166
EBUR128Context::scale
int scale
display scale type of statistics
Definition: f_ebur128.c:142
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: f_ebur128.c:1008
LRA_GATE_THRES
#define LRA_GATE_THRES
EBUR128Context::rlb_a
double rlb_a[3]
rlb-filter denominator coefficients
Definition: f_ebur128.c:125
pts
static int64_t pts
Definition: transcode_aac.c:644
integrator::cache_pos
int cache_pos
focus on the last added bin in the cache array
Definition: f_ebur128.c:67
EBUR128Context::nb_samples
int nb_samples
number of samples to consume per single input frame
Definition: f_ebur128.c:113
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
swr_convert
int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *const *out_arg, int out_count, const uint8_t *const *in_arg, int in_count)
Convert audio.
Definition: swresample.c:719
font_colors
static const uint8_t font_colors[]
Definition: f_ebur128.c:244
avassert.h
EBUR128Context::metadata
int metadata
whether or not to inject loudness results in frames
Definition: f_ebur128.c:137
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
MOVE_TO_NEXT_CACHED_ENTRY
#define MOVE_TO_NEXT_CACHED_ENTRY(time)
av_cold
#define av_cold
Definition: attributes.h:90
FILTER
#define FILTER(Y, X, NUM, DEN)
EBUR128Context::graph
struct rect graph
rectangle for the main graph in the center
Definition: f_ebur128.c:99
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
Definition: f_ebur128.c:629
PEAK_MODE_TRUE_PEAKS
@ PEAK_MODE_TRUE_PEAKS
Definition: f_ebur128.c:148
OFFSET
#define OFFSET(x)
Definition: f_ebur128.c:161
swr_init
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
Definition: swresample.c:140
config_video_output
static int config_video_output(AVFilterLink *outlink)
Definition: f_ebur128.c:293
mask
static const uint16_t mask[17]
Definition: lzw.c:38
EBUR128Context::integrated_loudness
double integrated_loudness
integrated loudness in LUFS (I)
Definition: f_ebur128.c:131
EBUR128Context::w
int w
Definition: f_ebur128.c:97
FONT16
#define FONT16
Definition: f_ebur128.c:242
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:247
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:679
EBUR128Context::target
int target
target level in LUFS used to set relative zero LU in visualization
Definition: f_ebur128.c:140
swr_alloc
av_cold struct SwrContext * swr_alloc(void)
Allocate SwrContext.
Definition: options.c:148
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
filters.h
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:304
ctx
AVFormatContext * ctx
Definition: movenc.c:49
PEAK_MODE_NONE
@ PEAK_MODE_NONE
Definition: f_ebur128.c:146
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:593
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
drawtext
static void drawtext(AVFrame *pic, int x, int y, int ftid, const uint8_t *color, const char *fmt,...)
Definition: f_ebur128.c:249
X
#define X
Definition: f_ebur128.c:165
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
hist_entry::loudness
double loudness
L = -0.691 + 10 * log10(E)
Definition: f_ebur128.c:62
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
ff_inlink_make_frame_writable
int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
Make sure a frame is writable.
Definition: avfilter.c:1489
EBUR128Context::true_peaks_per_frame
double * true_peaks_per_frame
true peaks in a frame per channel
Definition: f_ebur128.c:88
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:73
if
if(ret)
Definition: filter_design.txt:179
EBUR128Context::sample_peaks
double * sample_peaks
sample peaks per channel
Definition: f_ebur128.c:87
GAUGE_TYPE_SHORTTERM
@ GAUGE_TYPE_SHORTTERM
Definition: f_ebur128.c:153
HIST_GRAIN
#define HIST_GRAIN
defines histogram precision
Definition: f_ebur128.c:49
I400_BINS
#define I400_BINS(x)
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:1462
NULL
#define NULL
Definition: coverity.c:32
EBUR128Context::peak_mode
int peak_mode
enabled peak modes
Definition: f_ebur128.c:83
HIST_POS
#define HIST_POS(power)
Definition: f_ebur128.c:602
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_OPT_TYPE_IMAGE_SIZE
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive ints
Definition: opt.h:255
EBUR128Context::pre_b
double pre_b[3]
pre-filter numerator coefficients
Definition: f_ebur128.c:122
LOG_FMT
#define LOG_FMT
EBUR128Context::gauge
struct rect gauge
rectangle for the gauge on the right
Definition: f_ebur128.c:100
double
double
Definition: af_crystalizer.c:131
av_clipf
av_clipf
Definition: af_crystalizer.c:121
SCALE_TYPE_ABSOLUTE
@ SCALE_TYPE_ABSOLUTE
Definition: f_ebur128.c:157
swresample.h
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
av_opt_set_int
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:799
EBUR128Context
Definition: f_ebur128.c:79
AVFILTER_FLAG_DYNAMIC_OUTPUTS
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
Definition: avfilter.h:112
hist_entry::count
unsigned count
how many times the corresponding value occurred
Definition: f_ebur128.c:60
EBUR128Context::pre_a
double pre_a[3]
pre-filter denominator coefficients
Definition: f_ebur128.c:123
EBUR128Context::y_zero_lu
int y_zero_lu
the y value (pixel position) for 0 LU
Definition: f_ebur128.c:104
EBUR128Context::i3000
struct integrator i3000
3s integrator, used for Short term loudness (S), and Loudness Range (LRA)
Definition: f_ebur128.c:128
ENERGY
#define ENERGY(loudness)
Definition: f_ebur128.c:525
activate
static int activate(AVFilterContext *ctx)
Definition: f_ebur128.c:971
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
av_ts2timestr
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:83
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
av_opt_set_chlayout
int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *channel_layout, int search_flags)
Definition: opt.c:941
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
sample
#define sample
Definition: flacdsp_template.c:44
AV_CHAN_LOW_FREQUENCY
@ AV_CHAN_LOW_FREQUENCY
Definition: channel_layout.h:53
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
rect::h
int h
Definition: f_ebur128.c:77
swr_free
av_cold void swr_free(SwrContext **ss)
Free the given SwrContext and set the pointer to NULL.
Definition: swresample.c:121
EBUR128Context::true_peak
double true_peak
global true peak
Definition: f_ebur128.c:84
EBUR128Context::sample_peak
double sample_peak
global sample peak
Definition: f_ebur128.c:86
EBUR128Context::outpicref
AVFrame * outpicref
output picture reference, updated regularly
Definition: f_ebur128.c:101
line
Definition: graph2dot.c:48
FF_FILTER_FORWARD_WANTED
FF_FILTER_FORWARD_WANTED(outlink, inlink)
xga_font_data.h
ff_all_channel_layouts
AVFilterChannelLayouts * ff_all_channel_layouts(void)
Construct an empty AVFilterChannelLayouts/AVFilterFormats struct – representing any channel layout (w...
Definition: formats.c:613
rect::x
int x
Definition: f_ebur128.c:77
EBUR128Context::h
int h
size of the video output
Definition: f_ebur128.c:97
a0
#define a0
Definition: regdef.h:46
M_PI
#define M_PI
Definition: mathematics.h:67
I3000_BINS
#define I3000_BINS(x)
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
internal.h
AVChannel
AVChannel
Definition: channel_layout.h:47
GAUGE_TYPE_MOMENTARY
@ GAUGE_TYPE_MOMENTARY
Definition: f_ebur128.c:152
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:454
avpriv_vga16_font
const uint8_t avpriv_vga16_font[4096]
Definition: xga_font_data.c:160
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
EBUR128Context::y
double * y
3 pre-filter samples cache for each channel
Definition: f_ebur128.c:120
EBUR128Context::text
struct rect text
rectangle for the LU legend on the left
Definition: f_ebur128.c:98
EBUR128Context::y_line_ref
int * y_line_ref
y reference values for drawing the LU lines in the graph and the gauge
Definition: f_ebur128.c:107
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
vsnprintf
#define vsnprintf
Definition: snprintf.h:36
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
integrator::rel_threshold
double rel_threshold
relative threshold
Definition: f_ebur128.c:71
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
ABS_THRES
#define ABS_THRES
silence gate: we discard anything below this absolute (LUFS) threshold
Definition: f_ebur128.c:47
len
int len
Definition: vorbis_enc_data.h:426
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
integrator::nb_kept_powers
int nb_kept_powers
number of sum above absolute threshold
Definition: f_ebur128.c:73
EBUR128Context::true_peaks
double * true_peaks
true peaks per channel
Definition: f_ebur128.c:85
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
EBUR128Context::loudness_range
double loudness_range
loudness range in LU (LRA)
Definition: f_ebur128.c:132
AVFilter
Filter definition.
Definition: avfilter.h:166
hist_entry::energy
double energy
E = 10^((L + 0.691) / 10)
Definition: f_ebur128.c:61
graph_colors
static const uint8_t graph_colors[]
Definition: f_ebur128.c:204
ret
ret
Definition: filter_design.txt:187
EBUR128Context::lra_low
double lra_low
Definition: f_ebur128.c:133
LRA_LOWER_PRC
#define LRA_LOWER_PRC
dict.h
integrator::sum
double * sum
sum of the last N ms filtered samples (cache content)
Definition: f_ebur128.c:69
EBUR128Context::lra_high
double lra_high
low and high LRA values
Definition: f_ebur128.c:133
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:481
ff_af_ebur128
const AVFilter ff_af_ebur128
Definition: f_ebur128.c:1122
EBUR128Context::scale_range
int scale_range
the range of LU values according to the meter
Definition: f_ebur128.c:103
ff_all_samplerates
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:607
META_PREFIX
#define META_PREFIX
power
static float power(float r, float g, float b, float max)
Definition: preserve_color.h:45
SET_META
#define SET_META(name, var)
channel_layout.h
AV_CHAN_LOW_FREQUENCY_2
@ AV_CHAN_LOW_FREQUENCY_2
Definition: channel_layout.h:76
SAMPLES
#define SAMPLES
LOUDNESS
#define LOUDNESS(energy)
Definition: f_ebur128.c:526
EBUR128Context::meter
int meter
select a EBU mode between +9 and +18
Definition: f_ebur128.c:102
PAD
#define PAD
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:245
avfilter.h
EBUR128Context::insamples
AVFrame * insamples
input samples reference, updated regularly
Definition: f_ebur128.c:115
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
integrator::cache
double ** cache
window of filtered samples (N ms)
Definition: f_ebur128.c:66
ffmath.h
G
#define G
Definition: huffyuv.h:43
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
PEAK_MODE_SAMPLES_PEAKS
@ PEAK_MODE_SAMPLES_PEAKS
Definition: f_ebur128.c:147
AVFilterFormatsConfig::formats
AVFilterFormats * formats
List of supported formats (pixel or sample).
Definition: avfilter.h:510
ebur128_inputs
static const AVFilterPad ebur128_inputs[]
Definition: f_ebur128.c:1114
ff_append_outpad
int ff_append_outpad(AVFilterContext *f, AVFilterPad *p)
Definition: avfilter.c:138
avpriv_cga_font
const uint8_t avpriv_cga_font[2048]
Definition: xga_font_data.c:29
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
DRAW_RECT
#define DRAW_RECT(r)
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:261
EBUR128Context::nb_channels
int nb_channels
number of channels in the input
Definition: f_ebur128.c:110
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
EBUR128Context::idx_insample
int idx_insample
current sample position of processed samples in single input frame
Definition: f_ebur128.c:114
FF_FILTER_FORWARD_STATUS_ALL
#define FF_FILTER_FORWARD_STATUS_ALL(inlink, filter)
Acknowledge the status on an input link and forward it to an output link.
Definition: filters.h:239
EBUR128Context::i400
struct integrator i400
400ms integrator, used for Momentary loudness (M), and Integrated loudness (I)
Definition: f_ebur128.c:127
K
#define K
Definition: palette.c:25
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:244
Q
#define Q(x)
Definition: filter_template.c:433
timestamp.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:419
config_audio_input
static int config_audio_input(AVFilterLink *inlink)
Definition: f_ebur128.c:391
integrator::histogram
struct hist_entry * histogram
histogram of the powers, used to compute LRA and I
Definition: f_ebur128.c:74
integrator::cache_size
int cache_size
Definition: f_ebur128.c:68
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
EBUR128Context::x
double * x
3 input samples cache for each channel
Definition: f_ebur128.c:119
PRINT_PEAK_SUMMARY
#define PRINT_PEAK_SUMMARY(str, value, ptype)
h
h
Definition: vp9dsp_template.c:2038
BACK_MASK
#define BACK_MASK
AV_SAMPLE_FMT_DBL
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:61
lu_to_y
static int lu_to_y(const EBUR128Context *ebur128, double v)
Definition: f_ebur128.c:233
av_opt_set_sample_fmt
int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
Definition: opt.c:918
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:254
EBUR128Context::loglevel
int loglevel
log level for frame logging
Definition: f_ebur128.c:136
gate_update
static int gate_update(struct integrator *integ, double power, double loudness, int gate_thres)
Definition: f_ebur128.c:606
COMPUTE_LOUDNESS
#define COMPUTE_LOUDNESS(m, time)
ff_filter_set_ready
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:235
hist_entry
A histogram is an array of HIST_SIZE hist_entry storing all the energies recorded (with an accuracy o...
Definition: f_ebur128.c:59