98 #define OFFSET(x) offsetof(LoudNormContext, x) 99 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM 129 const int frame_size =
round((
double)sample_rate * (frame_len_msec / 1000.0));
130 return frame_size + (frame_size % 2);
135 double total_weight = 0.0;
136 const double sigma = 3.5;
140 const int offset = 21 / 2;
141 const double c1 = 1.0 / (sigma * sqrt(2.0 *
M_PI));
142 const double c2 = 2.0 * pow(sigma, 2.0);
144 for (i = 0; i < 21; i++) {
146 s->
weights[i] = c1 *
exp(-(pow(x, 2.0) / c2));
150 adjust = 1.0 / total_weight;
151 for (i = 0; i < 21; i++)
160 index = index - 10 > 0 ? index - 10 : index + 20;
161 for (i = 0; i < 21; i++)
162 result += s->
delta[((index + i) < 30) ? (index + i) : (index + i - 30)] * s->
weights[i];
183 s->
prev_smp[c] = fabs(buf[index + c - channels]);
186 for (n = 0; n < nb_samples; n++) {
188 double this, next, max_peak;
193 if ((s->
prev_smp[c] <=
this) && (next <=
this) && (
this > ceiling) && (n > 0)) {
197 for (i = 2; i < 12; i++) {
209 if (c == 0 || fabs(buf[index + c]) > max_peak)
210 max_peak = fabs(buf[index + c]);
217 *peak_value = max_peak;
232 int n,
c,
index, peak_delta, smp_cnt;
233 double ceiling, peak_value;
245 for (n = 0; n < 1920; n++) {
247 max = fabs(buf[c]) > max ? fabs(buf[c]) : max;
257 for (n = 0; n < 1920; n++) {
274 detect_peak(s, smp_cnt, nb_samples - smp_cnt, channels, &peak_delta, &peak_value);
275 if (peak_delta != -1) {
291 smp_cnt = nb_samples;
308 if (smp_cnt >= nb_samples) {
314 if (smp_cnt < nb_samples) {
322 detect_peak(s, smp_cnt, nb_samples, channels, &peak_delta, &peak_value);
323 if (peak_delta == -1) {
331 gain_reduction = ceiling / peak_value;
333 if (gain_reduction < s->gain_reduction[1]) {
358 if (smp_cnt >= nb_samples) {
379 if (smp_cnt >= nb_samples) {
385 if (smp_cnt < nb_samples) {
393 }
while (smp_cnt < nb_samples);
395 for (n = 0; n < nb_samples; n++) {
397 out[
c] = buf[index +
c];
398 if (fabs(out[c]) > ceiling) {
399 out[
c] = ceiling * (out[
c] < 0 ? -1 : 1);
419 int i,
n,
c, subframe_length, src_index;
420 double gain, gain_next, env_global, env_shortterm,
421 global, shortterm, lra, relative_threshold;
438 src = (
const double *)in->
data[0];
439 dst = (
double *)out->
data[0];
446 double offset, offset_tp, true_peak;
449 for (c = 0; c < inlink->
channels; c++) {
452 if (c == 0 || tmp > true_peak)
457 offset_tp = true_peak +
offset;
466 for (c = 0; c < inlink->
channels; c++) {
480 env_shortterm = shortterm <= -70. ? 0. : s->
target_i - shortterm;
483 for (n = 0; n < 30; n++)
484 s->
delta[n] = pow(10., env_shortterm / 20.);
491 for (c = 0; c < inlink->
channels; c++) {
519 for (c = 0; c < inlink->
channels; c++) {
550 double shortterm_out;
560 if (shortterm < relative_threshold || shortterm <= -70. || s->
above_threshold == 0) {
563 env_global = fabs(shortterm - global) < (s->
target_lra / 2.) ? shortterm - global : (s->
target_lra / 2.) * ((shortterm - global) < 0 ? -1 : 1);
564 env_shortterm = s->
target_i - shortterm;
565 s->
delta[s->
index] = pow(10., (env_global + env_shortterm) / 20.);
582 for (c = 0; c < inlink->
channels; c++) {
593 for (i = 0; i < in->
nb_samples / subframe_length; i++) {
596 for (n = 0; n < subframe_length; n++) {
597 for (c = 0; c < inlink->
channels; c++) {
613 dst += (subframe_length * inlink->
channels);
616 dst = (
double *)out->
data[0];
622 for (c = 0; c < inlink->
channels; c++) {
629 dst = (
double *)out->
data[0];
664 src = (
double *)frame->
data[0];
670 for (n = 0; n < nb_samples; n++) {
671 for (c = 0; c < inlink->
channels; c++) {
693 static const int input_srate[] = {192000, -1};
808 double i_in, i_out, lra_in, lra_out, thresh_in, thresh_out, tp_in, tp_out;
820 if ((c == 0) || (tmp > tp_in))
830 if ((c == 0) || (tmp > tp_out))
841 "\t\"input_i\" : \"%.2f\",\n" 842 "\t\"input_tp\" : \"%.2f\",\n" 843 "\t\"input_lra\" : \"%.2f\",\n" 844 "\t\"input_thresh\" : \"%.2f\",\n" 845 "\t\"output_i\" : \"%.2f\",\n" 846 "\t\"output_tp\" : \"%+.2f\",\n" 847 "\t\"output_lra\" : \"%.2f\",\n" 848 "\t\"output_thresh\" : \"%.2f\",\n" 849 "\t\"normalization_type\" : \"%s\",\n" 850 "\t\"target_offset\" : \"%.2f\"\n" 868 "Input Integrated: %+6.1f LUFS\n" 869 "Input True Peak: %+6.1f dBTP\n" 870 "Input LRA: %6.1f LU\n" 871 "Input Threshold: %+6.1f LUFS\n" 873 "Output Integrated: %+6.1f LUFS\n" 874 "Output True Peak: %+6.1f dBTP\n" 875 "Output LRA: %6.1f LU\n" 876 "Output Threshold: %+6.1f LUFS\n" 878 "Normalization Type: %s\n" 879 "Target Offset: %+6.1f LU\n",
927 .priv_class = &loudnorm_class,
931 .
inputs = avfilter_af_loudnorm_inputs,
932 .
outputs = avfilter_af_loudnorm_outputs,
This structure describes decoded (raw) audio or video data.
Main libavfilter public API header.
int max_samples
Maximum number of samples to filter at once.
int ff_ebur128_loudness_global(FFEBUR128State *st, double *out)
Get global integrated loudness in LUFS.
void ff_ebur128_destroy(FFEBUR128State **st)
Destroy library state.
can call ff_ebur128_loudness_global_* and ff_ebur128_relative_threshold
a channel that is counted twice
can call ff_ebur128_sample_peak
static int config_input(AVFilterLink *inlink)
void ff_ebur128_add_frames_double(FFEBUR128State *st, const double *src, size_t frames)
See ebur128_add_frames_short.
AVFILTER_DEFINE_CLASS(loudnorm)
const char * name
Pad name.
AVFilterLink ** inputs
array of pointers to input links
static const AVOption loudnorm_options[]
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_ebur128_loudness_range(FFEBUR128State *st, double *out)
Get loudness range (LRA) of programme in LU.
static av_cold int end(AVCodecContext *avctx)
static void detect_peak(LoudNormContext *s, int offset, int nb_samples, int channels, int *peak_delta, double *peak_value)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
#define AVERROR_EOF
End of file.
enum PrintFormat print_format
A filter pad used for either input or output.
A link between two filters.
FrameType
G723.1 frame types.
can call ff_ebur128_loudness_shortterm
static int request_frame(AVFilterLink *outlink)
int min_samples
Minimum number of samples to filter at once.
int sample_rate
samples per second
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void * priv
private data for use by the filter
int ff_ebur128_sample_peak(FFEBUR128State *st, unsigned int channel_number, double *out)
Get maximum sample peak of selected channel in float format.
int ff_ebur128_loudness_shortterm(FFEBUR128State *st, double *out)
Get short-term loudness (last 3s) in LUFS.
static av_always_inline av_const double round(double x)
can call ff_ebur128_loudness_range
static const AVFilterPad avfilter_af_loudnorm_inputs[]
enum LimiterState limiter_state
Contains information about the state of a loudness measurement.
AVFilterContext * src
source filter
int partial_buf_size
Size of the partial buffer to allocate.
static double gaussian_filter(LoudNormContext *s, int index)
FFEBUR128State * ff_ebur128_init(unsigned int channels, unsigned long samplerate, unsigned long window, int mode)
Initialize library state.
static const AVFilterPad inputs[]
AVFilterFormats * out_samplerates
static const AVFilterPad outputs[]
A list of supported channel layouts.
#define AV_LOG_INFO
Standard information.
AVFilterFormats * in_samplerates
Lists of channel layouts and sample rates used for automatic negotiation.
AVSampleFormat
Audio sample formats.
int ff_ebur128_set_channel(FFEBUR128State *st, unsigned int channel_number, int value)
Set channel type.
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
static void true_peak_limiter(LoudNormContext *s, double *out, int nb_samples, int channels)
enum FrameType frame_type
static av_cold int init(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Describe the class of an AVClass context structure.
const char * name
Filter name.
static int frame_size(int sample_rate, int frame_len_msec)
AVFilterLink ** outputs
array of pointers to output links
enum MovChannelLayoutTag * layouts
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static int query_formats(AVFilterContext *ctx)
int ff_ebur128_relative_threshold(FFEBUR128State *st, double *out)
Get relative threshold in LUFS.
int channels
Number of channels.
static void init_gaussian_filter(LoudNormContext *s)
AVFilterContext * dst
dest filter
static enum AVSampleFormat sample_fmts[]
static const AVFilterPad avfilter_af_loudnorm_outputs[]
#define av_malloc_array(a, b)
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
FFEBUR128State * r128_out
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
int nb_samples
number of audio samples (per channel) described by this frame
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define AV_NOPTS_VALUE
Undefined timestamp value.
libebur128 - a library for loudness measurement according to the EBU R128 standard.