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++) {
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];
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++) {
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)
456 offset = pow(10., (s->
target_i - global) / 20.);
457 offset_tp = true_peak *
offset;
465 for (c = 0; c < inlink->
channels; c++) {
479 env_shortterm = shortterm <= -70. ? 0. : s->
target_i - shortterm;
482 for (n = 0; n < 30; n++)
483 s->
delta[n] = pow(10., env_shortterm / 20.);
490 for (c = 0; c < inlink->
channels; c++) {
518 for (c = 0; c < inlink->
channels; c++) {
549 double shortterm_out;
559 if (shortterm < relative_threshold || shortterm <= -70. || s->
above_threshold == 0) {
562 env_global =
fabs(shortterm - global) < (s->
target_lra / 2.) ? shortterm - global : (s->
target_lra / 2.) * ((shortterm - global) < 0 ? -1 : 1);
563 env_shortterm = s->
target_i - shortterm;
564 s->
delta[s->
index] = pow(10., (env_global + env_shortterm) / 20.);
581 for (c = 0; c < inlink->
channels; c++) {
592 for (i = 0; i < in->
nb_samples / subframe_length; i++) {
595 for (n = 0; n < subframe_length; n++) {
596 for (c = 0; c < inlink->
channels; c++) {
612 dst += (subframe_length * inlink->
channels);
615 dst = (
double *)out->
data[0];
621 for (c = 0; c < inlink->
channels; c++) {
628 dst = (
double *)out->
data[0];
663 src = (
double *)frame->
data[0];
669 for (n = 0; n < nb_samples; n++) {
670 for (c = 0; c < inlink->
channels; c++) {
692 static const int input_srate[] = {192000, -1};
807 double i_in, i_out, lra_in, lra_out, thresh_in, thresh_out, tp_in, tp_out;
819 if ((c == 0) || (tmp > tp_in))
829 if ((c == 0) || (tmp > tp_out))
840 "\t\"input_i\" : \"%.2f\",\n" 841 "\t\"input_tp\" : \"%.2f\",\n" 842 "\t\"input_lra\" : \"%.2f\",\n" 843 "\t\"input_thresh\" : \"%.2f\",\n" 844 "\t\"output_i\" : \"%.2f\",\n" 845 "\t\"output_tp\" : \"%+.2f\",\n" 846 "\t\"output_lra\" : \"%.2f\",\n" 847 "\t\"output_thresh\" : \"%.2f\",\n" 848 "\t\"normalization_type\" : \"%s\",\n" 849 "\t\"target_offset\" : \"%.2f\"\n" 867 "Input Integrated: %+6.1f LUFS\n" 868 "Input True Peak: %+6.1f dBTP\n" 869 "Input LRA: %6.1f LU\n" 870 "Input Threshold: %+6.1f LUFS\n" 872 "Output Integrated: %+6.1f LUFS\n" 873 "Output True Peak: %+6.1f dBTP\n" 874 "Output LRA: %6.1f LU\n" 875 "Output Threshold: %+6.1f LUFS\n" 877 "Normalization Type: %s\n" 878 "Target Offset: %+6.1f LU\n",
926 .priv_class = &loudnorm_class,
930 .
inputs = avfilter_af_loudnorm_inputs,
931 .
outputs = avfilter_af_loudnorm_outputs,
This structure describes decoded (raw) audio or video data.
static int adjust(int x, int size)
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
AVFilterFormatsConfig outcfg
Lists of supported formats / etc.
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)
Add frames to be processed.
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.
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
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.
static __device__ float fabs(float a)
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.
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
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 outputs[]
A list of supported channel layouts.
#define AV_LOG_INFO
Standard information.
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)
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
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)\n", 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.
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
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.
AVFilterFormatsConfig incfg
Lists of supported formats / etc.
static void init_gaussian_filter(LoudNormContext *s)
AVFilterContext * dst
dest filter
and forward the result(frame or status change) to the corresponding input.If nothing is possible
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
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
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.