Commit 005d058f authored by Marton Balint's avatar Marton Balint

lavfi/loudnorm: add an internal libebur128 library

Also contains the following changes to the library:
- add ff_ prefix to functions
- remove cplusplus defines.
- add FF_ prefix to contants and some structs
- remove true peak calculation feature, since it uses its own resampler, and
  af_loudnorm does not need it.
- remove version info and some fprintf(stderr) functions
- convert to use av_malloc
- always use histogram mode for LRA calculation, otherwise LRA data is slowly
  consuming memory making af_loudnorm unfit for 24/7 operation. It also uses a
  BSD style linked list implementation which is probably not available on all
  platforms. So let's just remove the classic mode which not uses histogram.
- add ff_thread_once for calculating static histogram tables
- convert some functions to void which cannot fail
- remove intrinsics and some unused headers
- add support for planar audio
- remove channel / sample rate changer function, in ffmpeg usually we simply
  alloc a new context
- convert some static variables to defines
- declare static histogram variables as aligned
- convert some initalizations to mallocz
- add window size parameter to init function and remove window size setter
  function
- convert return codes to AVERROR
- fix indentation
Signed-off-by: 's avatarMarton Balint <cus@passwd.hu>
parent 7b8445f0
...@@ -3,6 +3,7 @@ releases are sorted from youngest to oldest. ...@@ -3,6 +3,7 @@ releases are sorted from youngest to oldest.
version <next>: version <next>:
- CrystalHD decoder moved to new decode API - CrystalHD decoder moved to new decode API
- add internal ebur128 library, remove external libebur128 dependency
version 3.2: version 3.2:
- libopenmpt demuxer - libopenmpt demuxer
......
...@@ -222,8 +222,6 @@ External library support: ...@@ -222,8 +222,6 @@ External library support:
--enable-libcdio enable audio CD grabbing with libcdio [no] --enable-libcdio enable audio CD grabbing with libcdio [no]
--enable-libdc1394 enable IIDC-1394 grabbing using libdc1394 --enable-libdc1394 enable IIDC-1394 grabbing using libdc1394
and libraw1394 [no] and libraw1394 [no]
--enable-libebur128 enable libebur128 for EBU R128 measurement,
needed for loudnorm filter [no]
--enable-libfdk-aac enable AAC de/encoding via libfdk-aac [no] --enable-libfdk-aac enable AAC de/encoding via libfdk-aac [no]
--enable-libflite enable flite (voice synthesis) support via libflite [no] --enable-libflite enable flite (voice synthesis) support via libflite [no]
--enable-libfontconfig enable libfontconfig, useful for drawtext filter [no] --enable-libfontconfig enable libfontconfig, useful for drawtext filter [no]
...@@ -1491,7 +1489,6 @@ EXTERNAL_LIBRARY_LIST=" ...@@ -1491,7 +1489,6 @@ EXTERNAL_LIBRARY_LIST="
libcdio libcdio
libcelt libcelt
libdc1394 libdc1394
libebur128
libfdk_aac libfdk_aac
libflite libflite
libfontconfig libfontconfig
...@@ -3052,7 +3049,6 @@ hqdn3d_filter_deps="gpl" ...@@ -3052,7 +3049,6 @@ hqdn3d_filter_deps="gpl"
interlace_filter_deps="gpl" interlace_filter_deps="gpl"
kerndeint_filter_deps="gpl" kerndeint_filter_deps="gpl"
ladspa_filter_deps="ladspa dlopen" ladspa_filter_deps="ladspa dlopen"
loudnorm_filter_deps="libebur128"
mcdeint_filter_deps="avcodec gpl" mcdeint_filter_deps="avcodec gpl"
movie_filter_deps="avcodec avformat" movie_filter_deps="avcodec avformat"
mpdecimate_filter_deps="gpl" mpdecimate_filter_deps="gpl"
...@@ -5689,7 +5685,6 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && ...@@ -5689,7 +5685,6 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 &&
{ check_lib celt/celt.h celt_decoder_create_custom -lcelt0 || { check_lib celt/celt.h celt_decoder_create_custom -lcelt0 ||
die "ERROR: libcelt must be installed and version must be >= 0.11.0."; } die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
enabled libcaca && require_pkg_config caca caca.h caca_create_canvas enabled libcaca && require_pkg_config caca caca.h caca_create_canvas
enabled libebur128 && require ebur128 ebur128.h ebur128_relative_threshold -lebur128
enabled libfdk_aac && { use_pkg_config fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen || enabled libfdk_aac && { use_pkg_config fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen ||
{ require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac && { require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac &&
warn "using libfdk without pkg-config"; } } warn "using libfdk without pkg-config"; } }
......
...@@ -2921,9 +2921,6 @@ EBU R128 loudness normalization. Includes both dynamic and linear normalization ...@@ -2921,9 +2921,6 @@ EBU R128 loudness normalization. Includes both dynamic and linear normalization
Support for both single pass (livestreams, files) and double pass (files) modes. Support for both single pass (livestreams, files) and double pass (files) modes.
This algorithm can target IL, LRA, and maximum true peak. This algorithm can target IL, LRA, and maximum true peak.
To enable compilation of this filter you need to configure FFmpeg with
@code{--enable-libebur128}.
The filter accepts the following options: The filter accepts the following options:
@table @option @table @option
......
...@@ -93,7 +93,7 @@ OBJS-$(CONFIG_HDCD_FILTER) += af_hdcd.o ...@@ -93,7 +93,7 @@ OBJS-$(CONFIG_HDCD_FILTER) += af_hdcd.o
OBJS-$(CONFIG_HIGHPASS_FILTER) += af_biquads.o OBJS-$(CONFIG_HIGHPASS_FILTER) += af_biquads.o
OBJS-$(CONFIG_JOIN_FILTER) += af_join.o OBJS-$(CONFIG_JOIN_FILTER) += af_join.o
OBJS-$(CONFIG_LADSPA_FILTER) += af_ladspa.o OBJS-$(CONFIG_LADSPA_FILTER) += af_ladspa.o
OBJS-$(CONFIG_LOUDNORM_FILTER) += af_loudnorm.o OBJS-$(CONFIG_LOUDNORM_FILTER) += af_loudnorm.o ebur128.o
OBJS-$(CONFIG_LOWPASS_FILTER) += af_biquads.o OBJS-$(CONFIG_LOWPASS_FILTER) += af_biquads.o
OBJS-$(CONFIG_PAN_FILTER) += af_pan.o OBJS-$(CONFIG_PAN_FILTER) += af_pan.o
OBJS-$(CONFIG_REPLAYGAIN_FILTER) += af_replaygain.o OBJS-$(CONFIG_REPLAYGAIN_FILTER) += af_replaygain.o
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "avfilter.h" #include "avfilter.h"
#include "internal.h" #include "internal.h"
#include "audio.h" #include "audio.h"
#include <ebur128.h> #include "ebur128.h"
enum FrameType { enum FrameType {
FIRST_FRAME, FIRST_FRAME,
...@@ -91,8 +91,8 @@ typedef struct LoudNormContext { ...@@ -91,8 +91,8 @@ typedef struct LoudNormContext {
int prev_nb_samples; int prev_nb_samples;
int channels; int channels;
ebur128_state *r128_in; FFEBUR128State *r128_in;
ebur128_state *r128_out; FFEBUR128State *r128_out;
} LoudNormContext; } LoudNormContext;
#define OFFSET(x) offsetof(LoudNormContext, x) #define OFFSET(x) offsetof(LoudNormContext, x)
...@@ -437,15 +437,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ...@@ -437,15 +437,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
buf = s->buf; buf = s->buf;
limiter_buf = s->limiter_buf; limiter_buf = s->limiter_buf;
ebur128_add_frames_double(s->r128_in, src, in->nb_samples); ff_ebur128_add_frames_double(s->r128_in, src, in->nb_samples);
if (s->frame_type == FIRST_FRAME && in->nb_samples < frame_size(inlink->sample_rate, 3000)) { if (s->frame_type == FIRST_FRAME && in->nb_samples < frame_size(inlink->sample_rate, 3000)) {
double offset, offset_tp, true_peak; double offset, offset_tp, true_peak;
ebur128_loudness_global(s->r128_in, &global); ff_ebur128_loudness_global(s->r128_in, &global);
for (c = 0; c < inlink->channels; c++) { for (c = 0; c < inlink->channels; c++) {
double tmp; double tmp;
ebur128_sample_peak(s->r128_in, c, &tmp); ff_ebur128_sample_peak(s->r128_in, c, &tmp);
if (c == 0 || tmp > true_peak) if (c == 0 || tmp > true_peak)
true_peak = tmp; true_peak = tmp;
} }
...@@ -467,7 +467,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ...@@ -467,7 +467,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
s->buf_index += inlink->channels; s->buf_index += inlink->channels;
} }
ebur128_loudness_shortterm(s->r128_in, &shortterm); ff_ebur128_loudness_shortterm(s->r128_in, &shortterm);
if (shortterm < s->measured_thresh) { if (shortterm < s->measured_thresh) {
s->above_threshold = 0; s->above_threshold = 0;
...@@ -497,7 +497,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ...@@ -497,7 +497,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
subframe_length = frame_size(inlink->sample_rate, 100); subframe_length = frame_size(inlink->sample_rate, 100);
true_peak_limiter(s, dst, subframe_length, inlink->channels); true_peak_limiter(s, dst, subframe_length, inlink->channels);
ebur128_add_frames_double(s->r128_out, dst, subframe_length); ff_ebur128_add_frames_double(s->r128_out, dst, subframe_length);
s->pts += s->pts +=
out->nb_samples = out->nb_samples =
...@@ -536,12 +536,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ...@@ -536,12 +536,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
s->limiter_buf_index = s->limiter_buf_index + subframe_length < s->limiter_buf_size ? s->limiter_buf_index + subframe_length : s->limiter_buf_index + subframe_length - s->limiter_buf_size; s->limiter_buf_index = s->limiter_buf_index + subframe_length < s->limiter_buf_size ? s->limiter_buf_index + subframe_length : s->limiter_buf_index + subframe_length - s->limiter_buf_size;
true_peak_limiter(s, dst, in->nb_samples, inlink->channels); true_peak_limiter(s, dst, in->nb_samples, inlink->channels);
ebur128_add_frames_double(s->r128_out, dst, in->nb_samples); ff_ebur128_add_frames_double(s->r128_out, dst, in->nb_samples);
ebur128_loudness_range(s->r128_in, &lra); ff_ebur128_loudness_range(s->r128_in, &lra);
ebur128_loudness_global(s->r128_in, &global); ff_ebur128_loudness_global(s->r128_in, &global);
ebur128_loudness_shortterm(s->r128_in, &shortterm); ff_ebur128_loudness_shortterm(s->r128_in, &shortterm);
ebur128_relative_threshold(s->r128_in, &relative_threshold); ff_ebur128_relative_threshold(s->r128_in, &relative_threshold);
if (s->above_threshold == 0) { if (s->above_threshold == 0) {
double shortterm_out; double shortterm_out;
...@@ -549,7 +549,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ...@@ -549,7 +549,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
if (shortterm > s->measured_thresh) if (shortterm > s->measured_thresh)
s->prev_delta *= 1.0058; s->prev_delta *= 1.0058;
ebur128_loudness_shortterm(s->r128_out, &shortterm_out); ff_ebur128_loudness_shortterm(s->r128_out, &shortterm_out);
if (shortterm_out >= s->target_i) if (shortterm_out >= s->target_i)
s->above_threshold = 1; s->above_threshold = 1;
} }
...@@ -611,7 +611,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ...@@ -611,7 +611,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
} }
dst = (double *)out->data[0]; dst = (double *)out->data[0];
ebur128_add_frames_double(s->r128_out, dst, in->nb_samples); ff_ebur128_add_frames_double(s->r128_out, dst, in->nb_samples);
break; break;
case LINEAR_MODE: case LINEAR_MODE:
...@@ -624,7 +624,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ...@@ -624,7 +624,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
} }
dst = (double *)out->data[0]; dst = (double *)out->data[0];
ebur128_add_frames_double(s->r128_out, dst, in->nb_samples); ff_ebur128_add_frames_double(s->r128_out, dst, in->nb_samples);
s->pts += in->nb_samples; s->pts += in->nb_samples;
break; break;
} }
...@@ -725,17 +725,17 @@ static int config_input(AVFilterLink *inlink) ...@@ -725,17 +725,17 @@ static int config_input(AVFilterLink *inlink)
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
LoudNormContext *s = ctx->priv; LoudNormContext *s = ctx->priv;
s->r128_in = ebur128_init(inlink->channels, inlink->sample_rate, EBUR128_MODE_I | EBUR128_MODE_S | EBUR128_MODE_LRA | EBUR128_MODE_SAMPLE_PEAK); s->r128_in = ff_ebur128_init(inlink->channels, inlink->sample_rate, 0, FF_EBUR128_MODE_I | FF_EBUR128_MODE_S | FF_EBUR128_MODE_LRA | FF_EBUR128_MODE_SAMPLE_PEAK);
if (!s->r128_in) if (!s->r128_in)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
s->r128_out = ebur128_init(inlink->channels, inlink->sample_rate, EBUR128_MODE_I | EBUR128_MODE_S | EBUR128_MODE_LRA | EBUR128_MODE_SAMPLE_PEAK); s->r128_out = ff_ebur128_init(inlink->channels, inlink->sample_rate, 0, FF_EBUR128_MODE_I | FF_EBUR128_MODE_S | FF_EBUR128_MODE_LRA | FF_EBUR128_MODE_SAMPLE_PEAK);
if (!s->r128_out) if (!s->r128_out)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
if (inlink->channels == 1 && s->dual_mono) { if (inlink->channels == 1 && s->dual_mono) {
ebur128_set_channel(s->r128_in, 0, EBUR128_DUAL_MONO); ff_ebur128_set_channel(s->r128_in, 0, FF_EBUR128_DUAL_MONO);
ebur128_set_channel(s->r128_out, 0, EBUR128_DUAL_MONO); ff_ebur128_set_channel(s->r128_out, 0, FF_EBUR128_DUAL_MONO);
} }
s->buf_size = frame_size(inlink->sample_rate, 3000) * inlink->channels; s->buf_size = frame_size(inlink->sample_rate, 3000) * inlink->channels;
...@@ -799,22 +799,22 @@ static av_cold void uninit(AVFilterContext *ctx) ...@@ -799,22 +799,22 @@ static av_cold void uninit(AVFilterContext *ctx)
if (!s->r128_in || !s->r128_out) if (!s->r128_in || !s->r128_out)
goto end; goto end;
ebur128_loudness_range(s->r128_in, &lra_in); ff_ebur128_loudness_range(s->r128_in, &lra_in);
ebur128_loudness_global(s->r128_in, &i_in); ff_ebur128_loudness_global(s->r128_in, &i_in);
ebur128_relative_threshold(s->r128_in, &thresh_in); ff_ebur128_relative_threshold(s->r128_in, &thresh_in);
for (c = 0; c < s->channels; c++) { for (c = 0; c < s->channels; c++) {
double tmp; double tmp;
ebur128_sample_peak(s->r128_in, c, &tmp); ff_ebur128_sample_peak(s->r128_in, c, &tmp);
if ((c == 0) || (tmp > tp_in)) if ((c == 0) || (tmp > tp_in))
tp_in = tmp; tp_in = tmp;
} }
ebur128_loudness_range(s->r128_out, &lra_out); ff_ebur128_loudness_range(s->r128_out, &lra_out);
ebur128_loudness_global(s->r128_out, &i_out); ff_ebur128_loudness_global(s->r128_out, &i_out);
ebur128_relative_threshold(s->r128_out, &thresh_out); ff_ebur128_relative_threshold(s->r128_out, &thresh_out);
for (c = 0; c < s->channels; c++) { for (c = 0; c < s->channels; c++) {
double tmp; double tmp;
ebur128_sample_peak(s->r128_out, c, &tmp); ff_ebur128_sample_peak(s->r128_out, c, &tmp);
if ((c == 0) || (tmp > tp_out)) if ((c == 0) || (tmp > tp_out))
tp_out = tmp; tp_out = tmp;
} }
...@@ -881,9 +881,9 @@ static av_cold void uninit(AVFilterContext *ctx) ...@@ -881,9 +881,9 @@ static av_cold void uninit(AVFilterContext *ctx)
end: end:
if (s->r128_in) if (s->r128_in)
ebur128_destroy(&s->r128_in); ff_ebur128_destroy(&s->r128_in);
if (s->r128_out) if (s->r128_out)
ebur128_destroy(&s->r128_out); ff_ebur128_destroy(&s->r128_out);
av_freep(&s->limiter_buf); av_freep(&s->limiter_buf);
av_freep(&s->prev_smp); av_freep(&s->prev_smp);
av_freep(&s->buf); av_freep(&s->buf);
......
This diff is collapsed.
This diff is collapsed.
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include "libavutil/version.h" #include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 6 #define LIBAVFILTER_VERSION_MAJOR 6
#define LIBAVFILTER_VERSION_MINOR 66 #define LIBAVFILTER_VERSION_MINOR 67
#define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
......
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