~ubuntu-branches/debian/sid/ffmpeg/sid

« back to all changes in this revision

Viewing changes to libavfilter/vf_psnr.c

  • Committer: Package Import Robot
  • Author(s): Andreas Cadhalpun, Fabian Greffrath, Andreas Cadhalpun
  • Date: 2015-09-22 15:15:20 UTC
  • mfrom: (0.1.29)
  • Revision ID: package-import@ubuntu.com-20150922151520-hhmd3in9ykigjvs9
Tags: 7:2.8-1
[ Fabian Greffrath ]
* Pass the --dbg-package=ffmpeg-dbg parameter only to dh_strip.
* Add alternative Depends: libavcodec-ffmpeg-extra56 to libavcodec-dev and
  ffmpeg-dbg to allow for building and debugging with this library installed.

[ Andreas Cadhalpun ]
* Import new major upstream release 2.8.
* Remove the transitional lib*-ffmpeg-dev packages.
* Drop old Breaks on kodi-bin.
* Drop workaround for sparc, which is no Debian architecture anymore.
* Re-enable x265 on alpha, as it's available again.
* Disable unavailable frei0r, opencv and x264 on mips64el.
* Disable libopenjpeg (#787275) and libschroedinger (#787957) decoders.
  (Closes: #786670)
* Disable libdc1394 on sparc64, because it links against the broken due to
  #790560 libudev1.
* Enable libsnappy support.
* Add new symbols.
* Update debian/copyright.
* Update debian/tests/encdec_list.txt.
* Add hls-only-seek-if-there-is-an-offset.patch. (Closes: #798189)
* Add 'Breaks: libavutil-ffmpeg54 (>= 8:0)' to the libraries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2011 Roger Pau Monn� <roger.pau@entel.upc.edu>
 
2
 * Copyright (c) 2011 Roger Pau Monné <roger.pau@entel.upc.edu>
3
3
 * Copyright (c) 2011 Stefano Sabatini
4
4
 * Copyright (c) 2013 Paul B Mahol
5
5
 *
25
25
 * Caculate the PSNR between two input videos.
26
26
 */
27
27
 
 
28
#include "libavutil/avstring.h"
28
29
#include "libavutil/opt.h"
29
30
#include "libavutil/pixdesc.h"
30
31
#include "avfilter.h"
32
33
#include "drawutils.h"
33
34
#include "formats.h"
34
35
#include "internal.h"
 
36
#include "psnr.h"
35
37
#include "video.h"
36
38
 
37
39
typedef struct PSNRContext {
38
40
    const AVClass *class;
39
41
    FFDualInputContext dinput;
40
 
    double mse, min_mse, max_mse;
 
42
    double mse, min_mse, max_mse, mse_comp[4];
41
43
    uint64_t nb_frames;
42
44
    FILE *stats_file;
43
45
    char *stats_file_str;
48
50
    int nb_components;
49
51
    int planewidth[4];
50
52
    int planeheight[4];
51
 
 
52
 
    void (*compute_mse)(struct PSNRContext *s,
53
 
                        const uint8_t *m[4], const int ml[4],
54
 
                        const uint8_t *r[4], const int rl[4],
55
 
                        int w, int h, double mse[4]);
 
53
    double planeweight[4];
 
54
    PSNRDSPContext dsp;
56
55
} PSNRContext;
57
56
 
58
57
#define OFFSET(x) offsetof(PSNRContext, x)
76
75
    return 10.0 * log(pow2(max) / (mse / nb_frames)) / log(10.0);
77
76
}
78
77
 
 
78
static uint64_t sse_line_8bit(const uint8_t *main_line,  const uint8_t *ref_line, int outw)
 
79
{
 
80
    int j;
 
81
    unsigned m2 = 0;
 
82
 
 
83
    for (j = 0; j < outw; j++)
 
84
        m2 += pow2(main_line[j] - ref_line[j]);
 
85
 
 
86
    return m2;
 
87
}
 
88
 
 
89
static uint64_t sse_line_16bit(const uint8_t *_main_line, const uint8_t *_ref_line, int outw)
 
90
{
 
91
    int j;
 
92
    uint64_t m2 = 0;
 
93
    const uint16_t *main_line = (const uint16_t *) _main_line;
 
94
    const uint16_t *ref_line = (const uint16_t *) _ref_line;
 
95
 
 
96
    for (j = 0; j < outw; j++)
 
97
        m2 += pow2(main_line[j] - ref_line[j]);
 
98
 
 
99
    return m2;
 
100
}
 
101
 
79
102
static inline
80
103
void compute_images_mse(PSNRContext *s,
81
104
                        const uint8_t *main_data[4], const int main_linesizes[4],
82
105
                        const uint8_t *ref_data[4], const int ref_linesizes[4],
83
106
                        int w, int h, double mse[4])
84
107
{
85
 
    int i, c, j;
 
108
    int i, c;
86
109
 
87
110
    for (c = 0; c < s->nb_components; c++) {
88
111
        const int outw = s->planewidth[c];
92
115
        const int ref_linesize = ref_linesizes[c];
93
116
        const int main_linesize = main_linesizes[c];
94
117
        uint64_t m = 0;
95
 
 
96
 
        for (i = 0; i < outh; i++) {
97
 
            int m2 = 0;
98
 
            for (j = 0; j < outw; j++)
99
 
                m2 += pow2(main_line[j] - ref_line[j]);
100
 
            m += m2;
101
 
            ref_line += ref_linesize;
102
 
            main_line += main_linesize;
103
 
        }
104
 
        mse[c] = m / (double)(outw * outh);
105
 
    }
106
 
}
107
 
 
108
 
static inline
109
 
void compute_images_mse_16bit(PSNRContext *s,
110
 
                        const uint8_t *main_data[4], const int main_linesizes[4],
111
 
                        const uint8_t *ref_data[4], const int ref_linesizes[4],
112
 
                        int w, int h, double mse[4])
113
 
{
114
 
    int i, c, j;
115
 
 
116
 
    for (c = 0; c < s->nb_components; c++) {
117
 
        const int outw = s->planewidth[c];
118
 
        const int outh = s->planeheight[c];
119
 
        const uint16_t *main_line = (uint16_t *)main_data[c];
120
 
        const uint16_t *ref_line = (uint16_t *)ref_data[c];
121
 
        const int ref_linesize = ref_linesizes[c] / 2;
122
 
        const int main_linesize = main_linesizes[c] / 2;
123
 
        uint64_t m = 0;
124
 
 
125
 
        for (i = 0; i < outh; i++) {
126
 
            for (j = 0; j < outw; j++)
127
 
                m += pow2(main_line[j] - ref_line[j]);
 
118
        for (i = 0; i < outh; i++) {
 
119
            m += s->dsp.sse_line(main_line, ref_line, outw);
128
120
            ref_line += ref_linesize;
129
121
            main_line += main_linesize;
130
122
        }
153
145
    int j, c;
154
146
    AVDictionary **metadata = avpriv_frame_get_metadatap(main);
155
147
 
156
 
    s->compute_mse(s, (const uint8_t **)main->data, main->linesize,
157
 
                      (const uint8_t **)ref->data, ref->linesize,
158
 
                       main->width, main->height, comp_mse);
 
148
    compute_images_mse(s, (const uint8_t **)main->data, main->linesize,
 
149
                          (const uint8_t **)ref->data, ref->linesize,
 
150
                          main->width, main->height, comp_mse);
159
151
 
160
152
    for (j = 0; j < s->nb_components; j++)
161
 
        mse += comp_mse[j];
162
 
    mse /= s->nb_components;
 
153
        mse += comp_mse[j] * s->planeweight[j];
163
154
 
164
155
    s->min_mse = FFMIN(s->min_mse, mse);
165
156
    s->max_mse = FFMAX(s->max_mse, mse);
166
157
 
167
158
    s->mse += mse;
 
159
    for (j = 0; j < s->nb_components; j++)
 
160
        s->mse_comp[j] += comp_mse[j];
168
161
    s->nb_frames++;
169
162
 
170
163
    for (j = 0; j < s->nb_components; j++) {
171
164
        c = s->is_rgb ? s->rgba_map[j] : j;
172
165
        set_meta(metadata, "lavfi.psnr.mse.", s->comps[j], comp_mse[c]);
173
 
        set_meta(metadata, "lavfi.psnr.mse_avg", 0, mse);
174
166
        set_meta(metadata, "lavfi.psnr.psnr.", s->comps[j], get_psnr(comp_mse[c], 1, s->max[c]));
175
 
        set_meta(metadata, "lavfi.psnr.psnr_avg", 0, get_psnr(mse, 1, s->average_max));
176
167
    }
 
168
    set_meta(metadata, "lavfi.psnr.mse_avg", 0, mse);
 
169
    set_meta(metadata, "lavfi.psnr.psnr_avg", 0, get_psnr(mse, 1, s->average_max));
177
170
 
178
171
    if (s->stats_file) {
179
172
        fprintf(s->stats_file, "n:%"PRId64" mse_avg:%0.2f ", s->nb_frames, mse);
181
174
            c = s->is_rgb ? s->rgba_map[j] : j;
182
175
            fprintf(s->stats_file, "mse_%c:%0.2f ", s->comps[j], comp_mse[c]);
183
176
        }
 
177
        fprintf(s->stats_file, "psnr_avg:%0.2f ", get_psnr(mse, 1, s->average_max));
184
178
        for (j = 0; j < s->nb_components; j++) {
185
179
            c = s->is_rgb ? s->rgba_map[j] : j;
186
180
            fprintf(s->stats_file, "psnr_%c:%0.2f ", s->comps[j],
243
237
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
244
238
    AVFilterContext *ctx  = inlink->dst;
245
239
    PSNRContext *s = ctx->priv;
 
240
    unsigned sum;
246
241
    int j;
247
242
 
248
243
    s->nb_components = desc->nb_components;
256
251
        return AVERROR(EINVAL);
257
252
    }
258
253
 
259
 
    switch (inlink->format) {
260
 
    case AV_PIX_FMT_GRAY8:
261
 
    case AV_PIX_FMT_GRAY16:
262
 
    case AV_PIX_FMT_GBRP:
263
 
    case AV_PIX_FMT_GBRP9:
264
 
    case AV_PIX_FMT_GBRP10:
265
 
    case AV_PIX_FMT_GBRP12:
266
 
    case AV_PIX_FMT_GBRP14:
267
 
    case AV_PIX_FMT_GBRP16:
268
 
    case AV_PIX_FMT_GBRAP:
269
 
    case AV_PIX_FMT_GBRAP16:
270
 
    case AV_PIX_FMT_YUVJ411P:
271
 
    case AV_PIX_FMT_YUVJ420P:
272
 
    case AV_PIX_FMT_YUVJ422P:
273
 
    case AV_PIX_FMT_YUVJ440P:
274
 
    case AV_PIX_FMT_YUVJ444P:
275
 
        s->max[0] = (1 << (desc->comp[0].depth_minus1 + 1)) - 1;
276
 
        s->max[1] = (1 << (desc->comp[1].depth_minus1 + 1)) - 1;
277
 
        s->max[2] = (1 << (desc->comp[2].depth_minus1 + 1)) - 1;
278
 
        s->max[3] = (1 << (desc->comp[3].depth_minus1 + 1)) - 1;
279
 
        break;
280
 
    default:
281
 
        s->max[0] = 235 * (1 << (desc->comp[0].depth_minus1 - 7));
282
 
        s->max[1] = 240 * (1 << (desc->comp[1].depth_minus1 - 7));
283
 
        s->max[2] = 240 * (1 << (desc->comp[2].depth_minus1 - 7));
284
 
        s->max[3] = (1 << (desc->comp[3].depth_minus1 + 1)) - 1;
285
 
    }
 
254
    s->max[0] = (1 << (desc->comp[0].depth_minus1 + 1)) - 1;
 
255
    s->max[1] = (1 << (desc->comp[1].depth_minus1 + 1)) - 1;
 
256
    s->max[2] = (1 << (desc->comp[2].depth_minus1 + 1)) - 1;
 
257
    s->max[3] = (1 << (desc->comp[3].depth_minus1 + 1)) - 1;
286
258
 
287
259
    s->is_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0;
288
260
    s->comps[0] = s->is_rgb ? 'r' : 'y' ;
290
262
    s->comps[2] = s->is_rgb ? 'b' : 'v' ;
291
263
    s->comps[3] = 'a';
292
264
 
293
 
    for (j = 0; j < s->nb_components; j++)
294
 
        s->average_max += s->max[j];
295
 
    s->average_max /= s->nb_components;
296
 
 
297
265
    s->planeheight[1] = s->planeheight[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
298
266
    s->planeheight[0] = s->planeheight[3] = inlink->h;
299
267
    s->planewidth[1]  = s->planewidth[2]  = FF_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
300
268
    s->planewidth[0]  = s->planewidth[3]  = inlink->w;
 
269
    sum = 0;
 
270
    for (j = 0; j < s->nb_components; j++)
 
271
        sum += s->planeheight[j] * s->planewidth[j];
 
272
    for (j = 0; j < s->nb_components; j++) {
 
273
        s->planeweight[j] = (double) s->planeheight[j] * s->planewidth[j] / sum;
 
274
        s->average_max += s->max[j] * s->planeweight[j];
 
275
    }
301
276
 
302
 
    s->compute_mse = desc->comp[0].depth_minus1 > 7 ? compute_images_mse_16bit : compute_images_mse;
 
277
    s->dsp.sse_line = desc->comp[0].depth_minus1 > 7 ? sse_line_16bit : sse_line_8bit;
 
278
    if (ARCH_X86)
 
279
        ff_psnr_init_x86(&s->dsp, desc->comp[0].depth_minus1 + 1);
303
280
 
304
281
    return 0;
305
282
}
339
316
    PSNRContext *s = ctx->priv;
340
317
 
341
318
    if (s->nb_frames > 0) {
342
 
        av_log(ctx, AV_LOG_INFO, "PSNR average:%0.2f min:%0.2f max:%0.2f\n",
 
319
        int j;
 
320
        char buf[256];
 
321
 
 
322
        buf[0] = 0;
 
323
        for (j = 0; j < s->nb_components; j++) {
 
324
            int c = s->is_rgb ? s->rgba_map[j] : j;
 
325
            av_strlcatf(buf, sizeof(buf), " %c:%0.2f", s->comps[j],
 
326
                        get_psnr(s->mse_comp[c], s->nb_frames, s->max[c]));
 
327
        }
 
328
        av_log(ctx, AV_LOG_INFO, "PSNR%s average:%0.2f min:%0.2f max:%0.2f\n",
 
329
               buf,
343
330
               get_psnr(s->mse, s->nb_frames, s->average_max),
344
331
               get_psnr(s->max_mse, 1, s->average_max),
345
332
               get_psnr(s->min_mse, 1, s->average_max));