45 #define MAX_CHANNELS 63
48 #define PRE_B0 1.53512485958697
49 #define PRE_B1 -2.69169618940638
50 #define PRE_B2 1.19839281085285
51 #define PRE_A1 -1.69065929318241
52 #define PRE_A2 0.73248077421585
58 #define RLB_A1 -1.99004745483398
59 #define RLB_A2 0.99007225036621
62 #define ABS_UP_THRES 10
63 #define HIST_GRAIN 100
64 #define HIST_SIZE ((ABS_UP_THRES - ABS_THRES) * HIST_GRAIN + 1)
100 #if CONFIG_SWRESAMPLE
129 #define I400_BINS (48000 * 4 / 10)
130 #define I3000_BINS (48000 * 3)
150 #define OFFSET(x) offsetof(EBUR128Context, x)
151 #define A AV_OPT_FLAG_AUDIO_PARAM
152 #define V AV_OPT_FLAG_VIDEO_PARAM
153 #define F AV_OPT_FLAG_FILTERING_PARAM
158 {
"framelog",
"force frame logging level",
OFFSET(loglevel),
AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX,
A|
V|
F,
"level" },
184 const int below0 = y > ebur128->
y_zero_lu;
185 const int reached = y >=
v;
187 const int colorid = 4*line + 2*reached + below0;
193 v += 2 * ebur128->
meter;
223 for (i = 0; buf[i]; i++) {
227 for (char_y = 0; char_y < font_height; char_y++) {
228 for (mask = 0x80;
mask; mask >>= 1) {
229 if (font[buf[i] * font_height + char_y] & mask)
232 memcpy(p,
"\x00\x00\x00", 3);
245 for (i = 0; i <
len; i++) {
246 memcpy(p,
"\x00\xff\x00", 3);
260 if (ebur128->
w < 640 || ebur128->
h < 480) {
262 "minimum size is 640x480\n", ebur128->
w, ebur128->
h);
265 outlink->
w = ebur128->
w;
266 outlink->
h = ebur128->
h;
272 ebur128->
text.
y = 40;
273 ebur128->
text.
w = 3 * 8;
305 memset(outpicref->
data[0], 0, ebur128->
h * outpicref->
linesize[0]);
309 for (i = ebur128->
meter; i >= -ebur128->
meter * 2; i--) {
311 x =
PAD + (i < 10 && i > -10) * 8;
315 "%c%d", i < 0 ? '-' : i > 0 ?
'+' :
' ',
FFABS(i));
322 for (y = 0; y < ebur128->
graph.
h; y++) {
325 for (x = 0; x < ebur128->
graph.
w; x++)
326 memcpy(p + x*3, c, 3);
331 #define DRAW_RECT(r) do { \
332 drawline(outpicref, r.x, r.y - 1, r.w, 3); \
333 drawline(outpicref, r.x, r.y + r.h, r.w, 3); \
334 drawline(outpicref, r.x - 1, r.y, r.h, outpicref->linesize[0]); \
335 drawline(outpicref, r.x + r.w, r.y, r.h, outpicref->linesize[0]); \
370 #define BACK_MASK (AV_CH_BACK_LEFT |AV_CH_BACK_CENTER |AV_CH_BACK_RIGHT| \
371 AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_BACK_RIGHT| \
372 AV_CH_SIDE_LEFT |AV_CH_SIDE_RIGHT| \
373 AV_CH_SURROUND_DIRECT_LEFT |AV_CH_SURROUND_DIRECT_RIGHT)
403 #if CONFIG_SWRESAMPLE
407 ebur128->swr_buf =
av_malloc_array(nb_channels, 19200 *
sizeof(
double));
411 if (!ebur128->swr_buf || !ebur128->
true_peaks ||
438 #define ENERGY(loudness) (pow(10, ((loudness) + 0.691) / 10.))
439 #define LOUDNESS(energy) (-0.691 + 10 * log10(energy))
440 #define DBFS(energy) (20 * log10(energy))
471 "True-peak mode requires libswresample to be performed\n");
513 #define HIST_POS(power) (int)(((power) - ABS_THRES) * HIST_GRAIN)
521 double relative_threshold;
532 if (!relative_threshold)
533 relative_threshold = 1e-12;
537 return gate_hist_pos;
542 int i, ch, idx_insample;
547 const double *samples = (
double *)insamples->
data[0];
550 #
if CONFIG_SWRESAMPLE
552 const double *swr_samples = ebur128->swr_buf;
559 for (idx_insample = 0; idx_insample < ret; idx_insample++) {
563 FFABS(*swr_samples));
570 for (idx_insample = 0; idx_insample < nb_samples; idx_insample++) {
574 #define MOVE_TO_NEXT_CACHED_ENTRY(time) do { \
575 ebur128->i##time.cache_pos++; \
576 if (ebur128->i##time.cache_pos == I##time##_BINS) { \
577 ebur128->i##time.filled = 1; \
578 ebur128->i##time.cache_pos = 0; \
591 ebur128->
x[ch * 3] = *samples++;
597 #define FILTER(Y, X, name) do { \
598 double *dst = ebur128->Y + ch*3; \
599 double *src = ebur128->X + ch*3; \
602 dst[0] = src[0]*name##_B0 + src[1]*name##_B1 + src[2]*name##_B2 \
603 - dst[1]*name##_A1 - dst[2]*name##_A2; \
608 ebur128->
x[ch * 3 + 2] = ebur128->
x[ch * 3 + 1];
609 ebur128->
x[ch * 3 + 1] = ebur128->
x[ch * 3 ];
612 bin = ebur128->
z[ch * 3] * ebur128->
z[ch * 3];
620 ebur128->
i400.
cache [ch][bin_id_400 ] = bin;
628 double loudness_400, loudness_3000;
629 double power_400 = 1e-12, power_3000 = 1e-12;
631 const int64_t
pts = insamples->
pts +
637 #define COMPUTE_LOUDNESS(m, time) do { \
638 if (ebur128->i##time.filled) { \
640 for (ch = 0; ch < nb_channels; ch++) \
641 power_##time += ebur128->ch_weighting[ch] * ebur128->i##time.sum[ch]; \
642 power_##time /= I##time##_BINS; \
644 loudness_##time = LOUDNESS(power_##time); \
651 #define I_GATE_THRES -10 // initially defined to -8 LU in the first EBU standard
654 double integrated_sum = 0;
655 int nb_integrated = 0;
661 for (i = gate_hist_pos; i <
HIST_SIZE; i++) {
663 nb_integrated += nb_v;
671 #define LRA_GATE_THRES -20
672 #define LRA_LOWER_PRC 10
673 #define LRA_HIGHER_PRC 95
682 for (i = gate_hist_pos; i <
HIST_SIZE; i++)
690 for (i = gate_hist_pos; i <
HIST_SIZE; i++) {
701 for (i = HIST_SIZE - 1; i >= 0; i--) {
714 #define LOG_FMT "M:%6.1f S:%6.1f I:%6.1f LUFS LRA:%6.1f LU"
721 const int y_loudness_lu_graph =
lu_to_y(ebur128, loudness_3000 + 23);
722 const int y_loudness_lu_gauge =
lu_to_y(ebur128, loudness_400 + 23);
725 p = pic->data[0] + ebur128->
graph.
y*pic->linesize[0] + ebur128->
graph.
x*3;
726 for (y = 0; y < ebur128->
graph.
h; y++) {
729 memmove(p, p + 3, (ebur128->
graph.
w - 1) * 3);
730 memcpy(p + (ebur128->
graph.
w - 1) * 3, c, 3);
731 p += pic->linesize[0];
735 p = pic->data[0] + ebur128->
gauge.
y*pic->linesize[0] + ebur128->
gauge.
x*3;
736 for (y = 0; y < ebur128->
gauge.
h; y++) {
739 for (x = 0; x < ebur128->
gauge.
w; x++)
740 memcpy(p + x*3, c, 3);
741 p += pic->linesize[0];
747 loudness_400, loudness_3000,
759 #define META_PREFIX "lavfi.r128."
761 #define SET_META(name, var) do { \
762 snprintf(metabuf, sizeof(metabuf), "%.3f", var); \
763 av_dict_set(&insamples->metadata, name, metabuf, 0); \
766 #define SET_META_PEAK(name, ptype) do { \
767 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
769 for (ch = 0; ch < nb_channels; ch++) { \
770 snprintf(key, sizeof(key), \
771 META_PREFIX AV_STRINGIFY(name) "_peaks_ch%d", ch); \
772 SET_META(key, ebur128->name##_peaks[ch]); \
790 loudness_400, loudness_3000,
793 #define PRINT_PEAKS(str, sp, ptype) do { \
794 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
795 av_log(ctx, ebur128->loglevel, " " str ":"); \
796 for (ch = 0; ch < nb_channels; ch++) \
797 av_log(ctx, ebur128->loglevel, " %5.1f", DBFS(sp[ch])); \
798 av_log(ctx, ebur128->loglevel, " dBFS"); \
821 static const int input_srate[] = {48000, -1};
863 " Integrated loudness:\n"
865 " Threshold: %5.1f LUFS\n\n"
868 " Threshold: %5.1f LUFS\n"
869 " LRA low: %5.1f LUFS\n"
870 " LRA high: %5.1f LUFS",
875 #define PRINT_PEAK_SUMMARY(str, sp, ptype) do { \
879 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
880 for (ch = 0; ch < ebur128->nb_channels; ch++) \
881 maxpeak = FFMAX(maxpeak, sp[ch]); \
882 av_log(ctx, AV_LOG_INFO, "\n\n " str " peak:\n" \
883 " Peak: %5.1f dBFS", \
906 #if CONFIG_SWRESAMPLE
931 .priv_class = &ebur128_class,
static struct hist_entry * get_histogram(void)
This structure describes decoded (raw) audio or video data.
int scale_range
the range of LU values according to the meter
static int query_formats(AVFilterContext *ctx)
double * true_peaks_per_frame
true peaks in a frame per channel
struct hist_entry * histogram
histogram of the powers, used to compute LRA and I
static int config_video_output(AVFilterLink *outlink)
static const AVFilterPad outputs[]
int sample_count
sample count used for refresh frequency, reset at refresh
Main libavfilter public API header.
packed RGB 8:8:8, 24bpp, RGBRGB...
int y_zero_lu
the y value (pixel position) for 0 LU
int max_samples
Maximum number of samples to filter at once.
static int config_audio_output(AVFilterLink *outlink)
int h
agreed upon image height
static int lu_to_y(const EBUR128Context *ebur128, double v)
#define COMPUTE_LOUDNESS(m, time)
static av_cold int init(AVFilterContext *ctx)
int cache_pos
focus on the last added bin in the cache array
#define SET_META_PEAK(name, ptype)
#define AV_CH_LOW_FREQUENCY_2
const uint8_t avpriv_vga16_font[4096]
int do_video
1 if video output enabled, 0 otherwise
static enum AVSampleFormat formats[]
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
static const AVOption ebur128_options[]
struct AVFilterChannelLayouts * in_channel_layouts
#define PRINT_PEAKS(str, sp, ptype)
int nb_channels
number of channels in the input
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
AVFILTER_DEFINE_CLASS(ebur128)
int metadata
whether or not to inject loudness results in frames
const char * name
Pad name.
AVFilterLink ** inputs
array of pointers to input links
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define HIST_GRAIN
defines histogram precision
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
AVFilterPad * output_pads
array of output pads
av_cold struct SwrContext * swr_alloc(void)
Allocate SwrContext.
static void drawtext(AVFrame *pic, int x, int y, int ftid, const uint8_t *color, const char *fmt,...)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
double sum_kept_powers
sum of the powers (weighted sums) above absolute threshold
timestamp utils, mostly useful for debugging/logging purposes
static void drawline(AVFrame *pic, int x, int y, int len, int step)
double * cache[MAX_CHANNELS]
window of filtered samples (N ms)
struct integrator i3000
3s integrator, used for Short term loudness (S), and Loudness Range (LRA)
double integrated_loudness
integrated loudness in LUFS (I)
double * true_peaks
true peaks per channel
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
static const uint8_t font_colors[]
#define AV_CH_LOW_FREQUENCY
int meter
select a EBU mode between +9 and +18
#define AV_LOG_VERBOSE
Detailed information.
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
A histogram is an array of HIST_SIZE hist_entry storing all the energies recorded (with an accuracy o...
AVFrame * outpicref
output picture reference, updated regularly
A filter pad used for either input or output.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
A link between two filters.
libswresample public header
double * sample_peaks
sample peaks per channel
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
unsigned flags
Link processing flags.
const uint8_t avpriv_cga_font[2048]
int min_samples
Minimum number of samples to filter at once.
int sample_rate
samples per second
int count
how many times the corresponding value occurred
static const uint16_t mask[17]
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
unsigned nb_outputs
number of output pads
The libswresample context.
#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 av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link...
simple assert() macros that are a bit more flexible than ISO C assert().
struct AVFilterChannelLayouts * out_channel_layouts
AVFilterFormats * in_formats
Lists of formats and channel layouts supported by the input and output filters respectively.
#define MOVE_TO_NEXT_CACHED_ENTRY(time)
struct integrator i400
400ms integrator, used for Momentary loudness (M), and Integrated loudness (I)
int w
agreed upon image width
static av_cold void uninit(AVFilterContext *ctx)
char * av_asprintf(const char *fmt,...)
int * y_line_ref
y reference values for drawing the LU lines in the graph and the gauge
struct rect graph
rectangle for the main graph in the center
audio channel layout utility functions
double loudness
L = -0.691 + 10 * log10(E)
double rel_threshold
relative threshold
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
AVFilterContext * src
source filter
int partial_buf_size
Size of the partial buffer to allocate.
double loudness_range
loudness range in LU (LRA)
Frame requests may need to loop in order to be fulfilled.
AVFilterFormats * out_samplerates
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
int format
agreed upon media format
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.
char * av_strdup(const char *s)
Duplicate the string s.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
#define ABS_THRES
silence gate: we discard anything below this absolute (LUFS) threshold
av_cold void swr_free(SwrContext **ss)
Free the given SwrContext and set the pointer to NULL.
int nb_kept_powers
number of sum above absolute threshold
Describe the class of an AVClass context structure.
static const AVFilterPad inputs[]
rational number numerator/denominator
const char * name
Filter name.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
offset must point to two consecutive integers
int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count, const uint8_t *in_arg[SWR_CH_MAX], int in_count)
AVFilterLink ** outputs
array of pointers to output links
enum MovChannelLayoutTag * layouts
static enum AVPixelFormat pix_fmts[]
void * av_calloc(size_t nmemb, size_t size)
Allocate a block of nmemb * size bytes with alignment suitable for all memory accesses (including vec...
static int64_t pts
Global timestamp for the audio frames.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
struct rect text
rectangle for the LU legend on the left
static const AVFilterPad ebur128_inputs[]
int h
size of the video output
#define PRINT_PEAK_SUMMARY(str, sp, ptype)
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
struct rect gauge
rectangle for the gauge on the right
uint64_t channel_layout
channel layout of current buffer (see libavutil/channel_layout.h)
static int config_audio_input(AVFilterLink *inlink)
static int gate_update(struct integrator *integ, double power, double loudness, int gate_thres)
int loglevel
log level for frame logging
double x[MAX_CHANNELS *3]
3 input samples cache for each channel
#define FILTER(Y, X, name)
double lra_high
low and high LRA values
AVFilterContext * dst
dest filter
static enum AVSampleFormat sample_fmts[]
double sum[MAX_CHANNELS]
sum of the last N ms filtered samples (cache content)
double z[MAX_CHANNELS *3]
3 RLB-filter samples cache for each channel
#define SET_META(name, var)
int peak_mode
enabled peak modes
#define av_malloc_array(a, b)
double * ch_weighting
channel weighting mapping
int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
static int ff_insert_outpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new output pad for the filter.
AVPixelFormat
Pixel format.
int nb_samples
number of audio samples (per channel) described by this frame
static const uint8_t graph_colors[]
CGA/EGA/VGA ROM font data.
AVFilterFormats * out_formats
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
double energy
E = 10^((L + 0.691) / 10)
int filled
1 if the cache is completely filled, 0 otherwise
static const uint8_t * get_graph_color(const EBUR128Context *ebur128, int v, int y)