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 modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 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
30 #include <math.h>
31
44
45 #define MAX_CHANNELS 63
46
47 /* pre-filter coefficients */
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
53
54 /* RLB-filter coefficients */
58 #define RLB_A1 -1.99004745483398
59 #define RLB_A2 0.99007225036621
60
61 #define ABS_THRES -70 ///< silence gate: we discard anything below this absolute (LUFS) threshold
62 #define ABS_UP_THRES 10
///< upper loud limit to consider (ABS_THRES being the minimum)
63 #define HIST_GRAIN 100
///< defines histogram precision
64 #define HIST_SIZE ((ABS_UP_THRES - ABS_THRES) * HIST_GRAIN + 1)
65
66 /**
67 * A histogram is an array of HIST_SIZE hist_entry storing all the energies
68 * recorded (with an accuracy of 1/HIST_GRAIN) of the loudnesses from ABS_THRES
69 * (at 0) to ABS_UP_THRES (at HIST_SIZE-1).
70 * This fixed-size system avoids the need of a list of energies growing
71 * infinitely over the time and is thus more scalable.
72 */
74 int count;
///< how many times the corresponding value occurred
75 double energy;
///< E = 10^((L + 0.691) / 10)
76 double loudness;
///< L = -0.691 + 10 * log10(E)
77 };
78
81 int cache_pos;
///< focus on the last added bin in the cache array
82 double sum[
MAX_CHANNELS];
///< sum of the last N ms filtered samples (cache content)
83 int filled;
///< 1 if the cache is completely filled, 0 otherwise
85 double sum_kept_powers;
///< sum of the powers (weighted sums) above absolute threshold
88 };
89
91
93 const AVClass *
class;
///< AVClass context for log and options purpose
94
95 /* peak metering */
100 #if CONFIG_SWRESAMPLE
101 SwrContext *swr_ctx;
///< over-sampling context for true peak metering
102 double *swr_buf; ///< resampled audio data for true peak metering
103 int swr_linesize;
104 #endif
105
106 /* video */
107 int do_video;
///< 1 if video output enabled, 0 otherwise
108 int w,
h;
///< size of the video output
109 struct rect text;
///< rectangle for the LU legend on the left
110 struct rect graph;
///< rectangle for the main graph in the center
111 struct rect gauge;
///< rectangle for the gauge on the right
113 int meter;
///< select a EBU mode between +9 and +18
114 int scale_range;
///< the range of LU values according to the meter
115 int y_zero_lu;
///< the y value (pixel position) for 0 LU
116 int *
y_line_ref;
///< y reference values for drawing the LU lines in the graph and the gauge
117
118 /* audio */
121 int sample_count;
///< sample count used for refresh frequency, reset at refresh
122
123 /* Filter caches.
124 * The mult by 3 in the following is for X[i], X[i-1] and X[i-2] */
126 double y[
MAX_CHANNELS * 3];
///< 3 pre-filter samples cache for each channel
127 double z[
MAX_CHANNELS * 3];
///< 3 RLB-filter samples cache for each channel
128
129 #define I400_BINS (48000 * 4 / 10)
130 #define I3000_BINS (48000 * 3)
131 struct integrator i400;
///< 400ms integrator, used for Momentary loudness (M), and Integrated loudness (I)
132 struct integrator i3000;
///< 3s integrator, used for Short term loudness (S), and Loudness Range (LRA)
133
134 /* I and LRA specific */
137 double lra_low, lra_high;
///< low and high LRA values
138
139 /* misc */
141 int metadata;
///< whether or not to inject loudness results in frames
142 int dual_mono;
///< whether or not to treat single channel input files as dual-mono
143 double pan_law;
///< pan law value used to calulate dual-mono measurements
145
146 enum {
150 };
151
152 #define OFFSET(x) offsetof(EBUR128Context, x)
153 #define A AV_OPT_FLAG_AUDIO_PARAM
154 #define V AV_OPT_FLAG_VIDEO_PARAM
155 #define F AV_OPT_FLAG_FILTERING_PARAM
160 {
"framelog",
"force frame logging level",
OFFSET(loglevel),
AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX,
A|
V|
F,
"level" },
169 {
"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 },
171 };
172
174
176 0xdd, 0x66, 0x66, // value above 0LU non reached
177 0x66, 0x66, 0xdd, // value below 0LU non reached
178 0x96, 0x33, 0x33, // value above 0LU reached
179 0x33, 0x33, 0x96, // value below 0LU reached
180 0xdd, 0x96, 0x96, // value above 0LU line non reached
181 0x96, 0x96, 0xdd, // value below 0LU line non reached
182 0xdd, 0x33, 0x33, // value above 0LU line reached
183 0x33, 0x33, 0xdd, // value below 0LU line reached
184 };
185
187 {
188 const int below0 = y > ebur128->
y_zero_lu;
189 const int reached = y >= v;
191 const int colorid = 4*line + 2*reached + below0;
193 }
194
196 {
197 v += 2 * ebur128->
meter;
// make it in range [0;...]
198 v = av_clipf(v, 0, ebur128->
scale_range);
// make sure it's in the graph scale
199 v = ebur128->
scale_range - v;
// invert value (y=0 is on top)
200 return v * ebur128->
graph.
h / ebur128->
scale_range;
// rescale from scale range to px height
201 }
202
205
207 0xdd, 0xdd, 0x00,
208 0x00, 0x96, 0x96,
209 };
210
212 {
213 int i;
216 int font_height;
217 va_list vl;
218
221 else return;
222
223 va_start(vl, fmt);
225 va_end(vl);
226
227 for (i = 0; buf[i]; i++) {
230
231 for (char_y = 0; char_y < font_height; char_y++) {
232 for (mask = 0x80;
mask; mask >>= 1) {
233 if (font[buf[i] * font_height + char_y] & mask)
234 memcpy(p, color, 3);
235 else
236 memcpy(p, "\x00\x00\x00", 3);
237 p += 3;
238 }
240 }
241 }
242 }
243
245 {
246 int i;
248
249 for (i = 0; i <
len; i++) {
250 memcpy(p, "\x00\xff\x00", 3);
251 p += step;
252 }
253 }
254
256 {
257 int i, x, y;
262
263 /* check if there is enough space to represent everything decently */
264 if (ebur128->
w < 640 || ebur128->
h < 480) {
266 "minimum size is 640x480\n", ebur128->
w, ebur128->
h);
268 }
269 outlink->
w = ebur128->
w;
270 outlink->
h = ebur128->
h;
271
272 #define PAD 8
273
274 /* configure text area position and size */
276 ebur128->
text.
y = 40;
277 ebur128->
text.
w = 3 * 8;
// 3 characters
279
280 /* configure gauge position and size */
285
286 /* configure graph position and size */
291
292 /* graph and gauge share the LU-to-pixel code */
294
295 /* prepare the initial picref buffer */
299 if (!outpicref)
302
303 /* init y references values (to draw LU lines) */
307
308 /* black background */
309 memset(outpicref->
data[0], 0, ebur128->
h * outpicref->
linesize[0]);
310
311 /* draw LU legends */
313 for (i = ebur128->
meter; i >= -ebur128->
meter * 2; i--) {
315 x =
PAD + (i < 10 && i > -10) * 8;
317 y -= 4; // -4 to center vertically
319 "%c%d", i < 0 ? '-' : i > 0 ?
'+' :
' ',
FFABS(i));
320 }
321
322 /* draw graph */
326 for (y = 0; y < ebur128->
graph.
h; y++) {
328
329 for (x = 0; x < ebur128->
graph.
w; x++)
330 memcpy(p + x*3, c, 3);
332 }
333
334 /* draw fancy rectangles around the graph and the gauge */
335 #define DRAW_RECT(r) do { \
336 drawline(outpicref, r.x, r.y - 1, r.w, 3); \
337 drawline(outpicref, r.x, r.y + r.h, r.w, 3); \
338 drawline(outpicref, r.x - 1, r.y, r.h, outpicref->linesize[0]); \
339 drawline(outpicref, r.x + r.w, r.y, r.h, outpicref->linesize[0]); \
340 } while (0)
343
344 return 0;
345 }
346
348 {
351
352 /* Force 100ms framing in case of metadata injection: the frames must have
353 * a granularity of the window overlap to be accurately exploited.
354 * As for the true peaks mode, it just simplifies the resampling buffer
355 * allocation and the lookup in it (since sample buffers differ in size, it
356 * can be more complex to integrate in the one-sample loop of
357 * filter_frame()). */
362 return 0;
363 }
364
366 {
367 int i;
371
372 #define BACK_MASK (AV_CH_BACK_LEFT |AV_CH_BACK_CENTER |AV_CH_BACK_RIGHT| \
373 AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_BACK_RIGHT| \
374 AV_CH_SIDE_LEFT |AV_CH_SIDE_RIGHT| \
375 AV_CH_SURROUND_DIRECT_LEFT |AV_CH_SURROUND_DIRECT_RIGHT)
376
381
383 /* channel weighting */
389 } else {
391 }
392
394 continue;
395
396 /* bins buffer for the two integration window (400ms and 3s) */
401 }
402
403 #if CONFIG_SWRESAMPLE
405 int ret;
406
407 ebur128->swr_buf =
av_malloc_array(nb_channels, 19200 *
sizeof(
double));
411 if (!ebur128->swr_buf || !ebur128->
true_peaks ||
414
418
422
424 if (ret < 0)
425 return ret;
426 }
427 #endif
428
433 }
434
435 return 0;
436 }
437
438 #define ENERGY(loudness) (ff_exp10(((loudness) + 0.691) / 10.))
439 #define LOUDNESS(energy) (-0.691 + 10 * log10(energy))
440 #define DBFS(energy) (20 * log10(energy))
441
443 {
444 int i;
446
447 if (!h)
452 }
454 }
455
457 {
460
465 else
467 }
468
471 "True-peak mode requires libswresample to be performed\n");
473 }
474
475 // if meter is +9 scale, scale range is from -18 LU to +9 LU (or 3*9)
476 // if meter is +18 scale, scale range is from -36 LU to +18 LU (or 3*18)
478
483
486
487 /* insert output pads */
493 };
497 }
502 };
506
507 /* summary */
509
510 return 0;
511 }
512
513 #define HIST_POS(power) (int)(((power) - ABS_THRES) * HIST_GRAIN)
514
515 /* loudness and power should be set such as loudness = -0.691 +
516 * 10*log10(power), we just avoid doing that calculus two times */
519 {
520 int ipower;
521 double relative_threshold;
522 int gate_hist_pos;
523
524 /* update powers histograms by incrementing current power count */
527
528 /* compute relative threshold and get its position in the histogram */
532 if (!relative_threshold)
533 relative_threshold = 1e-12;
536
537 return gate_hist_pos;
538 }
539
541 {
542 int i, ch, idx_insample;
547 const double *samples = (
double *)insamples->
data[0];
549
550 #if CONFIG_SWRESAMPLE
552 const double *swr_samples = ebur128->swr_buf;
555 if (ret < 0)
556 return ret;
559 for (idx_insample = 0; idx_insample < ret; idx_insample++) {
563 fabs(*swr_samples));
564 swr_samples++;
565 }
566 }
567 }
568 #endif
569
570 for (idx_insample = 0; idx_insample < nb_samples; idx_insample++) {
573
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; \
579 } \
580 } while (0)
581
584
586 double bin;
587
590
591 ebur128->
x[ch * 3] = *samples++;
// set X[i]
592
594 continue;
595
596 /* Y[i] = X[i]*b0 + X[i-1]*b1 + X[i-2]*b2 - Y[i-1]*a1 - Y[i-2]*a2 */
597 #define FILTER(Y, X, name) do { \
598 double *dst = ebur128->Y + ch*3; \
599 double *src = ebur128->X + ch*3; \
600 dst[2] = dst[1]; \
601 dst[1] = dst[0]; \
602 dst[0] = src[0]*name##_B0 + src[1]*name##_B1 + src[2]*name##_B2 \
603 - dst[1]*name##_A1 - dst[2]*name##_A2; \
604 } while (0)
605
606 // TODO: merge both filters in one?
607 FILTER(y, x, PRE);
// apply pre-filter
608 ebur128->
x[ch * 3 + 2] = ebur128->
x[ch * 3 + 1];
609 ebur128->
x[ch * 3 + 1] = ebur128->
x[ch * 3 ];
610 FILTER(z, y, RLB);
// apply RLB-filter
611
612 bin = ebur128->
z[ch * 3] * ebur128->
z[ch * 3];
613
614 /* add the new value, and limit the sum to the cache size (400ms or 3s)
615 * by removing the oldest one */
618
619 /* override old cache entry with the new value */
620 ebur128->
i400.
cache [ch][bin_id_400 ] = bin;
622 }
623
624 /* For integrated loudness, gating blocks are 400ms long with 75%
625 * overlap (see BS.1770-2 p5), so a re-computation is needed each 100ms
626 * (4800 samples at 48kHz). */
628 double loudness_400, loudness_3000;
629 double power_400 = 1e-12, power_3000 = 1e-12;
631 const int64_t
pts = insamples->
pts +
634
636
637 #define COMPUTE_LOUDNESS(m, time) do { \
638 if (ebur128->i##time.filled) { \
639 /* weighting sum of the last <time> ms */ \
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; \
643 } \
644 loudness_##time = LOUDNESS(power_##time); \
645 } while (0)
646
649
650 /* Integrated loudness */
651 #define I_GATE_THRES -10 // initially defined to -8 LU in the first EBU standard
652
654 double integrated_sum = 0;
655 int nb_integrated = 0;
658
659 /* compute integrated loudness by summing the histogram values
660 * above the relative threshold */
661 for (i = gate_hist_pos; i <
HIST_SIZE; i++) {
663 nb_integrated += nb_v;
665 }
666 if (nb_integrated) {
668 /* dual-mono correction */
669 if (nb_channels == 1 && ebur128->
dual_mono) {
671 }
672 }
673 }
674
675 /* LRA */
676 #define LRA_GATE_THRES -20
677 #define LRA_LOWER_PRC 10
678 #define LRA_HIGHER_PRC 95
679
680 /* XXX: example code in EBU 3342 is ">=" but formula in BS.1770
681 * specs is ">" */
683 int nb_powers = 0;
686
687 for (i = gate_hist_pos; i <
HIST_SIZE; i++)
691
692 /* get lower loudness to consider */
693 n = 0;
695 for (i = gate_hist_pos; i <
HIST_SIZE; i++) {
697 if (n >= nb_pow) {
699 break;
700 }
701 }
702
703 /* get higher loudness to consider */
704 n = nb_powers;
706 for (i = HIST_SIZE - 1; i >= 0; i--) {
708 if (n < nb_pow) {
710 break;
711 }
712 }
713
714 // XXX: show low & high on the graph?
716 }
717 }
718
719 /* dual-mono correction */
720 if (nb_channels == 1 && ebur128->
dual_mono) {
721 loudness_400 -= ebur128->
pan_law;
722 loudness_3000 -= ebur128->
pan_law;
723 }
724
725 #define LOG_FMT "M:%6.1f S:%6.1f I:%6.1f LUFS LRA:%6.1f LU"
726
727 /* push one video frame */
729 int x, y, ret;
731
732 const int y_loudness_lu_graph =
lu_to_y(ebur128, loudness_3000 + 23);
733 const int y_loudness_lu_gauge =
lu_to_y(ebur128, loudness_400 + 23);
734
735 /* draw the graph using the short-term loudness */
736 p = pic->data[0] + ebur128->
graph.
y*pic->linesize[0] + ebur128->
graph.
x*3;
737 for (y = 0; y < ebur128->
graph.
h; y++) {
739
740 memmove(p, p + 3, (ebur128->
graph.
w - 1) * 3);
741 memcpy(p + (ebur128->
graph.
w - 1) * 3, c, 3);
742 p += pic->linesize[0];
743 }
744
745 /* draw the gauge using the momentary loudness */
746 p = pic->data[0] + ebur128->
gauge.
y*pic->linesize[0] + ebur128->
gauge.
x*3;
747 for (y = 0; y < ebur128->
gauge.
h; y++) {
749
750 for (x = 0; x < ebur128->
gauge.
w; x++)
751 memcpy(p + x*3, c, 3);
752 p += pic->linesize[0];
753 }
754
755 /* draw textual info */
757 LOG_FMT " ",
// padding to erase trailing characters
758 loudness_400, loudness_3000,
760
761 /* set pts and push frame */
764 if (ret < 0)
765 return ret;
766 }
767
768 if (ebur128->
metadata) {
/* happens only once per filter_frame call */
769 char metabuf[128];
770 #define META_PREFIX "lavfi.r128."
771
772 #define SET_META(name, var) do { \
773 snprintf(metabuf, sizeof(metabuf), "%.3f", var); \
774 av_dict_set(&insamples->metadata, name, metabuf, 0); \
775 } while (0)
776
777 #define SET_META_PEAK(name, ptype) do { \
778 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
779 char key[64]; \
780 for (ch = 0; ch < nb_channels; ch++) { \
781 snprintf(key, sizeof(key), \
782 META_PREFIX AV_STRINGIFY(name) "_peaks_ch%d", ch); \
783 SET_META(key, ebur128->name##_peaks[ch]); \
784 } \
785 } \
786 } while (0)
787
794
797 }
798
801 loudness_400, loudness_3000,
803
804 #define PRINT_PEAKS(str, sp, ptype) do { \
805 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
806 av_log(ctx, ebur128->loglevel, " " str ":"); \
807 for (ch = 0; ch < nb_channels; ch++) \
808 av_log(ctx, ebur128->loglevel, " %5.1f", DBFS(sp[ch])); \
809 av_log(ctx, ebur128->loglevel, " dBFS"); \
810 } \
811 } while (0)
812
817 }
818 }
819
821 }
822
824 {
830 int ret;
831
833 static const int input_srate[] = {48000, -1}; // ITU-R BS.1770 provides coeff only for 48kHz
835
836 /* set optional output video format */
840 return ret;
842 }
843
844 /* set input and output audio formats
845 * Note: ff_set_common_* functions are not used because they affect all the
846 * links, and thus break the video format negotiation */
850 return ret;
851
855 return ret;
856
860 return ret;
861
862 return 0;
863 }
864
866 {
867 int i;
869
870 /* dual-mono correction */
876 }
877
879 " Integrated loudness:\n"
880 " I: %5.1f LUFS\n"
881 " Threshold: %5.1f LUFS\n\n"
882 " Loudness range:\n"
883 " LRA: %5.1f LU\n"
884 " Threshold: %5.1f LUFS\n"
885 " LRA low: %5.1f LUFS\n"
886 " LRA high: %5.1f LUFS",
890
891 #define PRINT_PEAK_SUMMARY(str, sp, ptype) do { \
892 int ch; \
893 double maxpeak; \
894 maxpeak = 0.0; \
895 if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \
896 for (ch = 0; ch < ebur128->nb_channels; ch++) \
897 maxpeak = FFMAX(maxpeak, sp[ch]); \
898 av_log(ctx, AV_LOG_INFO, "\n\n " str " peak:\n" \
899 " Peak: %5.1f dBFS", \
900 DBFS(maxpeak)); \
901 } \
902 } while (0)
903
907
918 }
922 #if CONFIG_SWRESAMPLE
925 #endif
926 }
927
929 {
934 },
936 };
937
947 .priv_class = &ebur128_class,
949 };
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)
#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.
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 outputs[]
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.
static const AVFilterPad inputs[]
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.
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.
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
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 calulate 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.
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)