[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