From 6ef2315aafe352998fd612dd6cd21c4eb9731031 Mon Sep 17 00:00:00 2001 From: Jean First Date: Sat, 25 Jan 2014 23:19:06 +0100 Subject: [PATCH] lavfi/ebur128: print peak metering in dBFS Signed-off-by: Jean First --- doc/filters.texi | 7 ++++--- libavfilter/f_ebur128.c | 35 ++++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 7c6b945987..f04b30f8d5 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -9334,13 +9334,14 @@ Disable any peak mode (default). @item sample Enable sample-peak mode. -Simple peak mode looking for the higher sample value. +Simple peak mode looking for the higher sample value. It logs a message +for sample-peak (identified by @code{SPK}). @item true Enable true-peak mode. If enabled, the peak lookup is done on an over-sampled version of the input -stream for better peak accuracy. This mode requires a build with -@code{libswresample}. +stream for better peak accuracy. It logs a message for true-peak. +(identified by @code{TPK}). This mode requires a build with @code{libswresample}. @end table @end table diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c index 503d87ac32..53815ec161 100644 --- a/libavfilter/f_ebur128.c +++ b/libavfilter/f_ebur128.c @@ -23,7 +23,6 @@ * EBU R.128 implementation * @see http://tech.ebu.ch/loudness * @see https://www.youtube.com/watch?v=iuEtQqC-Sqo "EBU R128 Introduction - Florian Camerer" - * @todo True Peak * @todo implement start/stop/reset through filter command injection * @todo support other frequencies to avoid resampling */ @@ -443,6 +442,7 @@ static int config_audio_output(AVFilterLink *outlink) #define ENERGY(loudness) (pow(10, ((loudness) + 0.691) / 10.)) #define LOUDNESS(energy) (-0.691 + 10 * log10(energy)) +#define DBFS(energy) (20 * log10(energy)) static struct hist_entry *get_histogram(void) { @@ -791,13 +791,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) loudness_400, loudness_3000, ebur128->integrated_loudness, ebur128->loudness_range); -#define PRINT_PEAKS(str, sp, ptype) do { \ - if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \ - av_log(ctx, ebur128->loglevel, " [" str ":"); \ - for (ch = 0; ch < nb_channels; ch++) \ - av_log(ctx, ebur128->loglevel, " %.5f", sp[ch]); \ - av_log(ctx, ebur128->loglevel, "]"); \ - } \ +#define PRINT_PEAKS(str, sp, ptype) do { \ + if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \ + av_log(ctx, ebur128->loglevel, " " str ":"); \ + for (ch = 0; ch < nb_channels; ch++) \ + av_log(ctx, ebur128->loglevel, " %5.1f", DBFS(sp[ch])); \ + av_log(ctx, ebur128->loglevel, " dBFS"); \ + } \ } while (0) PRINT_PEAKS("SPK", ebur128->sample_peaks, SAMPLES); @@ -867,11 +867,28 @@ static av_cold void uninit(AVFilterContext *ctx) " LRA: %5.1f LU\n" " Threshold: %5.1f LUFS\n" " LRA low: %5.1f LUFS\n" - " LRA high: %5.1f LUFS\n", + " LRA high: %5.1f LUFS", ebur128->integrated_loudness, ebur128->i400.rel_threshold, ebur128->loudness_range, ebur128->i3000.rel_threshold, ebur128->lra_low, ebur128->lra_high); +#define PRINT_PEAK_SUMMARY(str, sp, ptype) do { \ + int ch; \ + double maxpeak; \ + maxpeak = 0.0; \ + if (ebur128->peak_mode & PEAK_MODE_ ## ptype ## _PEAKS) { \ + for (ch = 0; ch < ebur128->nb_channels; ch++) \ + maxpeak = FFMAX(maxpeak, sp[ch]); \ + av_log(ctx, AV_LOG_INFO, "\n\n " str " peak:\n" \ + " Peak: %5.1f dBFS", \ + DBFS(maxpeak)); \ + } \ +} while (0) + + PRINT_PEAK_SUMMARY("Sample", ebur128->sample_peaks, SAMPLES); + PRINT_PEAK_SUMMARY("True", ebur128->true_peaks, TRUE); + av_log(ctx, AV_LOG_INFO, "\n"); + av_freep(&ebur128->y_line_ref); av_freep(&ebur128->ch_weighting); av_freep(&ebur128->true_peaks);