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.
version <next>:
- CrystalHD decoder moved to new decode API
- add internal ebur128 library, remove external libebur128 dependency
version 3.2:
- libopenmpt demuxer
......
......@@ -222,8 +222,6 @@ External library support:
--enable-libcdio enable audio CD grabbing with libcdio [no]
--enable-libdc1394 enable IIDC-1394 grabbing using libdc1394
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-libflite enable flite (voice synthesis) support via libflite [no]
--enable-libfontconfig enable libfontconfig, useful for drawtext filter [no]
......@@ -1491,7 +1489,6 @@ EXTERNAL_LIBRARY_LIST="
libcdio
libcelt
libdc1394
libebur128
libfdk_aac
libflite
libfontconfig
......@@ -3052,7 +3049,6 @@ hqdn3d_filter_deps="gpl"
interlace_filter_deps="gpl"
kerndeint_filter_deps="gpl"
ladspa_filter_deps="ladspa dlopen"
loudnorm_filter_deps="libebur128"
mcdeint_filter_deps="avcodec gpl"
movie_filter_deps="avcodec avformat"
mpdecimate_filter_deps="gpl"
......@@ -5689,7 +5685,6 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 &&
{ check_lib celt/celt.h celt_decoder_create_custom -lcelt0 ||
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 libebur128 && require ebur128 ebur128.h ebur128_relative_threshold -lebur128
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 &&
warn "using libfdk without pkg-config"; } }
......
......@@ -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.
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:
@table @option
......
......@@ -93,7 +93,7 @@ OBJS-$(CONFIG_HDCD_FILTER) += af_hdcd.o
OBJS-$(CONFIG_HIGHPASS_FILTER) += af_biquads.o
OBJS-$(CONFIG_JOIN_FILTER) += af_join.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_PAN_FILTER) += af_pan.o
OBJS-$(CONFIG_REPLAYGAIN_FILTER) += af_replaygain.o
......
......@@ -24,7 +24,7 @@
#include "avfilter.h"
#include "internal.h"
#include "audio.h"
#include <ebur128.h>
#include "ebur128.h"
enum FrameType {
FIRST_FRAME,
......@@ -91,8 +91,8 @@ typedef struct LoudNormContext {
int prev_nb_samples;
int channels;
ebur128_state *r128_in;
ebur128_state *r128_out;
FFEBUR128State *r128_in;
FFEBUR128State *r128_out;
} LoudNormContext;
#define OFFSET(x) offsetof(LoudNormContext, x)
......@@ -437,15 +437,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
buf = s->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)) {
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++) {
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)
true_peak = tmp;
}
......@@ -467,7 +467,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
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) {
s->above_threshold = 0;
......@@ -497,7 +497,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
subframe_length = frame_size(inlink->sample_rate, 100);
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 +=
out->nb_samples =
......@@ -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;
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);
ebur128_loudness_global(s->r128_in, &global);
ebur128_loudness_shortterm(s->r128_in, &shortterm);
ebur128_relative_threshold(s->r128_in, &relative_threshold);
ff_ebur128_loudness_range(s->r128_in, &lra);
ff_ebur128_loudness_global(s->r128_in, &global);
ff_ebur128_loudness_shortterm(s->r128_in, &shortterm);
ff_ebur128_relative_threshold(s->r128_in, &relative_threshold);
if (s->above_threshold == 0) {
double shortterm_out;
......@@ -549,7 +549,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
if (shortterm > s->measured_thresh)
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)
s->above_threshold = 1;
}
......@@ -611,7 +611,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
}
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;
case LINEAR_MODE:
......@@ -624,7 +624,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
}
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;
break;
}
......@@ -725,17 +725,17 @@ static int config_input(AVFilterLink *inlink)
AVFilterContext *ctx = inlink->dst;
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)
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)
return AVERROR(ENOMEM);
if (inlink->channels == 1 && s->dual_mono) {
ebur128_set_channel(s->r128_in, 0, EBUR128_DUAL_MONO);
ebur128_set_channel(s->r128_out, 0, EBUR128_DUAL_MONO);
ff_ebur128_set_channel(s->r128_in, 0, FF_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;
......@@ -799,22 +799,22 @@ static av_cold void uninit(AVFilterContext *ctx)
if (!s->r128_in || !s->r128_out)
goto end;
ebur128_loudness_range(s->r128_in, &lra_in);
ebur128_loudness_global(s->r128_in, &i_in);
ebur128_relative_threshold(s->r128_in, &thresh_in);
ff_ebur128_loudness_range(s->r128_in, &lra_in);
ff_ebur128_loudness_global(s->r128_in, &i_in);
ff_ebur128_relative_threshold(s->r128_in, &thresh_in);
for (c = 0; c < s->channels; c++) {
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))
tp_in = tmp;
}
ebur128_loudness_range(s->r128_out, &lra_out);
ebur128_loudness_global(s->r128_out, &i_out);
ebur128_relative_threshold(s->r128_out, &thresh_out);
ff_ebur128_loudness_range(s->r128_out, &lra_out);
ff_ebur128_loudness_global(s->r128_out, &i_out);
ff_ebur128_relative_threshold(s->r128_out, &thresh_out);
for (c = 0; c < s->channels; c++) {
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))
tp_out = tmp;
}
......@@ -881,9 +881,9 @@ static av_cold void uninit(AVFilterContext *ctx)
end:
if (s->r128_in)
ebur128_destroy(&s->r128_in);
ff_ebur128_destroy(&s->r128_in);
if (s->r128_out)
ebur128_destroy(&s->r128_out);
ff_ebur128_destroy(&s->r128_out);
av_freep(&s->limiter_buf);
av_freep(&s->prev_smp);
av_freep(&s->buf);
......
This diff is collapsed.
This diff is collapsed.
......@@ -30,7 +30,7 @@
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 6
#define LIBAVFILTER_VERSION_MINOR 66
#define LIBAVFILTER_VERSION_MINOR 67
#define LIBAVFILTER_VERSION_MICRO 100
#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