1 /*
2 * Copyright (c) 2012 Clément Bœsch
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file
23 * EBU R.128 implementation
24 * @see http://tech.ebu.ch/loudness
25 * @see https://www.youtube.com/watch?v=iuEtQqC-Sqo "EBU R128 Introduction - Florian Camerer"
26 * @todo implement start/stop/reset through filter command injection
27 * @todo support other frequencies to avoid resampling
28 */
29
31
45
46 #define MAX_CHANNELS 63
47
48 /* pre-filter coefficients */
49 #define PRE_B0 1.53512485958697
50 #define PRE_B1 -2.69169618940638
51 #define PRE_B2 1.19839281085285
52 #define PRE_A1 -1.69065929318241
53 #define PRE_A2 0.73248077421585
54
55 /* RLB-filter coefficients */
59 #define RLB_A1 -1.99004745483398
60 #define RLB_A2 0.99007225036621
61
62 #define ABS_THRES -70 ///< silence gate: we discard anything below this absolute (LUFS) threshold
63 #define ABS_UP_THRES 10
///< upper loud limit to consider (ABS_THRES being the minimum)
64 #define HIST_GRAIN 100
///< defines histogram precision
65 #define HIST_SIZE ((ABS_UP_THRES - ABS_THRES) * HIST_GRAIN + 1)
66
67 /**
68 * A histogram is an array of HIST_SIZE hist_entry storing all the energies
69 * recorded (with an accuracy of 1/HIST_GRAIN) of the loudnesses from ABS_THRES
70 * (at 0) to ABS_UP_THRES (at HIST_SIZE-1).
71 * This fixed-size system avoids the need of a list of energies growing
72 * infinitely over the time and is thus more scalable.
73 */
75 int count;
///< how many times the corresponding value occurred
76 double energy;
///< E = 10^((L + 0.691) / 10)
77 double loudness;
///< L = -0.691 + 10 * log10(E)
78 };
79
82 int cache_pos;
///< focus on the last added bin in the cache array
83 double sum[
MAX_CHANNELS];
///< sum of the last N ms filtered samples (cache content)
84 int filled;
///< 1 if the cache is completely filled, 0 otherwise
86 double sum_kept_powers;
///< sum of the powers (weighted sums) above absolute threshold
89 };
90
92
94 const AVClass *
class;
///< AVClass context for log and options purpose
95
96 /* peak metering */
101 #if CONFIG_SWRESAMPLE
102 SwrContext *swr_ctx;
///< over-sampling context for true peak metering
103 double *swr_buf; ///< resampled audio data for true peak metering
104 int swr_linesize;
105 #endif
106
107 /* video */
108 int do_video;
///< 1 if video output enabled, 0 otherwise
109 int w,
h;
///< size of the video output
110 struct rect text;
///< rectangle for the LU legend on the left
111 struct rect graph;
///< rectangle for the main graph in the center
112 struct rect gauge;
///< rectangle for the gauge on the right
114 int meter;
///< select a EBU mode between +9 and +18
115 int scale_range;
///< the range of LU values according to the meter
116 int y_zero_lu;
///< the y value (pixel position) for 0 LU
117 int *
y_line_ref;
///< y reference values for drawing the LU lines in the graph and the gauge
118
119 /* audio */
122 int sample_count;
///< sample count used for refresh frequency, reset at refresh
123
124 /* Filter caches.
125 * The mult by 3 in the following is for X[i], X[i-1] and X[i-2] */
127 double y[
MAX_CHANNELS * 3];
///< 3 pre-filter samples cache for each channel
128 double z[
MAX_CHANNELS * 3];
///< 3 RLB-filter samples cache for each channel
129
130 #define I400_BINS (48000 * 4 / 10)
131 #define I3000_BINS (48000 * 3)
132 struct integrator i400;
///< 400ms integrator, used for Momentary loudness (M), and Integrated loudness (I)
133 struct integrator i3000;
///< 3s integrator, used for Short term loudness (S), and Loudness Range (LRA)
134
135 /* I and LRA specific */
139
140 /* misc */
142 int metadata;
///< whether or not to inject loudness results in frames
143 int dual_mono;
///< whether or not to treat single channel input files as dual-mono
144 double pan_law;
///< pan law value used to calculate dual-mono measurements
146
147 enum {
151 };
152
153 #define OFFSET(x) offsetof(EBUR128Context, x)
154 #define A AV_OPT_FLAG_AUDIO_PARAM
155 #define V AV_OPT_FLAG_VIDEO_PARAM
156 #define F AV_OPT_FLAG_FILTERING_PARAM
161 {
"framelog",
"force frame logging level",
OFFSET(loglevel),
AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX,
A|
V|
F,
"level" },
170 {
"panlaw",
"set a specific pan law for dual-mono files",
OFFSET(pan_law),
AV_OPT_TYPE_DOUBLE, {.dbl = -3.01029995663978}, -10.0, 0.0,
A|
F },
172 };
173
175
177 0xdd, 0x66, 0x66, // value above 0LU non reached
178 0x66, 0x66, 0xdd, // value below 0LU non reached
179 0x96, 0x33, 0x33, // value above 0LU reached
180 0x33, 0x33, 0x96, // value below 0LU reached
181 0xdd, 0x96, 0x96, // value above 0LU line non reached
182 0x96, 0x96, 0xdd, // value below 0LU line non reached
183 0xdd, 0x33, 0x33, // value above 0LU line reached
184 0x33, 0x33, 0xdd, // value below 0LU line reached
185 };
186
188 {
189 const int below0 = y > ebur128->
y_zero_lu;
190 const int reached = y >= v;
192 const int colorid = 4*line + 2*reached + below0;
194 }
195
197 {
198 v += 2 * ebur128->
meter;
// make it in range [0;...]
199 v = av_clipf(v, 0, ebur128->
scale_range);
// make sure it's in the graph scale
200 v = ebur128->
scale_range - v;
// invert value (y=0 is on top)
201 return v * ebur128->
graph.
h / ebur128->
scale_range;
// rescale from scale range to px height
202 }
203
206
208 0xdd, 0xdd, 0x00,
209 0x00, 0x96, 0x96,
210 };
211
213 {
214 int i;
217 int font_height;
218 va_list vl;
219
222 else return;
223
224 va_start(vl, fmt);
226 va_end(vl);
227
228 for (i = 0; buf[i]; i++) {
231
232 for (char_y = 0; char_y < font_height; char_y++) {
233 for (mask = 0x80;
mask; mask >>= 1) {
234 if (font[buf[i] * font_height + char_y] & mask)
235 memcpy(p, color, 3);
236 else
237 memcpy(p, "\x00\x00\x00", 3);
238 p += 3;
239 }
241 }
242 }
243 }
244
246 {
247 int i;
249
250 for (i = 0; i <
len; i++) {
251 memcpy(p, "\x00\xff\x00", 3);
252 p += step;
253 }
254 }
255
257 {
258 int i, x, y;
263
264 /* check if there is enough space to represent everything decently */
265 if (ebur128->
w < 640 || ebur128->
h < 480) {
267 "minimum size is 640x480\n", ebur128->
w, ebur128->
h);
269 }
270 outlink->
w = ebur128->
w;
271 outlink->
h = ebur128->
h;
273
274 #define PAD 8
275
276 /* configure text area position and size */
278 ebur128->
text.
y = 40;
279 ebur128->
text.
w = 3 * 8;
// 3 characters
281
282 /* configure gauge position and size */
287
288 /* configure graph position and size */
293
294 /* graph and gauge share the LU-to-pixel code */
296
297 /* prepare the initial picref buffer */
301 if (!outpicref)
304
305 /* init y references values (to draw LU lines) */
309
310 /* black background */
311 memset(outpicref->
data[0], 0, ebur128->
h * outpicref->
linesize[0]);
312
313 /* draw LU legends */
315 for (i = ebur128->
meter; i >= -ebur128->
meter * 2; i--) {
317 x =
PAD + (i < 10 && i > -10) * 8;
319 y -= 4; // -4 to center vertically
321 "%c%d", i < 0 ? '-' : i > 0 ?
'+' :
' ',
FFABS(i));
322 }
323
324 /* draw graph */
328 for (y = 0; y < ebur128->
graph.
h; y++) {
330
331 for (x = 0; x < ebur128->
graph.
w; x++)
332 memcpy(p + x*3, c, 3);
334 }
335
336 /* draw fancy rectangles around the graph and the gauge */
337 #define DRAW_RECT(r) do { \
338 drawline(outpicref, r.x, r.y - 1, r.w, 3); \
339 drawline(outpicref, r.x, r.y + r.h, r.w, 3); \
340 drawline(outpicref, r.x - 1, r.y, r.h, outpicref->linesize[0]); \
341 drawline(outpicref, r.x + r.w, r.y, r.h, outpicref->linesize[0]); \
342 } while (0)
345
346 return 0;
347 }
348
350 {
353
354 /* Force 100ms framing in case of metadata injection: the frames must have
355 * a granularity of the window overlap to be accurately exploited.
356 * As for the true peaks mode, it just simplifies the resampling buffer
357 * allocation and the lookup in it (since sample buffers differ in size, it
358 * can be more complex to integrate in the one-sample loop of
359 * filter_frame()). */
364 return 0;
365 }
366
368 {
369 int i;
373
374 #define BACK_MASK (AV_CH_BACK_LEFT |AV_CH_BACK_CENTER |AV_CH_BACK_RIGHT| \
375 AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_BACK_RIGHT| \
376 AV_CH_SIDE_LEFT |AV_CH_SIDE_RIGHT| \
377 AV_CH_SURROUND_DIRECT_LEFT |AV_CH_SURROUND_DIRECT_RIGHT)
378
383
385 /* channel weighting */
391 } else {
393 }
394
396 continue;
397
398 /* bins buffer for the two integration window (400ms and 3s) */
403 }
404
405 #if CONFIG_SWRESAMPLE
407 int ret;
408
409 ebur128->swr_buf =
av_malloc_array(nb_channels, 19200 *
sizeof(
double));
413 if (!ebur128->swr_buf || !ebur128->
true_peaks ||
416
420
424
426 if (ret < 0)
427 return ret;
428 }
429 #endif
430
435 }
436
437 return 0;
438 }
439
440 #define ENERGY(loudness) (ff_exp10(((loudness) + 0.691) / 10.))
441 #define LOUDNESS(energy) (-0.691 + 10 * log10(energy))
442 #define DBFS(energy) (20 * log10(energy))
443
445 {
446 int i;
448
449 if (!h)
454 }
456 }
457
459 {
462
467 else
469 }
470
473 "True-peak mode requires libswresample to be performed\n");
475 }
476
477 // if meter is +9 scale, scale range is from -18 LU to +9 LU (or 3*9)
478 // if meter is +18 scale, scale range is from -36 LU to +18 LU (or 3*18)
480
485
488
489 /* insert output pads */
495 };
499 }
504 };
508
509 /* summary */
511
512 return 0;
513 }
514
515 #define HIST_POS(power) (int)(((power) - ABS_THRES) * HIST_GRAIN)
516
517 /* loudness and power should be set such as loudness = -0.691 +
518 * 10*log10(power), we just avoid doing that calculus two times */
521 {
522 int ipower;
523 double relative_threshold;
524 int gate_hist_pos;
525
526 /* update powers histograms by incrementing current power count */
529
530 /* compute relative threshold and get its position in the histogram */
534 if (!relative_threshold)
535 relative_threshold = 1e-12;
538
539 return gate_hist_pos;
540 }
541
543 {
544 int i,
ch, idx_insample;
549 const double *samples = (
double *)insamples->
data[0];
551
552 #if CONFIG_SWRESAMPLE
554 const double *swr_samples = ebur128->swr_buf;
557 if (ret < 0)
558 return ret;
561 for (idx_insample = 0; idx_insample < ret; idx_insample++) {
565 fabs(*swr_samples));
566 swr_samples++;
567 }
568 }
569 }
570 #endif
571
572 for (idx_insample = 0; idx_insample < nb_samples; idx_insample++) {
575
576 #define MOVE_TO_NEXT_CACHED_ENTRY(time) do { \
577 ebur128->i##time.cache_pos++; \
578 if (ebur128->i##time.cache_pos == I##time##_BINS) { \
579 ebur128->i##time.filled = 1; \
580 ebur128->i##time.cache_pos = 0; \
581 } \
582 } while (0)
583
586
588 double bin;
589
592
593 ebur128->
x[ch * 3] = *samples++;
// set X[i]
594
596 continue;
597
598 /* Y[i] = X[i]*b0 + X[i-1]*b1 + X[i-2]*b2 - Y[i-1]*a1 - Y[i-2]*a2 */
599 #define FILTER(Y, X, name) do { \
600 double *dst = ebur128->Y + ch*3; \
601 double *src = ebur128->X + ch*3; \
602 dst[2] = dst[1]; \
603 dst[1] = dst[0]; \
604 dst[0] = src[0]*name##_B0 + src[1]*name##_B1 + src[2]*name##_B2 \
605 - dst[1]*name##_A1 - dst[2]*name##_A2; \
606 } while (0)
607
608 // TODO: merge both filters in one?
609 FILTER(y, x, PRE);
// apply pre-filter
610 ebur128->
x[ch * 3 + 2] = ebur128->
x[ch * 3 + 1];
611 ebur128->
x[ch * 3 + 1] = ebur128->
x[ch * 3 ];
612 FILTER(z, y, RLB);
// apply RLB-filter
613
614 bin = ebur128->
z[ch * 3] * ebur128->
z[ch * 3];
615
616 /* add the new value, and limit the sum to the cache size (400ms or 3s)
617 * by removing the oldest one */
620
621 /* override old cache entry with the new value */
624 }
625
626 /* For integrated loudness, gating blocks are 400ms long with 75%
627 * overlap (see BS.1770-2 p5), so a re-computation is needed each 100ms
628 * (4800 samples at 48kHz). */
630 double loudness_400, loudness_3000;
631 double power_400 = 1e-12, power_3000 = 1e-12;
633 const int64_t
pts = insamples->
pts +
636
638
639 #define COMPUTE_LOUDNESS(m, time) do { \
640 if (ebur128->i##time.filled) { \
641 /* weighting sum of the last <time> ms */ \
642 for (ch = 0; ch < nb_channels; ch++) \
643 power_##time += ebur128->ch_weighting[ch] * ebur128->i##time.sum[ch]; \
644 power_##time /= I##time##_BINS; \
645 } \
646 loudness_##time = LOUDNESS(power_##time); \
647 } while (0)
648
651
652 /* Integrated loudness */
653 #define I_GATE_THRES -10 // initially defined to -8 LU in the first EBU standard
654
656 double integrated_sum = 0;
657 int nb_integrated = 0;
660
661 /* compute integrated loudness by summing the histogram values
662 * above the relative threshold */
663 for (i = gate_hist_pos; i <
HIST_SIZE; i++) {
665 nb_integrated += nb_v;
667 }
668 if (nb_integrated) {
670 /* dual-mono correction */
671 if (nb_channels == 1 && ebur128->
dual_mono) {
673 }
674 }
675 }
676
677 /* LRA */
678 #define LRA_GATE_THRES -20
679 #define LRA_LOWER_PRC 10
680 #define LRA_HIGHER_PRC 95
681
682 /* XXX: example code in EBU 3342 is ">=" but formula in BS.1770
683 * specs is ">" */
685 int nb_powers = 0;
688
689 for (i = gate_hist_pos; i <
HIST_SIZE; i++)
693
694 /* get lower loudness to consider */
695 n = 0;
697 for (i = gate_hist_pos; i <
HIST_SIZE; i++) {
699 if (n >= nb_pow) {
701 break;
702 }
703 }
704
705 /* get higher loudness to consider */
706 n = nb_powers;
708 for (i = HIST_SIZE - 1; i >= 0; i--) {
710 if (n < nb_pow) {
712 break;
713 }
714 }
715
716 // XXX: show low & high on the graph?
718 }
719 }
720
721 /* dual-mono correction */
722 if (nb_channels == 1 && ebur128->
dual_mono) {
723 loudness_400 -= ebur128->
pan_law;
724 loudness_3000 -= ebur128->
pan_law;
725 }
726
727 #define LOG_FMT "M:%6.1f S:%6.1f I:%6.1f LUFS LRA:%6.1f LU"
728
729 /* push one video frame */
731 int x, y, ret;
733
734 const int y_loudness_lu_graph =
lu_to_y(ebur128, loudness_3000 + 23);
735 const int y_loudness_lu_gauge =
lu_to_y(ebur128, loudness_400 + 23);
736
737 /* draw the graph using the short-term loudness */
738 p = pic->data[0] + ebur128->
graph.
y*pic->linesize[0] + ebur128->
graph.
x*3;
739 for (y = 0; y < ebur128->
graph.
h; y++) {
741
742 memmove(p, p + 3, (ebur128->
graph.
w - 1) * 3);
743 memcpy(p + (ebur128->
graph.
w - 1) * 3, c, 3);
744 p += pic->linesize[0];
745 }
746
747 /* draw the gauge using the momentary loudness */
748 p = pic->data[0] + ebur128->
gauge.
y*pic->linesize[0] + ebur128->
gauge.
x*3;
749 for (y = 0; y < ebur128->
gauge.
h; y++) {
751
752 for (x = 0; x < ebur128->
gauge.
w; x++)
753 memcpy(p + x*3, c, 3);
754 p += pic->linesize[0];
755 }
756
757 /* draw textual info */
759 LOG_FMT " ",
// padding to erase trailing characters
760 loudness_400, loudness_3000,
762
763 /* set pts and push frame */
766 if (ret < 0)
767 return ret;
768 }
769
770 if (ebur128->
metadata) {
/* happens only once per filter_frame call */
771 char metabuf[128];
772 #define META_PREFIX "lavfi.r128."
773
774 #define SET_META(name, var) do { \
775 snprintf(metabuf, sizeof(metabuf), "%.3f", var); \
776 av_dict_set(&insamples->metadata, name, metabuf, 0); \
777 } while (0)
778
779 #define SET_META_PEAK(name, ptype) do { \
780 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
781 char key[64]; \
782 for (ch = 0; ch < nb_channels; ch++) { \
783 snprintf(key, sizeof(key), \
784 META_PREFIX AV_STRINGIFY(name) "_peaks_ch%d", ch); \
785 SET_META(key, ebur128->name##_peaks[ch]); \
786 } \
787 } \
788 } while (0)
789
796
799 }
800
803 loudness_400, loudness_3000,
805
806 #define PRINT_PEAKS(str, sp, ptype) do { \
807 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
808 av_log(ctx, ebur128->loglevel, " " str ":"); \
809 for (ch = 0; ch < nb_channels; ch++) \
810 av_log(ctx, ebur128->loglevel, " %5.1f", DBFS(sp[ch])); \
811 av_log(ctx, ebur128->loglevel, " dBFS"); \
812 } \
813 } while (0)
814
819 }
820 }
821
823 }
824
826 {
832 int ret;
833
835 static const int input_srate[] = {48000, -1}; // ITU-R BS.1770 provides coeff only for 48kHz
837
838 /* set optional output video format */
842 return ret;
844 }
845
846 /* set input and output audio formats
847 * Note: ff_set_common_* functions are not used because they affect all the
848 * links, and thus break the video format negotiation */
852 return ret;
853
857 return ret;
858
862 return ret;
863
864 return 0;
865 }
866
868 {
869 int i;
871
872 /* dual-mono correction */
878 }
879
881 " Integrated loudness:\n"
882 " I: %5.1f LUFS\n"
883 " Threshold: %5.1f LUFS\n\n"
884 " Loudness range:\n"
885 " LRA: %5.1f LU\n"
886 " Threshold: %5.1f LUFS\n"
887 " LRA low: %5.1f LUFS\n"
888 " LRA high: %5.1f LUFS",
892
893 #define PRINT_PEAK_SUMMARY(str, sp, ptype) do { \
894 int ch; \
895 double maxpeak; \
896 maxpeak = 0.0; \
897 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
898 for (ch = 0; ch < ebur128->nb_channels; ch++) \
899 maxpeak = FFMAX(maxpeak, sp[ch]); \
900 av_log(ctx, AV_LOG_INFO, "\n\n " str " peak:\n" \
901 " Peak: %5.1f dBFS", \
902 DBFS(maxpeak)); \
903 } \
904 } while (0)
905
909
920 }
924 #if CONFIG_SWRESAMPLE
927 #endif
928 }
929
931 {
936 },
938 };
939
949 .priv_class = &ebur128_class,
951 };
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)
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)
double y[MAX_CHANNELS *3]
3 pre-filter samples cache for each channel
#define AV_CH_LOW_FREQUENCY_2
const uint8_t avpriv_vga16_font[4096]
int do_video
1 if video output enabled, 0 otherwise
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
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
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.
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)
static const AVFilterPad inputs[]
AVFilterFormats * out_samplerates
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
static const AVFilterPad outputs[]
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.
char * av_strdup(const char *s)
Duplicate a string.
AVSampleFormat
Audio sample formats.
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.
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
int nb_kept_powers
number of sum above absolute threshold
Describe the class of an AVClass context structure.
Rational number (pair of numerator and 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[]
int dual_mono
whether or not to treat single channel input files as dual-mono
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
struct rect text
rectangle for the LU legend on the left
internal math functions header
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
double pan_law
pan law value used to calculate dual-mono measurements
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.
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(constuint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(constint16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(constint32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(constint64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(constfloat *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(constdouble *) pi *(INT64_C(1)<< 63)))#defineFMT_PAIR_FUNC(out, in) staticconv_func_type *constfmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};staticvoidcpy1(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, len);}staticvoidcpy2(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 2 *len);}staticvoidcpy4(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 4 *len);}staticvoidcpy8(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, constint *ch_map, intflags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) returnNULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) returnNULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case1:ctx->simd_f=cpy1;break;case2:ctx->simd_f=cpy2;break;case4:ctx->simd_f=cpy4;break;case8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);returnctx;}voidswri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}intswri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, intlen){intch;intoff=0;constintos=(out->planar?1:out->ch_count)*out->bps;unsignedmisaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){intplanes=in->planar?in->ch_count:1;unsignedm=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){intplanes=out->planar?out->ch_count:1;unsignedm=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){intplanes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
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)