2 * Copyright (c) 2012 Clément Bœsch
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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 * @todo support other frequencies to avoid resampling
32 #include "libavutil/avassert.h"
33 #include "libavutil/avstring.h"
34 #include "libavutil/channel_layout.h"
35 #include "libavutil/dict.h"
36 #include "libavutil/xga_font_data.h"
37 #include "libavutil/opt.h"
38 #include "libavutil/timestamp.h"
39 #include "libswresample/swresample.h"
45 #define MAX_CHANNELS 63
47 /* pre-filter coefficients */
48 #define PRE_B0 1.53512485958697
49 #define PRE_B1 -2.69169618940638
50 #define PRE_B2 1.19839281085285
51 #define PRE_A1 -1.69065929318241
52 #define PRE_A2 0.73248077421585
54 /* RLB-filter coefficients */
58 #define RLB_A1 -1.99004745483398
59 #define RLB_A2 0.99007225036621
61 #define ABS_THRES -70 ///< silence gate: we discard anything below this absolute (LUFS) threshold
62 #define ABS_UP_THRES 10 ///< upper loud limit to consider (ABS_THRES being the minimum)
63 #define HIST_GRAIN 100 ///< defines histogram precision
64 #define HIST_SIZE ((ABS_UP_THRES - ABS_THRES) * HIST_GRAIN + 1)
67 * A histogram is an array of HIST_SIZE hist_entry storing all the energies
68 * recorded (with an accuracy of 1/HIST_GRAIN) of the loudnesses from ABS_THRES
69 * (at 0) to ABS_UP_THRES (at HIST_SIZE-1).
70 * This fixed-size system avoids the need of a list of energies growing
71 * infinitely over the time and is thus more scalable.
74 int count
; ///< how many times the corresponding value occurred
75 double energy
; ///< E = 10^((L + 0.691) / 10)
76 double loudness
; ///< L = -0.691 + 10 * log10(E)
80 double *cache
[MAX_CHANNELS
]; ///< window of filtered samples (N ms)
81 int cache_pos
; ///< focus on the last added bin in the cache array
82 double sum
[MAX_CHANNELS
]; ///< sum of the last N ms filtered samples (cache content)
83 int filled
; ///< 1 if the cache is completely filled, 0 otherwise
84 double rel_threshold
; ///< relative threshold
85 double sum_kept_powers
; ///< sum of the powers (weighted sums) above absolute threshold
86 int nb_kept_powers
; ///< number of sum above absolute threshold
87 struct hist_entry
*histogram
; ///< histogram of the powers, used to compute LRA and I
90 struct rect
{ int x
, y
, w
, h
; };
93 const AVClass
*class; ///< AVClass context for log and options purpose
96 int peak_mode
; ///< enabled peak modes
97 double *true_peaks
; ///< true peaks per channel
98 double *sample_peaks
; ///< sample peaks per channel
99 double *true_peaks_per_frame
; ///< true peaks in a frame per channel
100 #if CONFIG_SWRESAMPLE
101 SwrContext
*swr_ctx
; ///< over-sampling context for true peak metering
102 double *swr_buf
; ///< resampled audio data for true peak metering
107 int do_video
; ///< 1 if video output enabled, 0 otherwise
108 int w
, h
; ///< size of the video output
109 struct rect text
; ///< rectangle for the LU legend on the left
110 struct rect graph
; ///< rectangle for the main graph in the center
111 struct rect gauge
; ///< rectangle for the gauge on the right
112 AVFrame
*outpicref
; ///< output picture reference, updated regularly
113 int meter
; ///< select a EBU mode between +9 and +18
114 int scale_range
; ///< the range of LU values according to the meter
115 int y_zero_lu
; ///< the y value (pixel position) for 0 LU
116 int *y_line_ref
; ///< y reference values for drawing the LU lines in the graph and the gauge
119 int nb_channels
; ///< number of channels in the input
120 double *ch_weighting
; ///< channel weighting mapping
121 int sample_count
; ///< sample count used for refresh frequency, reset at refresh
124 * The mult by 3 in the following is for X[i], X[i-1] and X[i-2] */
125 double x
[MAX_CHANNELS
* 3]; ///< 3 input samples cache for each channel
126 double y
[MAX_CHANNELS
* 3]; ///< 3 pre-filter samples cache for each channel
127 double z
[MAX_CHANNELS
* 3]; ///< 3 RLB-filter samples cache for each channel
129 #define I400_BINS (48000 * 4 / 10)
130 #define I3000_BINS (48000 * 3)
131 struct integrator i400
; ///< 400ms integrator, used for Momentary loudness (M), and Integrated loudness (I)
132 struct integrator i3000
; ///< 3s integrator, used for Short term loudness (S), and Loudness Range (LRA)
134 /* I and LRA specific */
135 double integrated_loudness
; ///< integrated loudness in LUFS (I)
136 double loudness_range
; ///< loudness range in LU (LRA)
137 double lra_low
, lra_high
; ///< low and high LRA values
140 int loglevel
; ///< log level for frame logging
141 int metadata
; ///< whether or not to inject loudness results in frames
146 PEAK_MODE_SAMPLES_PEAKS
= 1<<1,
147 PEAK_MODE_TRUE_PEAKS
= 1<<2,
150 #define OFFSET(x) offsetof(EBUR128Context, x)
151 #define A AV_OPT_FLAG_AUDIO_PARAM
152 #define V AV_OPT_FLAG_VIDEO_PARAM
153 #define F AV_OPT_FLAG_FILTERING_PARAM
154 static const AVOption ebur128_options
[] = {
155 { "video", "set video output", OFFSET(do_video
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, 1, V
|F
},
156 { "size", "set video size", OFFSET(w
), AV_OPT_TYPE_IMAGE_SIZE
, {.str
= "640x480"}, 0, 0, V
|F
},
157 { "meter", "set scale meter (+9 to +18)", OFFSET(meter
), AV_OPT_TYPE_INT
, {.i64
= 9}, 9, 18, V
|F
},
158 { "framelog", "force frame logging level", OFFSET(loglevel
), AV_OPT_TYPE_INT
, {.i64
= -1}, INT_MIN
, INT_MAX
, A
|V
|F
, "level" },
159 { "info", "information logging level", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_LOG_INFO
}, INT_MIN
, INT_MAX
, A
|V
|F
, "level" },
160 { "verbose", "verbose logging level", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_LOG_VERBOSE
}, INT_MIN
, INT_MAX
, A
|V
|F
, "level" },
161 { "metadata", "inject metadata in the filtergraph", OFFSET(metadata
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, 1, A
|V
|F
},
162 { "peak", "set peak mode", OFFSET(peak_mode
), AV_OPT_TYPE_FLAGS
, {.i64
= PEAK_MODE_NONE
}, 0, INT_MAX
, A
|F
, "mode" },
163 { "none", "disable any peak mode", 0, AV_OPT_TYPE_CONST
, {.i64
= PEAK_MODE_NONE
}, INT_MIN
, INT_MAX
, A
|F
, "mode" },
164 { "sample", "enable peak-sample mode", 0, AV_OPT_TYPE_CONST
, {.i64
= PEAK_MODE_SAMPLES_PEAKS
}, INT_MIN
, INT_MAX
, A
|F
, "mode" },
165 { "true", "enable true-peak mode", 0, AV_OPT_TYPE_CONST
, {.i64
= PEAK_MODE_TRUE_PEAKS
}, INT_MIN
, INT_MAX
, A
|F
, "mode" },
169 AVFILTER_DEFINE_CLASS(ebur128
);
171 static const uint8_t graph_colors
[] = {
172 0xdd, 0x66, 0x66, // value above 0LU non reached
173 0x66, 0x66, 0xdd, // value below 0LU non reached
174 0x96, 0x33, 0x33, // value above 0LU reached
175 0x33, 0x33, 0x96, // value below 0LU reached
176 0xdd, 0x96, 0x96, // value above 0LU line non reached
177 0x96, 0x96, 0xdd, // value below 0LU line non reached
178 0xdd, 0x33, 0x33, // value above 0LU line reached
179 0x33, 0x33, 0xdd, // value below 0LU line reached
182 static const uint8_t *get_graph_color(const EBUR128Context
*ebur128
, int v
, int y
)
184 const int below0
= y
> ebur128
->y_zero_lu
;
185 const int reached
= y
>= v
;
186 const int line
= ebur128
->y_line_ref
[y
] || y
== ebur128
->y_zero_lu
;
187 const int colorid
= 4*line
+ 2*reached
+ below0
;
188 return graph_colors
+ 3*colorid
;
191 static inline int lu_to_y(const EBUR128Context
*ebur128
, double v
)
193 v
+= 2 * ebur128
->meter
; // make it in range [0;...]
194 v
= av_clipf(v
, 0, ebur128
->scale_range
); // make sure it's in the graph scale
195 v
= ebur128
->scale_range
- v
; // invert value (y=0 is on top)
196 return v
* ebur128
->graph
.h
/ ebur128
->scale_range
; // rescale from scale range to px height
202 static const uint8_t font_colors
[] = {
207 static void drawtext(AVFrame
*pic
, int x
, int y
, int ftid
, const uint8_t *color
, const char *fmt
, ...)
215 if (ftid
== FONT16
) font
= avpriv_vga16_font
, font_height
= 16;
216 else if (ftid
== FONT8
) font
= avpriv_cga_font
, font_height
= 8;
220 vsnprintf(buf
, sizeof(buf
), fmt
, vl
);
223 for (i
= 0; buf
[i
]; i
++) {
225 uint8_t *p
= pic
->data
[0] + y
*pic
->linesize
[0] + (x
+ i
*8)*3;
227 for (char_y
= 0; char_y
< font_height
; char_y
++) {
228 for (mask
= 0x80; mask
; mask
>>= 1) {
229 if (font
[buf
[i
] * font_height
+ char_y
] & mask
)
232 memcpy(p
, "\x00\x00\x00", 3);
235 p
+= pic
->linesize
[0] - 8*3;
240 static void drawline(AVFrame
*pic
, int x
, int y
, int len
, int step
)
243 uint8_t *p
= pic
->data
[0] + y
*pic
->linesize
[0] + x
*3;
245 for (i
= 0; i
< len
; i
++) {
246 memcpy(p
, "\x00\xff\x00", 3);
251 static int config_video_output(AVFilterLink
*outlink
)
255 AVFilterContext
*ctx
= outlink
->src
;
256 EBUR128Context
*ebur128
= ctx
->priv
;
259 /* check if there is enough space to represent everything decently */
260 if (ebur128
->w
< 640 || ebur128
->h
< 480) {
261 av_log(ctx
, AV_LOG_ERROR
, "Video size %dx%d is too small, "
262 "minimum size is 640x480\n", ebur128
->w
, ebur128
->h
);
263 return AVERROR(EINVAL
);
265 outlink
->w
= ebur128
->w
;
266 outlink
->h
= ebur128
->h
;
270 /* configure text area position and size */
271 ebur128
->text
.x
= PAD
;
272 ebur128
->text
.y
= 40;
273 ebur128
->text
.w
= 3 * 8; // 3 characters
274 ebur128
->text
.h
= ebur128
->h
- PAD
- ebur128
->text
.y
;
276 /* configure gauge position and size */
277 ebur128
->gauge
.w
= 20;
278 ebur128
->gauge
.h
= ebur128
->text
.h
;
279 ebur128
->gauge
.x
= ebur128
->w
- PAD
- ebur128
->gauge
.w
;
280 ebur128
->gauge
.y
= ebur128
->text
.y
;
282 /* configure graph position and size */
283 ebur128
->graph
.x
= ebur128
->text
.x
+ ebur128
->text
.w
+ PAD
;
284 ebur128
->graph
.y
= ebur128
->gauge
.y
;
285 ebur128
->graph
.w
= ebur128
->gauge
.x
- ebur128
->graph
.x
- PAD
;
286 ebur128
->graph
.h
= ebur128
->gauge
.h
;
288 /* graph and gauge share the LU-to-pixel code */
289 av_assert0(ebur128
->graph
.h
== ebur128
->gauge
.h
);
291 /* prepare the initial picref buffer */
292 av_frame_free(&ebur128
->outpicref
);
293 ebur128
->outpicref
= outpicref
=
294 ff_get_video_buffer(outlink
, outlink
->w
, outlink
->h
);
296 return AVERROR(ENOMEM
);
297 outlink
->sample_aspect_ratio
= (AVRational
){1,1};
299 /* init y references values (to draw LU lines) */
300 ebur128
->y_line_ref
= av_calloc(ebur128
->graph
.h
+ 1, sizeof(*ebur128
->y_line_ref
));
301 if (!ebur128
->y_line_ref
)
302 return AVERROR(ENOMEM
);
304 /* black background */
305 memset(outpicref
->data
[0], 0, ebur128
->h
* outpicref
->linesize
[0]);
307 /* draw LU legends */
308 drawtext(outpicref
, PAD
, PAD
+16, FONT8
, font_colors
+3, " LU");
309 for (i
= ebur128
->meter
; i
>= -ebur128
->meter
* 2; i
--) {
310 y
= lu_to_y(ebur128
, i
);
311 x
= PAD
+ (i
< 10 && i
> -10) * 8;
312 ebur128
->y_line_ref
[y
] = i
;
313 y
-= 4; // -4 to center vertically
314 drawtext(outpicref
, x
, y
+ ebur128
->graph
.y
, FONT8
, font_colors
+3,
315 "%c%d", i
< 0 ? '-' : i
> 0 ? '+' : ' ', FFABS(i
));
319 ebur128
->y_zero_lu
= lu_to_y(ebur128
, 0);
320 p
= outpicref
->data
[0] + ebur128
->graph
.y
* outpicref
->linesize
[0]
321 + ebur128
->graph
.x
* 3;
322 for (y
= 0; y
< ebur128
->graph
.h
; y
++) {
323 const uint8_t *c
= get_graph_color(ebur128
, INT_MAX
, y
);
325 for (x
= 0; x
< ebur128
->graph
.w
; x
++)
326 memcpy(p
+ x
*3, c
, 3);
327 p
+= outpicref
->linesize
[0];
330 /* draw fancy rectangles around the graph and the gauge */
331 #define DRAW_RECT(r) do { \
332 drawline(outpicref, r.x, r.y - 1, r.w, 3); \
333 drawline(outpicref, r.x, r.y + r.h, r.w, 3); \
334 drawline(outpicref, r.x - 1, r.y, r.h, outpicref->linesize[0]); \
335 drawline(outpicref, r.x + r.w, r.y, r.h, outpicref->linesize[0]); \
337 DRAW_RECT(ebur128
->graph
);
338 DRAW_RECT(ebur128
->gauge
);
340 outlink
->flags
|= FF_LINK_FLAG_REQUEST_LOOP
;
345 static int config_audio_input(AVFilterLink
*inlink
)
347 AVFilterContext
*ctx
= inlink
->dst
;
348 EBUR128Context
*ebur128
= ctx
->priv
;
350 /* Force 100ms framing in case of metadata injection: the frames must have
351 * a granularity of the window overlap to be accurately exploited.
352 * As for the true peaks mode, it just simplifies the resampling buffer
353 * allocation and the lookup in it (since sample buffers differ in size, it
354 * can be more complex to integrate in the one-sample loop of
355 * filter_frame()). */
356 if (ebur128
->metadata
|| (ebur128
->peak_mode
& PEAK_MODE_TRUE_PEAKS
))
357 inlink
->min_samples
=
358 inlink
->max_samples
=
359 inlink
->partial_buf_size
= inlink
->sample_rate
/ 10;
363 static int config_audio_output(AVFilterLink
*outlink
)
366 AVFilterContext
*ctx
= outlink
->src
;
367 EBUR128Context
*ebur128
= ctx
->priv
;
368 const int nb_channels
= av_get_channel_layout_nb_channels(outlink
->channel_layout
);
370 #define BACK_MASK (AV_CH_BACK_LEFT |AV_CH_BACK_CENTER |AV_CH_BACK_RIGHT| \
371 AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_BACK_RIGHT| \
372 AV_CH_SIDE_LEFT |AV_CH_SIDE_RIGHT| \
373 AV_CH_SURROUND_DIRECT_LEFT |AV_CH_SURROUND_DIRECT_RIGHT)
375 ebur128
->nb_channels
= nb_channels
;
376 ebur128
->ch_weighting
= av_calloc(nb_channels
, sizeof(*ebur128
->ch_weighting
));
377 if (!ebur128
->ch_weighting
)
378 return AVERROR(ENOMEM
);
380 for (i
= 0; i
< nb_channels
; i
++) {
381 /* channel weighting */
382 const uint16_t chl
= av_channel_layout_extract_channel(outlink
->channel_layout
, i
);
383 if (chl
& (AV_CH_LOW_FREQUENCY
|AV_CH_LOW_FREQUENCY_2
)) {
384 ebur128
->ch_weighting
[i
] = 0;
385 } else if (chl
& BACK_MASK
) {
386 ebur128
->ch_weighting
[i
] = 1.41;
388 ebur128
->ch_weighting
[i
] = 1.0;
391 if (!ebur128
->ch_weighting
[i
])
394 /* bins buffer for the two integration window (400ms and 3s) */
395 ebur128
->i400
.cache
[i
] = av_calloc(I400_BINS
, sizeof(*ebur128
->i400
.cache
[0]));
396 ebur128
->i3000
.cache
[i
] = av_calloc(I3000_BINS
, sizeof(*ebur128
->i3000
.cache
[0]));
397 if (!ebur128
->i400
.cache
[i
] || !ebur128
->i3000
.cache
[i
])
398 return AVERROR(ENOMEM
);
401 outlink
->flags
|= FF_LINK_FLAG_REQUEST_LOOP
;
403 #if CONFIG_SWRESAMPLE
404 if (ebur128
->peak_mode
& PEAK_MODE_TRUE_PEAKS
) {
407 ebur128
->swr_buf
= av_malloc_array(nb_channels
, 19200 * sizeof(double));
408 ebur128
->true_peaks
= av_calloc(nb_channels
, sizeof(*ebur128
->true_peaks
));
409 ebur128
->true_peaks_per_frame
= av_calloc(nb_channels
, sizeof(*ebur128
->true_peaks_per_frame
));
410 ebur128
->swr_ctx
= swr_alloc();
411 if (!ebur128
->swr_buf
|| !ebur128
->true_peaks
||
412 !ebur128
->true_peaks_per_frame
|| !ebur128
->swr_ctx
)
413 return AVERROR(ENOMEM
);
415 av_opt_set_int(ebur128
->swr_ctx
, "in_channel_layout", outlink
->channel_layout
, 0);
416 av_opt_set_int(ebur128
->swr_ctx
, "in_sample_rate", outlink
->sample_rate
, 0);
417 av_opt_set_sample_fmt(ebur128
->swr_ctx
, "in_sample_fmt", outlink
->format
, 0);
419 av_opt_set_int(ebur128
->swr_ctx
, "out_channel_layout", outlink
->channel_layout
, 0);
420 av_opt_set_int(ebur128
->swr_ctx
, "out_sample_rate", 192000, 0);
421 av_opt_set_sample_fmt(ebur128
->swr_ctx
, "out_sample_fmt", outlink
->format
, 0);
423 ret
= swr_init(ebur128
->swr_ctx
);
429 if (ebur128
->peak_mode
& PEAK_MODE_SAMPLES_PEAKS
) {
430 ebur128
->sample_peaks
= av_calloc(nb_channels
, sizeof(*ebur128
->sample_peaks
));
431 if (!ebur128
->sample_peaks
)
432 return AVERROR(ENOMEM
);
438 #define ENERGY(loudness) (pow(10, ((loudness) + 0.691) / 10.))
439 #define LOUDNESS(energy) (-0.691 + 10 * log10(energy))
440 #define DBFS(energy) (20 * log10(energy))
442 static struct hist_entry
*get_histogram(void)
445 struct hist_entry
*h
= av_calloc(HIST_SIZE
, sizeof(*h
));
449 for (i
= 0; i
< HIST_SIZE
; i
++) {
450 h
[i
].loudness
= i
/ (double)HIST_GRAIN
+ ABS_THRES
;
451 h
[i
].energy
= ENERGY(h
[i
].loudness
);
456 static av_cold
int init(AVFilterContext
*ctx
)
458 EBUR128Context
*ebur128
= ctx
->priv
;
461 if (ebur128
->loglevel
!= AV_LOG_INFO
&&
462 ebur128
->loglevel
!= AV_LOG_VERBOSE
) {
463 if (ebur128
->do_video
|| ebur128
->metadata
)
464 ebur128
->loglevel
= AV_LOG_VERBOSE
;
466 ebur128
->loglevel
= AV_LOG_INFO
;
469 if (!CONFIG_SWRESAMPLE
&& (ebur128
->peak_mode
& PEAK_MODE_TRUE_PEAKS
)) {
470 av_log(ctx
, AV_LOG_ERROR
,
471 "True-peak mode requires libswresample to be performed\n");
472 return AVERROR(EINVAL
);
475 // if meter is +9 scale, scale range is from -18 LU to +9 LU (or 3*9)
476 // if meter is +18 scale, scale range is from -36 LU to +18 LU (or 3*18)
477 ebur128
->scale_range
= 3 * ebur128
->meter
;
479 ebur128
->i400
.histogram
= get_histogram();
480 ebur128
->i3000
.histogram
= get_histogram();
481 if (!ebur128
->i400
.histogram
|| !ebur128
->i3000
.histogram
)
482 return AVERROR(ENOMEM
);
484 ebur128
->integrated_loudness
= ABS_THRES
;
485 ebur128
->loudness_range
= 0;
487 /* insert output pads */
488 if (ebur128
->do_video
) {
490 .name
= av_strdup("out0"),
491 .type
= AVMEDIA_TYPE_VIDEO
,
492 .config_props
= config_video_output
,
495 return AVERROR(ENOMEM
);
496 ff_insert_outpad(ctx
, 0, &pad
);
499 .name
= av_asprintf("out%d", ebur128
->do_video
),
500 .type
= AVMEDIA_TYPE_AUDIO
,
501 .config_props
= config_audio_output
,
504 return AVERROR(ENOMEM
);
505 ff_insert_outpad(ctx
, ebur128
->do_video
, &pad
);
508 av_log(ctx
, AV_LOG_VERBOSE
, "EBU +%d scale\n", ebur128
->meter
);
513 #define HIST_POS(power) (int)(((power) - ABS_THRES) * HIST_GRAIN)
515 /* loudness and power should be set such as loudness = -0.691 +
516 * 10*log10(power), we just avoid doing that calculus two times */
517 static int gate_update(struct integrator
*integ
, double power
,
518 double loudness
, int gate_thres
)
521 double relative_threshold
;
524 /* update powers histograms by incrementing current power count */
525 ipower
= av_clip(HIST_POS(loudness
), 0, HIST_SIZE
- 1);
526 integ
->histogram
[ipower
].count
++;
528 /* compute relative threshold and get its position in the histogram */
529 integ
->sum_kept_powers
+= power
;
530 integ
->nb_kept_powers
++;
531 relative_threshold
= integ
->sum_kept_powers
/ integ
->nb_kept_powers
;
532 if (!relative_threshold
)
533 relative_threshold
= 1e-12;
534 integ
->rel_threshold
= LOUDNESS(relative_threshold
) + gate_thres
;
535 gate_hist_pos
= av_clip(HIST_POS(integ
->rel_threshold
), 0, HIST_SIZE
- 1);
537 return gate_hist_pos
;
540 static int filter_frame(AVFilterLink
*inlink
, AVFrame
*insamples
)
542 int i
, ch
, idx_insample
;
543 AVFilterContext
*ctx
= inlink
->dst
;
544 EBUR128Context
*ebur128
= ctx
->priv
;
545 const int nb_channels
= ebur128
->nb_channels
;
546 const int nb_samples
= insamples
->nb_samples
;
547 const double *samples
= (double *)insamples
->data
[0];
548 AVFrame
*pic
= ebur128
->outpicref
;
550 #if CONFIG_SWRESAMPLE
551 if (ebur128
->peak_mode
& PEAK_MODE_TRUE_PEAKS
) {
552 const double *swr_samples
= ebur128
->swr_buf
;
553 int ret
= swr_convert(ebur128
->swr_ctx
, (uint8_t**)&ebur128
->swr_buf
, 19200,
554 (const uint8_t **)insamples
->data
, nb_samples
);
557 for (ch
= 0; ch
< nb_channels
; ch
++)
558 ebur128
->true_peaks_per_frame
[ch
] = 0.0;
559 for (idx_insample
= 0; idx_insample
< ret
; idx_insample
++) {
560 for (ch
= 0; ch
< nb_channels
; ch
++) {
561 ebur128
->true_peaks
[ch
] = FFMAX(ebur128
->true_peaks
[ch
], FFABS(*swr_samples
));
562 ebur128
->true_peaks_per_frame
[ch
] = FFMAX(ebur128
->true_peaks_per_frame
[ch
],
563 FFABS(*swr_samples
));
570 for (idx_insample
= 0; idx_insample
< nb_samples
; idx_insample
++) {
571 const int bin_id_400
= ebur128
->i400
.cache_pos
;
572 const int bin_id_3000
= ebur128
->i3000
.cache_pos
;
574 #define MOVE_TO_NEXT_CACHED_ENTRY(time) do { \
575 ebur128->i##time.cache_pos++; \
576 if (ebur128->i##time.cache_pos == I##time##_BINS) { \
577 ebur128->i##time.filled = 1; \
578 ebur128->i##time.cache_pos = 0; \
582 MOVE_TO_NEXT_CACHED_ENTRY(400);
583 MOVE_TO_NEXT_CACHED_ENTRY(3000);
585 for (ch
= 0; ch
< nb_channels
; ch
++) {
588 if (ebur128
->peak_mode
& PEAK_MODE_SAMPLES_PEAKS
)
589 ebur128
->sample_peaks
[ch
] = FFMAX(ebur128
->sample_peaks
[ch
], FFABS(*samples
));
591 ebur128
->x
[ch
* 3] = *samples
++; // set X[i]
593 if (!ebur128
->ch_weighting
[ch
])
596 /* Y[i] = X[i]*b0 + X[i-1]*b1 + X[i-2]*b2 - Y[i-1]*a1 - Y[i-2]*a2 */
597 #define FILTER(Y, X, name) do { \
598 double *dst = ebur128->Y + ch*3; \
599 double *src = ebur128->X + ch*3; \
602 dst[0] = src[0]*name##_B0 + src[1]*name##_B1 + src[2]*name##_B2 \
603 - dst[1]*name##_A1 - dst[2]*name##_A2; \
606 // TODO: merge both filters in one?
607 FILTER(y
, x
, PRE
); // apply pre-filter
608 ebur128
->x
[ch
* 3 + 2] = ebur128
->x
[ch
* 3 + 1];
609 ebur128
->x
[ch
* 3 + 1] = ebur128
->x
[ch
* 3 ];
610 FILTER(z
, y
, RLB
); // apply RLB-filter
612 bin
= ebur128
->z
[ch
* 3] * ebur128
->z
[ch
* 3];
614 /* add the new value, and limit the sum to the cache size (400ms or 3s)
615 * by removing the oldest one */
616 ebur128
->i400
.sum
[ch
] = ebur128
->i400
.sum
[ch
] + bin
- ebur128
->i400
.cache
[ch
][bin_id_400
];
617 ebur128
->i3000
.sum
[ch
] = ebur128
->i3000
.sum
[ch
] + bin
- ebur128
->i3000
.cache
[ch
][bin_id_3000
];
619 /* override old cache entry with the new value */
620 ebur128
->i400
.cache
[ch
][bin_id_400
] = bin
;
621 ebur128
->i3000
.cache
[ch
][bin_id_3000
] = bin
;
624 /* For integrated loudness, gating blocks are 400ms long with 75%
625 * overlap (see BS.1770-2 p5), so a re-computation is needed each 100ms
626 * (4800 samples at 48kHz). */
627 if (++ebur128
->sample_count
== 4800) {
628 double loudness_400
, loudness_3000
;
629 double power_400
= 1e-12, power_3000
= 1e-12;
630 AVFilterLink
*outlink
= ctx
->outputs
[0];
631 const int64_t pts
= insamples
->pts
+
632 av_rescale_q(idx_insample
, (AVRational
){ 1, inlink
->sample_rate
},
635 ebur128
->sample_count
= 0;
637 #define COMPUTE_LOUDNESS(m, time) do { \
638 if (ebur128->i##time.filled) { \
639 /* weighting sum of the last <time> ms */ \
640 for (ch = 0; ch < nb_channels; ch++) \
641 power_##time += ebur128->ch_weighting[ch] * ebur128->i##time.sum[ch]; \
642 power_##time /= I##time##_BINS; \
644 loudness_##time = LOUDNESS(power_##time); \
647 COMPUTE_LOUDNESS(M
, 400);
648 COMPUTE_LOUDNESS(S
, 3000);
650 /* Integrated loudness */
651 #define I_GATE_THRES -10 // initially defined to -8 LU in the first EBU standard
653 if (loudness_400
>= ABS_THRES
) {
654 double integrated_sum
= 0;
655 int nb_integrated
= 0;
656 int gate_hist_pos
= gate_update(&ebur128
->i400
, power_400
,
657 loudness_400
, I_GATE_THRES
);
659 /* compute integrated loudness by summing the histogram values
660 * above the relative threshold */
661 for (i
= gate_hist_pos
; i
< HIST_SIZE
; i
++) {
662 const int nb_v
= ebur128
->i400
.histogram
[i
].count
;
663 nb_integrated
+= nb_v
;
664 integrated_sum
+= nb_v
* ebur128
->i400
.histogram
[i
].energy
;
667 ebur128
->integrated_loudness
= LOUDNESS(integrated_sum
/ nb_integrated
);
671 #define LRA_GATE_THRES -20
672 #define LRA_LOWER_PRC 10
673 #define LRA_HIGHER_PRC 95
675 /* XXX: example code in EBU 3342 is ">=" but formula in BS.1770
677 if (loudness_3000
>= ABS_THRES
) {
679 int gate_hist_pos
= gate_update(&ebur128
->i3000
, power_3000
,
680 loudness_3000
, LRA_GATE_THRES
);
682 for (i
= gate_hist_pos
; i
< HIST_SIZE
; i
++)
683 nb_powers
+= ebur128
->i3000
.histogram
[i
].count
;
687 /* get lower loudness to consider */
689 nb_pow
= LRA_LOWER_PRC
* nb_powers
/ 100. + 0.5;
690 for (i
= gate_hist_pos
; i
< HIST_SIZE
; i
++) {
691 n
+= ebur128
->i3000
.histogram
[i
].count
;
693 ebur128
->lra_low
= ebur128
->i3000
.histogram
[i
].loudness
;
698 /* get higher loudness to consider */
700 nb_pow
= LRA_HIGHER_PRC
* nb_powers
/ 100. + 0.5;
701 for (i
= HIST_SIZE
- 1; i
>= 0; i
--) {
702 n
-= ebur128
->i3000
.histogram
[i
].count
;
704 ebur128
->lra_high
= ebur128
->i3000
.histogram
[i
].loudness
;
709 // XXX: show low & high on the graph?
710 ebur128
->loudness_range
= ebur128
->lra_high
- ebur128
->lra_low
;
714 #define LOG_FMT "M:%6.1f S:%6.1f I:%6.1f LUFS LRA:%6.1f LU"
716 /* push one video frame */
717 if (ebur128
->do_video
) {
721 const int y_loudness_lu_graph
= lu_to_y(ebur128
, loudness_3000
+ 23);
722 const int y_loudness_lu_gauge
= lu_to_y(ebur128
, loudness_400
+ 23);
724 /* draw the graph using the short-term loudness */
725 p
= pic
->data
[0] + ebur128
->graph
.y
*pic
->linesize
[0] + ebur128
->graph
.x
*3;
726 for (y
= 0; y
< ebur128
->graph
.h
; y
++) {
727 const uint8_t *c
= get_graph_color(ebur128
, y_loudness_lu_graph
, y
);
729 memmove(p
, p
+ 3, (ebur128
->graph
.w
- 1) * 3);
730 memcpy(p
+ (ebur128
->graph
.w
- 1) * 3, c
, 3);
731 p
+= pic
->linesize
[0];
734 /* draw the gauge using the momentary loudness */
735 p
= pic
->data
[0] + ebur128
->gauge
.y
*pic
->linesize
[0] + ebur128
->gauge
.x
*3;
736 for (y
= 0; y
< ebur128
->gauge
.h
; y
++) {
737 const uint8_t *c
= get_graph_color(ebur128
, y_loudness_lu_gauge
, y
);
739 for (x
= 0; x
< ebur128
->gauge
.w
; x
++)
740 memcpy(p
+ x
*3, c
, 3);
741 p
+= pic
->linesize
[0];
744 /* draw textual info */
745 drawtext(pic
, PAD
, PAD
- PAD
/2, FONT16
, font_colors
,
746 LOG_FMT
" ", // padding to erase trailing characters
747 loudness_400
, loudness_3000
,
748 ebur128
->integrated_loudness
, ebur128
->loudness_range
);
750 /* set pts and push frame */
752 ret
= ff_filter_frame(outlink
, av_frame_clone(pic
));
757 if (ebur128
->metadata
) { /* happens only once per filter_frame call */
759 #define META_PREFIX "lavfi.r128."
761 #define SET_META(name, var) do { \
762 snprintf(metabuf, sizeof(metabuf), "%.3f", var); \
763 av_dict_set(&insamples->metadata, name, metabuf, 0); \
766 #define SET_META_PEAK(name, ptype) do { \
767 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
769 for (ch = 0; ch < nb_channels; ch++) { \
770 snprintf(key, sizeof(key), \
771 META_PREFIX AV_STRINGIFY(name) "_peaks_ch%d", ch); \
772 SET_META(key, ebur128->name##_peaks[ch]); \
777 SET_META(META_PREFIX
"M", loudness_400
);
778 SET_META(META_PREFIX
"S", loudness_3000
);
779 SET_META(META_PREFIX
"I", ebur128
->integrated_loudness
);
780 SET_META(META_PREFIX
"LRA", ebur128
->loudness_range
);
781 SET_META(META_PREFIX
"LRA.low", ebur128
->lra_low
);
782 SET_META(META_PREFIX
"LRA.high", ebur128
->lra_high
);
784 SET_META_PEAK(sample
, SAMPLES
);
785 SET_META_PEAK(true, TRUE
);
788 av_log(ctx
, ebur128
->loglevel
, "t: %-10s " LOG_FMT
,
789 av_ts2timestr(pts
, &outlink
->time_base
),
790 loudness_400
, loudness_3000
,
791 ebur128
->integrated_loudness
, ebur128
->loudness_range
);
793 #define PRINT_PEAKS(str, sp, ptype) do { \
794 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
795 av_log(ctx, ebur128->loglevel, " " str ":"); \
796 for (ch = 0; ch < nb_channels; ch++) \
797 av_log(ctx, ebur128->loglevel, " %5.1f", DBFS(sp[ch])); \
798 av_log(ctx, ebur128->loglevel, " dBFS"); \
802 PRINT_PEAKS("SPK", ebur128
->sample_peaks
, SAMPLES
);
803 PRINT_PEAKS("FTPK", ebur128
->true_peaks_per_frame
, TRUE
);
804 PRINT_PEAKS("TPK", ebur128
->true_peaks
, TRUE
);
805 av_log(ctx
, ebur128
->loglevel
, "\n");
809 return ff_filter_frame(ctx
->outputs
[ebur128
->do_video
], insamples
);
812 static int query_formats(AVFilterContext
*ctx
)
814 EBUR128Context
*ebur128
= ctx
->priv
;
815 AVFilterFormats
*formats
;
816 AVFilterChannelLayouts
*layouts
;
817 AVFilterLink
*inlink
= ctx
->inputs
[0];
818 AVFilterLink
*outlink
= ctx
->outputs
[0];
820 static const enum AVSampleFormat sample_fmts
[] = { AV_SAMPLE_FMT_DBL
, AV_SAMPLE_FMT_NONE
};
821 static const int input_srate
[] = {48000, -1}; // ITU-R BS.1770 provides coeff only for 48kHz
822 static const enum AVPixelFormat pix_fmts
[] = { AV_PIX_FMT_RGB24
, AV_PIX_FMT_NONE
};
824 /* set optional output video format */
825 if (ebur128
->do_video
) {
826 formats
= ff_make_format_list(pix_fmts
);
828 return AVERROR(ENOMEM
);
829 ff_formats_ref(formats
, &outlink
->in_formats
);
830 outlink
= ctx
->outputs
[1];
833 /* set input and output audio formats
834 * Note: ff_set_common_* functions are not used because they affect all the
835 * links, and thus break the video format negotiation */
836 formats
= ff_make_format_list(sample_fmts
);
838 return AVERROR(ENOMEM
);
839 ff_formats_ref(formats
, &inlink
->out_formats
);
840 ff_formats_ref(formats
, &outlink
->in_formats
);
842 layouts
= ff_all_channel_layouts();
844 return AVERROR(ENOMEM
);
845 ff_channel_layouts_ref(layouts
, &inlink
->out_channel_layouts
);
846 ff_channel_layouts_ref(layouts
, &outlink
->in_channel_layouts
);
848 formats
= ff_make_format_list(input_srate
);
850 return AVERROR(ENOMEM
);
851 ff_formats_ref(formats
, &inlink
->out_samplerates
);
852 ff_formats_ref(formats
, &outlink
->in_samplerates
);
857 static av_cold
void uninit(AVFilterContext
*ctx
)
860 EBUR128Context
*ebur128
= ctx
->priv
;
862 av_log(ctx
, AV_LOG_INFO
, "Summary:\n\n"
863 " Integrated loudness:\n"
865 " Threshold: %5.1f LUFS\n\n"
868 " Threshold: %5.1f LUFS\n"
869 " LRA low: %5.1f LUFS\n"
870 " LRA high: %5.1f LUFS",
871 ebur128
->integrated_loudness
, ebur128
->i400
.rel_threshold
,
872 ebur128
->loudness_range
, ebur128
->i3000
.rel_threshold
,
873 ebur128
->lra_low
, ebur128
->lra_high
);
875 #define PRINT_PEAK_SUMMARY(str, sp, ptype) do { \
879 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
880 for (ch = 0; ch < ebur128->nb_channels; ch++) \
881 maxpeak = FFMAX(maxpeak, sp[ch]); \
882 av_log(ctx, AV_LOG_INFO, "\n\n " str " peak:\n" \
883 " Peak: %5.1f dBFS", \
888 PRINT_PEAK_SUMMARY("Sample", ebur128
->sample_peaks
, SAMPLES
);
889 PRINT_PEAK_SUMMARY("True", ebur128
->true_peaks
, TRUE
);
890 av_log(ctx
, AV_LOG_INFO
, "\n");
892 av_freep(&ebur128
->y_line_ref
);
893 av_freep(&ebur128
->ch_weighting
);
894 av_freep(&ebur128
->true_peaks
);
895 av_freep(&ebur128
->sample_peaks
);
896 av_freep(&ebur128
->true_peaks_per_frame
);
897 av_freep(&ebur128
->i400
.histogram
);
898 av_freep(&ebur128
->i3000
.histogram
);
899 for (i
= 0; i
< ebur128
->nb_channels
; i
++) {
900 av_freep(&ebur128
->i400
.cache
[i
]);
901 av_freep(&ebur128
->i3000
.cache
[i
]);
903 for (i
= 0; i
< ctx
->nb_outputs
; i
++)
904 av_freep(&ctx
->output_pads
[i
].name
);
905 av_frame_free(&ebur128
->outpicref
);
906 #if CONFIG_SWRESAMPLE
907 av_freep(&ebur128
->swr_buf
);
908 swr_free(&ebur128
->swr_ctx
);
912 static const AVFilterPad ebur128_inputs
[] = {
915 .type
= AVMEDIA_TYPE_AUDIO
,
916 .filter_frame
= filter_frame
,
917 .config_props
= config_audio_input
,
922 AVFilter ff_af_ebur128
= {
924 .description
= NULL_IF_CONFIG_SMALL("EBU R128 scanner."),
925 .priv_size
= sizeof(EBUR128Context
),
928 .query_formats
= query_formats
,
929 .inputs
= ebur128_inputs
,
931 .priv_class
= &ebur128_class
,
932 .flags
= AVFILTER_FLAG_DYNAMIC_OUTPUTS
,