[FFmpeg-devel] [PATCH] lavfi: psnr filter

Derek Buitenhuis derek.buitenhuis at gmail.com
Sun Jul 7 20:54:16 CEST 2013


On 7/6/2013 7:54 AM, Paul B Mahol wrote:
> diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c
> new file mode 100644
> index 0000000..9b87a61
> --- /dev/null
> +++ b/libavfilter/vf_psnr.c
> @@ -0,0 +1,310 @@
> +/*
> + * Copyright (c) 2011 Roger Pau Monn� <roger.pau at entel.upc.edu>

This doesn't display right for me... maybe I'm mussing some unicode symbol?
Seems to show up fine in Google Chrome, though.

> +    {"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 },

"Where to store per-frame difference information."

> +    if (s->stats_file) {
> +        fprintf(s->stats_file, "n:%d mse_avg:%0.2f ", s->nb_frames, mse);
> +        for (j = 0; j < s->desc->nb_components; j++) {
> +            c = s->is_rgb ? s->rgba_map[j] : j;
> +            fprintf(s->stats_file, "mse_%c:%0.2f ", s->comps[j], comp_mse[c]);
> +        }
> +        for (j = 0; j < s->desc->nb_components; j++) {
> +            c = s->is_rgb ? s->rgba_map[j] : j;
> +            fprintf(s->stats_file, "s%c:%0.2f ",
> +                    s->comps[j], get_psnr(comp_mse[c], 1, s->max[c]));
> +        }
> +        fprintf(s->stats_file, "\n");
> +    }

This is really useless for anything but the ffmpeg CLI util. libavfilter now
has facilities to to properly pass back information via the library API metadata.

For example:
    http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavfilter/af_silencedetect.c;h=eb4718b268099d203562de57263ab56d929bc44e;hb=HEAD#l97

It shouldn't be much work to change it to and/or add this, and it actually makes
libavfilter useful.

> +    if (s->stats_file_str) {
> +        s->stats_file = fopen(s->stats_file_str, "w");
> +        if (!s->stats_file) {
> +            av_log(ctx, AV_LOG_ERROR,
> +                   "Could not open stats file %s: %s\n",
> +                   s->stats_file_str, strerror(errno));
> +            return AVERROR(EINVAL);
> +        }
> +    }

Ditto.

> +    s->desc = av_pix_fmt_desc_get(inlink->format);
> +    if (ctx->inputs[0]->w != ctx->inputs[1]->w ||
> +        ctx->inputs[0]->h != ctx->inputs[1]->h) {
> +        av_log(ctx, AV_LOG_ERROR,
> +               "Width and/or heigth of input videos are different, could not calculate PSNR\n");
> +        return AVERROR(EINVAL);
> +    }
> +    if (ctx->inputs[0]->format != ctx->inputs[1]->format) {
> +        av_log(ctx, AV_LOG_ERROR,
> +               "Input filters have different pixel formats, could not calculate PSNR\n");
> +        return AVERROR(EINVAL);
> +    }

Can we not compare nb_frames to make sure they're the same length? What
sort of behavior does this filter exhibit if two clips of varying length
are given?

> +    s->is_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0;
> +    s->comps[0] = s->is_rgb ? 'r' : 'y' ;
> +    s->comps[1] = s->is_rgb ? 'g' : 'u' ;
> +    s->comps[2] = s->is_rgb ? 'b' : 'v' ;
> +    s->comps[3] = 'a';

No XYZ? :P

- Derek


More information about the ffmpeg-devel mailing list