Commit d445bcb1 authored by Daniel Molkentin's avatar Daniel Molkentin Committed by Paul B Mahol

libavfilter/ebur128: introduce target range

This eases meeting the target level during live mixing.
Signed-off-by: 's avatarDaniel Molkentin <daniel@molkentin.de>
Signed-off-by: 's avatarConrad Zelck <c.zelck@imail.de>
parent d5873909
...@@ -19284,6 +19284,9 @@ short-term loudness (3 seconds of analysis), and the gauge on the right is for ...@@ -19284,6 +19284,9 @@ short-term loudness (3 seconds of analysis), and the gauge on the right is for
the momentary loudness (400 milliseconds), but can optionally be configured the momentary loudness (400 milliseconds), but can optionally be configured
to instead display short-term loudness (see @var{gauge}). to instead display short-term loudness (see @var{gauge}).
The green area marks a +/- 1LU target range around the target loudness
(-23LUFS by default, unless modified through @var{target}).
More information about the Loudness Recommendation EBU R128 on More information about the Loudness Recommendation EBU R128 on
@url{http://tech.ebu.ch/loudness}. @url{http://tech.ebu.ch/loudness}.
......
...@@ -114,6 +114,8 @@ typedef struct EBUR128Context { ...@@ -114,6 +114,8 @@ typedef struct EBUR128Context {
int meter; ///< select a EBU mode between +9 and +18 int meter; ///< select a EBU mode between +9 and +18
int scale_range; ///< the range of LU values according to the meter int scale_range; ///< the range of LU values according to the meter
int y_zero_lu; ///< the y value (pixel position) for 0 LU int y_zero_lu; ///< the y value (pixel position) for 0 LU
int y_opt_max; ///< the y value (pixel position) for 1 LU
int y_opt_min; ///< the y value (pixel position) for -1 LU
int *y_line_ref; ///< y reference values for drawing the LU lines in the graph and the gauge int *y_line_ref; ///< y reference values for drawing the LU lines in the graph and the gauge
/* audio */ /* audio */
...@@ -188,22 +190,31 @@ static const AVOption ebur128_options[] = { ...@@ -188,22 +190,31 @@ static const AVOption ebur128_options[] = {
AVFILTER_DEFINE_CLASS(ebur128); AVFILTER_DEFINE_CLASS(ebur128);
static const uint8_t graph_colors[] = { static const uint8_t graph_colors[] = {
0xdd, 0x66, 0x66, // value above 0LU non reached 0xdd, 0x66, 0x66, // value above 1LU non reached below -1LU (impossible)
0x66, 0x66, 0xdd, // value below 0LU non reached 0x66, 0x66, 0xdd, // value below 1LU non reached below -1LU
0x96, 0x33, 0x33, // value above 0LU reached 0x96, 0x33, 0x33, // value above 1LU reached below -1LU (impossible)
0x33, 0x33, 0x96, // value below 0LU reached 0x33, 0x33, 0x96, // value below 1LU reached below -1LU
0xdd, 0x96, 0x96, // value above 0LU line non reached 0xdd, 0x96, 0x96, // value above 1LU line non reached below -1LU (impossible)
0x96, 0x96, 0xdd, // value below 0LU line non reached 0x96, 0x96, 0xdd, // value below 1LU line non reached below -1LU
0xdd, 0x33, 0x33, // value above 0LU line reached 0xdd, 0x33, 0x33, // value above 1LU line reached below -1LU (impossible)
0x33, 0x33, 0xdd, // value below 0LU line reached 0x33, 0x33, 0xdd, // value below 1LU line reached below -1LU
0xdd, 0x66, 0x66, // value above 1LU non reached above -1LU
0x66, 0xdd, 0x66, // value below 1LU non reached above -1LU
0x96, 0x33, 0x33, // value above 1LU reached above -1LU
0x33, 0x96, 0x33, // value below 1LU reached above -1LU
0xdd, 0x96, 0x96, // value above 1LU line non reached above -1LU
0x96, 0xdd, 0x96, // value below 1LU line non reached above -1LU
0xdd, 0x33, 0x33, // value above 1LU line reached above -1LU
0x33, 0xdd, 0x33, // value below 1LU line reached above -1LU
}; };
static const uint8_t *get_graph_color(const EBUR128Context *ebur128, int v, int y) static const uint8_t *get_graph_color(const EBUR128Context *ebur128, int v, int y)
{ {
const int below0 = y > ebur128->y_zero_lu; const int above_opt_max = y > ebur128->y_opt_max;
const int below_opt_min = y < ebur128->y_opt_min;
const int reached = y >= v; const int reached = y >= v;
const int line = ebur128->y_line_ref[y] || y == ebur128->y_zero_lu; const int line = ebur128->y_line_ref[y] || y == ebur128->y_zero_lu;
const int colorid = 4*line + 2*reached + below0; const int colorid = 8*below_opt_min+ 4*line + 2*reached + above_opt_max;
return graph_colors + 3*colorid; return graph_colors + 3*colorid;
} }
...@@ -337,6 +348,8 @@ static int config_video_output(AVFilterLink *outlink) ...@@ -337,6 +348,8 @@ static int config_video_output(AVFilterLink *outlink)
/* draw graph */ /* draw graph */
ebur128->y_zero_lu = lu_to_y(ebur128, 0); ebur128->y_zero_lu = lu_to_y(ebur128, 0);
ebur128->y_opt_max = lu_to_y(ebur128, 1);
ebur128->y_opt_min = lu_to_y(ebur128, -1);
p = outpicref->data[0] + ebur128->graph.y * outpicref->linesize[0] p = outpicref->data[0] + ebur128->graph.y * outpicref->linesize[0]
+ ebur128->graph.x * 3; + ebur128->graph.x * 3;
for (y = 0; y < ebur128->graph.h; y++) { for (y = 0; y < ebur128->graph.h; y++) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment