]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/vf_psnr.c
lavc/alsdec: use get_bitsz() to simplify reading of the mantissa
[ffmpeg] / libavfilter / vf_psnr.c
index 89acd3ca76eabe759a66c5271c18a0ac5986283a..320f43307ec2dd2b4c71036263d835de24d32efc 100644 (file)
@@ -43,6 +43,9 @@ typedef struct PSNRContext {
     uint64_t nb_frames;
     FILE *stats_file;
     char *stats_file_str;
+    int stats_version;
+    int stats_header_written;
+    int stats_add_max;
     int max[4], average_max;
     int is_rgb;
     uint8_t rgba_map[4];
@@ -60,6 +63,8 @@ typedef struct PSNRContext {
 static const AVOption psnr_options[] = {
     {"stats_file", "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
     {"f",          "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
+    {"stats_version", "Set the format version for the stats file.",               OFFSET(stats_version),  AV_OPT_TYPE_INT,    {.i64=1},    1, 2, FLAGS },
+    {"output_max",  "Add raw stats (max values) to the output log.",            OFFSET(stats_add_max), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
     { NULL }
 };
 
@@ -169,6 +174,25 @@ static AVFrame *do_psnr(AVFilterContext *ctx, AVFrame *main,
     set_meta(metadata, "lavfi.psnr.psnr_avg", 0, get_psnr(mse, 1, s->average_max));
 
     if (s->stats_file) {
+        if (s->stats_version == 2 && !s->stats_header_written) {
+            fprintf(s->stats_file, "psnr_log_version:2 fields:n");
+            fprintf(s->stats_file, ",mse_avg");
+            for (j = 0; j < s->nb_components; j++) {
+                fprintf(s->stats_file, ",mse_%c", s->comps[j]);
+            }
+            fprintf(s->stats_file, ",psnr_avg");
+            for (j = 0; j < s->nb_components; j++) {
+                fprintf(s->stats_file, ",psnr_%c", s->comps[j]);
+            }
+            if (s->stats_add_max) {
+                fprintf(s->stats_file, ",max_avg");
+                for (j = 0; j < s->nb_components; j++) {
+                    fprintf(s->stats_file, ",max_%c", s->comps[j]);
+                }
+            }
+            fprintf(s->stats_file, "\n");
+            s->stats_header_written = 1;
+        }
         fprintf(s->stats_file, "n:%"PRId64" mse_avg:%0.2f ", s->nb_frames, mse);
         for (j = 0; j < s->nb_components; j++) {
             c = s->is_rgb ? s->rgba_map[j] : j;
@@ -180,6 +204,13 @@ static AVFrame *do_psnr(AVFilterContext *ctx, AVFrame *main,
             fprintf(s->stats_file, "psnr_%c:%0.2f ", s->comps[j],
                     get_psnr(comp_mse[c], 1, s->max[c]));
         }
+        if (s->stats_version == 2 && s->stats_add_max) {
+            fprintf(s->stats_file, "max_avg:%d ", s->average_max);
+            for (j = 0; j < s->nb_components; j++) {
+                c = s->is_rgb ? s->rgba_map[j] : j;
+                fprintf(s->stats_file, "max_%c:%d ", s->comps[j], s->max[c]);
+            }
+        }
         fprintf(s->stats_file, "\n");
     }
 
@@ -194,6 +225,11 @@ static av_cold int init(AVFilterContext *ctx)
     s->max_mse = -INFINITY;
 
     if (s->stats_file_str) {
+        if (s->stats_version < 2 && s->stats_add_max) {
+            av_log(ctx, AV_LOG_ERROR,
+                "stats_add_max was specified but stats_version < 2.\n" );
+            return AVERROR(EINVAL);
+        }
         if (!strcmp(s->stats_file_str, "-")) {
             s->stats_file = stdout;
         } else {
@@ -241,6 +277,7 @@ static int config_input_ref(AVFilterLink *inlink)
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     AVFilterContext *ctx  = inlink->dst;
     PSNRContext *s = ctx->priv;
+    double average_max;
     unsigned sum;
     int j;
 
@@ -273,10 +310,12 @@ static int config_input_ref(AVFilterLink *inlink)
     sum = 0;
     for (j = 0; j < s->nb_components; j++)
         sum += s->planeheight[j] * s->planewidth[j];
+    average_max = 0;
     for (j = 0; j < s->nb_components; j++) {
         s->planeweight[j] = (double) s->planeheight[j] * s->planewidth[j] / sum;
-        s->average_max += s->max[j] * s->planeweight[j];
+        average_max += s->max[j] * s->planeweight[j];
     }
+    s->average_max = lrint(average_max);
 
     s->dsp.sse_line = desc->comp[0].depth > 8 ? sse_line_16bit : sse_line_8bit;
     if (ARCH_X86)