diff mbox series

[FFmpeg-devel,v1,3/4] avfilter/af_loudnorm: Add support for two pass stats for measure

Message ID 20200409110720.6965-3-lance.lmwang@gmail.com
State New
Headers show
Series [FFmpeg-devel,v1,1/4] avfilter/af_loudnorm: Add file option for the measured stats
Related show

Checks

Context Check Description
andriy/ffmpeg-patchwork pending
andriy/ffmpeg-patchwork success Applied patch
andriy/ffmpeg-patchwork success Configure finished
andriy/ffmpeg-patchwork success Make finished
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Limin Wang April 9, 2020, 11:07 a.m. UTC
From: Limin Wang <lance.lmwang@gmail.com>

Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
---
 libavfilter/af_loudnorm.c | 41 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/libavfilter/af_loudnorm.c b/libavfilter/af_loudnorm.c
index 3012aa2471..380d0570d4 100644
--- a/libavfilter/af_loudnorm.c
+++ b/libavfilter/af_loudnorm.c
@@ -96,6 +96,7 @@  typedef struct LoudNormContext {
     int above_threshold;
     int prev_nb_samples;
     int channels;
+    int pass;
 
     FFEBUR128State *r128_in;
     FFEBUR128State *r128_out;
@@ -128,6 +129,7 @@  static const AVOption loudnorm_options[] = {
     {     "compact",      0,                                   0,                        AV_OPT_TYPE_CONST,   {.i64 =  COMPACT},  0,         0,  FLAGS, "print_format" },
     { "file", "set file path for the measured stats",          OFFSET(filename),         AV_OPT_TYPE_STRING,  {.str=NULL},                       FLAGS },
     { "f",    "set file path for the measured stats",          OFFSET(filename),         AV_OPT_TYPE_STRING,  {.str=NULL},                       FLAGS },
+    { "pass", "enable two pass stats for measure",             OFFSET(pass),             AV_OPT_TYPE_INT,     {.i64 =  -1},       -1,        2,  FLAGS },
     { NULL }
 };
 
@@ -833,11 +835,42 @@  static av_cold int init(AVFilterContext *ctx)
     }
 
     if (s->print_format != NONE && s->filename) {
+        if (s->pass == 1 && s->print_format != COMPACT) {
+            av_log(ctx, AV_LOG_ERROR, "first pass must be in compact format\n");
+            return AVERROR_INVALIDDATA;
+        }
         s->print = print_file;
     } else {
         s->print = print_log;
     }
 
+    /* load first pass stats for second pass*/
+    if (s->filename && s->pass == 2) {
+        char buf[1024] = { 0 };
+        FILE *f = av_fopen_utf8(s->filename, "r");
+        if (!f) {
+            av_log(ctx, AV_LOG_ERROR, "Could not open %s\n", s->filename);
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (fgets(buf, sizeof(buf)-1, f)) {
+            if (sscanf(buf, "input_i: %lf, input_tp: %lf, input_lra: %lf, input_thresh: %lf, target_offset: %lf\n",
+                        &s->measured_i, &s->measured_lra, &s->measured_tp, &s->measured_thresh,
+                        &s->offset) != 5) {
+                av_log(ctx, AV_LOG_ERROR, "Invalid first pass stats file(%s) for parse\n", s->filename);
+                return AVERROR_INVALIDDATA;
+            }
+            av_log(ctx, AV_LOG_INFO, "load first pass stats: measured_i %.2f, measured_lra: %.2f, "
+                    "measured_tp: %.2f, measured_thresh: %.2f, target_offset: %.2f\n",
+                    s->measured_i, s->measured_lra, s->measured_tp, s->measured_thresh, s->offset);
+        } else {
+            av_log(ctx, AV_LOG_ERROR, "Invalid first pass stats file(%s) for parse\n", s->filename);
+            return AVERROR_INVALIDDATA;
+        }
+
+        fclose(f);
+    }
+
     if (s->filename) {
         int ret = avio_open(&s->pb, s->filename, AVIO_FLAG_WRITE);
         if (ret < 0) {
@@ -912,7 +945,13 @@  static av_cold void uninit(AVFilterContext *ctx)
         break;
 
     case COMPACT:
-        s->print(ctx, "input_i: %.2f, input_tp: %.2f, input_lra: %.2f, input_thresh: %.2f, "
+        if (s->pass == 1)
+            s->print(ctx, "input_i: %.2f, input_tp: %.2f, input_lra: %.2f, input_thresh: %.2f, "
+                    "target_offset: %.2f \n",
+                  i_in, 20. * log10(tp_in), lra_in, thresh_in,
+                  s->target_i - i_out);
+        else
+            s->print(ctx, "input_i: %.2f, input_tp: %.2f, input_lra: %.2f, input_thresh: %.2f, "
                  "output_i: %.2f, output_tp: %.2f, output_lra: %.2f, output_thresh: %.2f, "
                   "normalization_type: %s, target_offset: %.2f\n",
                   i_in, 20. * log10(tp_in), lra_in, thresh_in,