X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_psnr.c;h=9390f7c625f07e8488fc02f5cd8159ed18090c29;hb=9a829a2b6a7a5bc7f6fb492577daaaec43c9f6c8;hp=b2c6531621b772c3bf4dea3f677aa955cbb87f44;hpb=0303d43964cdcab868d3f765282c00086f3a8123;p=ffmpeg diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c index b2c6531621b..9390f7c625f 100644 --- a/libavfilter/vf_psnr.c +++ b/libavfilter/vf_psnr.c @@ -33,6 +33,7 @@ #include "drawutils.h" #include "formats.h" #include "internal.h" +#include "psnr.h" #include "video.h" typedef struct PSNRContext { @@ -50,11 +51,7 @@ typedef struct PSNRContext { int planewidth[4]; int planeheight[4]; double planeweight[4]; - - void (*compute_mse)(struct PSNRContext *s, - const uint8_t *m[4], const int ml[4], - const uint8_t *r[4], const int rl[4], - int w, int h, double mse[4]); + PSNRDSPContext dsp; } PSNRContext; #define OFFSET(x) offsetof(PSNRContext, x) @@ -78,55 +75,48 @@ static inline double get_psnr(double mse, uint64_t nb_frames, int max) return 10.0 * log(pow2(max) / (mse / nb_frames)) / log(10.0); } -static inline -void compute_images_mse(PSNRContext *s, - const uint8_t *main_data[4], const int main_linesizes[4], - const uint8_t *ref_data[4], const int ref_linesizes[4], - int w, int h, double mse[4]) +static uint64_t sse_line_8bit(const uint8_t *main_line, const uint8_t *ref_line, int outw) { - int i, c, j; + int j; + unsigned m2 = 0; - for (c = 0; c < s->nb_components; c++) { - const int outw = s->planewidth[c]; - const int outh = s->planeheight[c]; - const uint8_t *main_line = main_data[c]; - const uint8_t *ref_line = ref_data[c]; - const int ref_linesize = ref_linesizes[c]; - const int main_linesize = main_linesizes[c]; - uint64_t m = 0; + for (j = 0; j < outw; j++) + m2 += pow2(main_line[j] - ref_line[j]); - for (i = 0; i < outh; i++) { - int m2 = 0; - for (j = 0; j < outw; j++) - m2 += pow2(main_line[j] - ref_line[j]); - m += m2; - ref_line += ref_linesize; - main_line += main_linesize; - } - mse[c] = m / (double)(outw * outh); - } + return m2; +} + +static uint64_t sse_line_16bit(const uint8_t *_main_line, const uint8_t *_ref_line, int outw) +{ + int j; + uint64_t m2 = 0; + const uint16_t *main_line = (const uint16_t *) _main_line; + const uint16_t *ref_line = (const uint16_t *) _ref_line; + + for (j = 0; j < outw; j++) + m2 += pow2(main_line[j] - ref_line[j]); + + return m2; } static inline -void compute_images_mse_16bit(PSNRContext *s, +void compute_images_mse(PSNRContext *s, const uint8_t *main_data[4], const int main_linesizes[4], const uint8_t *ref_data[4], const int ref_linesizes[4], int w, int h, double mse[4]) { - int i, c, j; + int i, c; for (c = 0; c < s->nb_components; c++) { const int outw = s->planewidth[c]; const int outh = s->planeheight[c]; - const uint16_t *main_line = (uint16_t *)main_data[c]; - const uint16_t *ref_line = (uint16_t *)ref_data[c]; - const int ref_linesize = ref_linesizes[c] / 2; - const int main_linesize = main_linesizes[c] / 2; + const uint8_t *main_line = main_data[c]; + const uint8_t *ref_line = ref_data[c]; + const int ref_linesize = ref_linesizes[c]; + const int main_linesize = main_linesizes[c]; uint64_t m = 0; - for (i = 0; i < outh; i++) { - for (j = 0; j < outw; j++) - m += pow2(main_line[j] - ref_line[j]); + m += s->dsp.sse_line(main_line, ref_line, outw); ref_line += ref_linesize; main_line += main_linesize; } @@ -155,9 +145,9 @@ static AVFrame *do_psnr(AVFilterContext *ctx, AVFrame *main, int j, c; AVDictionary **metadata = avpriv_frame_get_metadatap(main); - s->compute_mse(s, (const uint8_t **)main->data, main->linesize, - (const uint8_t **)ref->data, ref->linesize, - main->width, main->height, comp_mse); + compute_images_mse(s, (const uint8_t **)main->data, main->linesize, + (const uint8_t **)ref->data, ref->linesize, + main->width, main->height, comp_mse); for (j = 0; j < s->nb_components; j++) mse += comp_mse[j] * s->planeweight[j]; @@ -173,10 +163,10 @@ static AVFrame *do_psnr(AVFilterContext *ctx, AVFrame *main, for (j = 0; j < s->nb_components; j++) { c = s->is_rgb ? s->rgba_map[j] : j; set_meta(metadata, "lavfi.psnr.mse.", s->comps[j], comp_mse[c]); - set_meta(metadata, "lavfi.psnr.mse_avg", 0, mse); set_meta(metadata, "lavfi.psnr.psnr.", s->comps[j], get_psnr(comp_mse[c], 1, s->max[c])); - set_meta(metadata, "lavfi.psnr.psnr_avg", 0, get_psnr(mse, 1, s->average_max)); } + set_meta(metadata, "lavfi.psnr.mse_avg", 0, mse); + set_meta(metadata, "lavfi.psnr.psnr_avg", 0, get_psnr(mse, 1, s->average_max)); if (s->stats_file) { fprintf(s->stats_file, "n:%"PRId64" mse_avg:%0.2f ", s->nb_frames, mse); @@ -260,33 +250,10 @@ static int config_input_ref(AVFilterLink *inlink) return AVERROR(EINVAL); } - switch (inlink->format) { - case AV_PIX_FMT_GRAY8: - case AV_PIX_FMT_GRAY16: - case AV_PIX_FMT_GBRP: - case AV_PIX_FMT_GBRP9: - case AV_PIX_FMT_GBRP10: - case AV_PIX_FMT_GBRP12: - case AV_PIX_FMT_GBRP14: - case AV_PIX_FMT_GBRP16: - case AV_PIX_FMT_GBRAP: - case AV_PIX_FMT_GBRAP16: - case AV_PIX_FMT_YUVJ411P: - case AV_PIX_FMT_YUVJ420P: - case AV_PIX_FMT_YUVJ422P: - case AV_PIX_FMT_YUVJ440P: - case AV_PIX_FMT_YUVJ444P: - s->max[0] = (1 << (desc->comp[0].depth_minus1 + 1)) - 1; - s->max[1] = (1 << (desc->comp[1].depth_minus1 + 1)) - 1; - s->max[2] = (1 << (desc->comp[2].depth_minus1 + 1)) - 1; - s->max[3] = (1 << (desc->comp[3].depth_minus1 + 1)) - 1; - break; - default: - s->max[0] = 235 * (1 << (desc->comp[0].depth_minus1 - 7)); - s->max[1] = 240 * (1 << (desc->comp[1].depth_minus1 - 7)); - s->max[2] = 240 * (1 << (desc->comp[2].depth_minus1 - 7)); - s->max[3] = (1 << (desc->comp[3].depth_minus1 + 1)) - 1; - } + s->max[0] = (1 << (desc->comp[0].depth_minus1 + 1)) - 1; + s->max[1] = (1 << (desc->comp[1].depth_minus1 + 1)) - 1; + s->max[2] = (1 << (desc->comp[2].depth_minus1 + 1)) - 1; + s->max[3] = (1 << (desc->comp[3].depth_minus1 + 1)) - 1; s->is_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0; s->comps[0] = s->is_rgb ? 'r' : 'y' ; @@ -306,7 +273,9 @@ static int config_input_ref(AVFilterLink *inlink) s->average_max += s->max[j] * s->planeweight[j]; } - s->compute_mse = desc->comp[0].depth_minus1 > 7 ? compute_images_mse_16bit : compute_images_mse; + s->dsp.sse_line = desc->comp[0].depth_minus1 > 7 ? sse_line_16bit : sse_line_8bit; + if (ARCH_X86) + ff_psnr_init_x86(&s->dsp, desc->comp[0].depth_minus1 + 1); return 0; } @@ -350,9 +319,11 @@ static av_cold void uninit(AVFilterContext *ctx) char buf[256]; buf[0] = 0; - for (j = 0; j < s->nb_components; j++) + for (j = 0; j < s->nb_components; j++) { + int c = s->is_rgb ? s->rgba_map[j] : j; av_strlcatf(buf, sizeof(buf), " %c:%0.2f", s->comps[j], - get_psnr(s->mse_comp[j], s->nb_frames, s->max[j])); + get_psnr(s->mse_comp[c], s->nb_frames, s->max[c])); + } av_log(ctx, AV_LOG_INFO, "PSNR%s average:%0.2f min:%0.2f max:%0.2f\n", buf, get_psnr(s->mse, s->nb_frames, s->average_max),