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