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

lance.lmwang at gmail.com lance.lmwang at gmail.com
Thu Apr 9 14:07:19 EEST 2020


From: Limin Wang <lance.lmwang at gmail.com>

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

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,
-- 
2.21.0



More information about the ffmpeg-devel mailing list