FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vf_psnr.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Roger Pau Monné
3  * Copyright (c) 2011 Stefano Sabatini
4  * Copyright (c) 2013 Paul B Mahol
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /**
24  * @file
25  * Caculate the PSNR between two input videos.
26  */
27 
28 #include "libavutil/opt.h"
29 #include "libavutil/pixdesc.h"
30 #include "avfilter.h"
31 #include "dualinput.h"
32 #include "drawutils.h"
33 #include "formats.h"
34 #include "internal.h"
35 #include "video.h"
36 
37 typedef struct PSNRContext {
38  const AVClass *class;
40  double mse, min_mse, max_mse;
41  uint64_t nb_frames;
42  FILE *stats_file;
44  int max[4], average_max;
45  int is_rgb;
47  char comps[4];
49  int planewidth[4];
50  int planeheight[4];
51 
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]);
56 } PSNRContext;
57 
58 #define OFFSET(x) offsetof(PSNRContext, x)
59 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
60 
61 static const AVOption psnr_options[] = {
62  {"stats_file", "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
63  {"f", "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
64  { NULL }
65 };
66 
68 
69 static inline unsigned pow2(unsigned base)
70 {
71  return base*base;
72 }
73 
74 static inline double get_psnr(double mse, uint64_t nb_frames, int max)
75 {
76  return 10.0 * log(pow2(max) / (mse / nb_frames)) / log(10.0);
77 }
78 
79 static inline
81  const uint8_t *main_data[4], const int main_linesizes[4],
82  const uint8_t *ref_data[4], const int ref_linesizes[4],
83  int w, int h, double mse[4])
84 {
85  int i, c, j;
86 
87  for (c = 0; c < s->nb_components; c++) {
88  const int outw = s->planewidth[c];
89  const int outh = s->planeheight[c];
90  const uint8_t *main_line = main_data[c];
91  const uint8_t *ref_line = ref_data[c];
92  const int ref_linesize = ref_linesizes[c];
93  const int main_linesize = main_linesizes[c];
94  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
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]);
128  ref_line += ref_linesize;
129  main_line += main_linesize;
130  }
131  mse[c] = m / (double)(outw * outh);
132  }
133 }
134 
135 static void set_meta(AVDictionary **metadata, const char *key, char comp, float d)
136 {
137  char value[128];
138  snprintf(value, sizeof(value), "%0.2f", d);
139  if (comp) {
140  char key2[128];
141  snprintf(key2, sizeof(key2), "%s%c", key, comp);
142  av_dict_set(metadata, key2, value, 0);
143  } else {
144  av_dict_set(metadata, key, value, 0);
145  }
146 }
147 
149  const AVFrame *ref)
150 {
151  PSNRContext *s = ctx->priv;
152  double comp_mse[4], mse = 0;
153  int j, c;
154  AVDictionary **metadata = avpriv_frame_get_metadatap(main);
155 
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);
159 
160  for (j = 0; j < s->nb_components; j++)
161  mse += comp_mse[j];
162  mse /= s->nb_components;
163 
164  s->min_mse = FFMIN(s->min_mse, mse);
165  s->max_mse = FFMAX(s->max_mse, mse);
166 
167  s->mse += mse;
168  s->nb_frames++;
169 
170  for (j = 0; j < s->nb_components; j++) {
171  c = s->is_rgb ? s->rgba_map[j] : j;
172  set_meta(metadata, "lavfi.psnr.mse.", s->comps[j], comp_mse[c]);
173  set_meta(metadata, "lavfi.psnr.mse_avg", 0, mse);
174  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  }
177 
178  if (s->stats_file) {
179  fprintf(s->stats_file, "n:%"PRId64" mse_avg:%0.2f ", s->nb_frames, mse);
180  for (j = 0; j < s->nb_components; j++) {
181  c = s->is_rgb ? s->rgba_map[j] : j;
182  fprintf(s->stats_file, "mse_%c:%0.2f ", s->comps[j], comp_mse[c]);
183  }
184  for (j = 0; j < s->nb_components; j++) {
185  c = s->is_rgb ? s->rgba_map[j] : j;
186  fprintf(s->stats_file, "psnr_%c:%0.2f ", s->comps[j],
187  get_psnr(comp_mse[c], 1, s->max[c]));
188  }
189  fprintf(s->stats_file, "\n");
190  }
191 
192  return main;
193 }
194 
195 static av_cold int init(AVFilterContext *ctx)
196 {
197  PSNRContext *s = ctx->priv;
198 
199  s->min_mse = +INFINITY;
200  s->max_mse = -INFINITY;
201 
202  if (s->stats_file_str) {
203  s->stats_file = fopen(s->stats_file_str, "w");
204  if (!s->stats_file) {
205  int err = AVERROR(errno);
206  char buf[128];
207  av_strerror(err, buf, sizeof(buf));
208  av_log(ctx, AV_LOG_ERROR, "Could not open stats file %s: %s\n",
209  s->stats_file_str, buf);
210  return err;
211  }
212  }
213 
214  s->dinput.process = do_psnr;
215  return 0;
216 }
217 
219 {
220  static const enum AVPixelFormat pix_fmts[] = {
222 #define PF_NOALPHA(suf) AV_PIX_FMT_YUV420##suf, AV_PIX_FMT_YUV422##suf, AV_PIX_FMT_YUV444##suf
223 #define PF_ALPHA(suf) AV_PIX_FMT_YUVA420##suf, AV_PIX_FMT_YUVA422##suf, AV_PIX_FMT_YUVA444##suf
224 #define PF(suf) PF_NOALPHA(suf), PF_ALPHA(suf)
225  PF(P), PF(P9), PF(P10), PF_NOALPHA(P12), PF_NOALPHA(P14), PF(P16),
233  };
234 
235  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
236  if (!fmts_list)
237  return AVERROR(ENOMEM);
238  return ff_set_common_formats(ctx, fmts_list);
239 }
240 
241 static int config_input_ref(AVFilterLink *inlink)
242 {
243  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
244  AVFilterContext *ctx = inlink->dst;
245  PSNRContext *s = ctx->priv;
246  int j;
247 
248  s->nb_components = desc->nb_components;
249  if (ctx->inputs[0]->w != ctx->inputs[1]->w ||
250  ctx->inputs[0]->h != ctx->inputs[1]->h) {
251  av_log(ctx, AV_LOG_ERROR, "Width and height of input videos must be same.\n");
252  return AVERROR(EINVAL);
253  }
254  if (ctx->inputs[0]->format != ctx->inputs[1]->format) {
255  av_log(ctx, AV_LOG_ERROR, "Inputs must be of same pixel format.\n");
256  return AVERROR(EINVAL);
257  }
258 
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  }
286 
287  s->is_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0;
288  s->comps[0] = s->is_rgb ? 'r' : 'y' ;
289  s->comps[1] = s->is_rgb ? 'g' : 'u' ;
290  s->comps[2] = s->is_rgb ? 'b' : 'v' ;
291  s->comps[3] = 'a';
292 
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  s->planeheight[1] = s->planeheight[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
298  s->planeheight[0] = s->planeheight[3] = inlink->h;
299  s->planewidth[1] = s->planewidth[2] = FF_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
300  s->planewidth[0] = s->planewidth[3] = inlink->w;
301 
303 
304  return 0;
305 }
306 
307 static int config_output(AVFilterLink *outlink)
308 {
309  AVFilterContext *ctx = outlink->src;
310  PSNRContext *s = ctx->priv;
311  AVFilterLink *mainlink = ctx->inputs[0];
312  int ret;
313 
314  outlink->w = mainlink->w;
315  outlink->h = mainlink->h;
316  outlink->time_base = mainlink->time_base;
317  outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio;
318  outlink->frame_rate = mainlink->frame_rate;
319  if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0)
320  return ret;
321 
322  return 0;
323 }
324 
325 static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
326 {
327  PSNRContext *s = inlink->dst->priv;
328  return ff_dualinput_filter_frame(&s->dinput, inlink, inpicref);
329 }
330 
331 static int request_frame(AVFilterLink *outlink)
332 {
333  PSNRContext *s = outlink->src->priv;
334  return ff_dualinput_request_frame(&s->dinput, outlink);
335 }
336 
337 static av_cold void uninit(AVFilterContext *ctx)
338 {
339  PSNRContext *s = ctx->priv;
340 
341  if (s->nb_frames > 0) {
342  av_log(ctx, AV_LOG_INFO, "PSNR average:%0.2f min:%0.2f max:%0.2f\n",
343  get_psnr(s->mse, s->nb_frames, s->average_max),
344  get_psnr(s->max_mse, 1, s->average_max),
345  get_psnr(s->min_mse, 1, s->average_max));
346  }
347 
349 
350  if (s->stats_file)
351  fclose(s->stats_file);
352 }
353 
354 static const AVFilterPad psnr_inputs[] = {
355  {
356  .name = "main",
357  .type = AVMEDIA_TYPE_VIDEO,
358  .filter_frame = filter_frame,
359  },{
360  .name = "reference",
361  .type = AVMEDIA_TYPE_VIDEO,
362  .filter_frame = filter_frame,
363  .config_props = config_input_ref,
364  },
365  { NULL }
366 };
367 
368 static const AVFilterPad psnr_outputs[] = {
369  {
370  .name = "default",
371  .type = AVMEDIA_TYPE_VIDEO,
372  .config_props = config_output,
373  .request_frame = request_frame,
374  },
375  { NULL }
376 };
377 
379  .name = "psnr",
380  .description = NULL_IF_CONFIG_SMALL("Calculate the PSNR between two video streams."),
381  .init = init,
382  .uninit = uninit,
383  .query_formats = query_formats,
384  .priv_size = sizeof(PSNRContext),
385  .priv_class = &psnr_class,
386  .inputs = psnr_inputs,
387  .outputs = psnr_outputs,
388 };
double max_mse
Definition: vf_psnr.c:40
#define PF_NOALPHA(suf)
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:631
#define P
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2090
This structure describes decoded (raw) audio or video data.
Definition: frame.h:171
AVOption.
Definition: opt.h:255
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:248
Main libavfilter public API header.
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:176
int planewidth[4]
Definition: vf_psnr.c:49
static AVFrame * do_psnr(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
Definition: vf_psnr.c:148
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:380
char * stats_file_str
Definition: vf_psnr.c:43
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
int max[4]
Definition: vf_psnr.c:44
static int request_frame(AVFilterLink *outlink)
Definition: vf_psnr.c:331
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
#define OFFSET(x)
Definition: vf_psnr.c:58
const char * name
Pad name.
Definition: internal.h:67
int ff_dualinput_filter_frame(FFDualInputContext *s, AVFilterLink *inlink, AVFrame *in)
Definition: dualinput.c:69
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:641
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:100
uint8_t
#define av_cold
Definition: attributes.h:74
static double get_psnr(double mse, uint64_t nb_frames, int max)
Definition: vf_psnr.c:74
static 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])
Definition: vf_psnr.c:80
AVOptions.
double min_mse
Definition: vf_psnr.c:40
#define PF(suf)
static double psnr(double d)
Definition: ffmpeg.c:1183
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
Definition: vf_psnr.c:325
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:379
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
Definition: pixfmt.h:102
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:76
void ff_dualinput_uninit(FFDualInputContext *s)
Definition: dualinput.c:80
#define av_log(a,...)
unsigned m
Definition: audioconvert.c:187
int is_rgb
Definition: vf_psnr.c:45
A filter pad used for either input or output.
Definition: internal.h:61
uint16_t depth_minus1
Number of bits in the component minus 1.
Definition: pixdesc.h:57
int width
width and height of the video frame
Definition: frame.h:220
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:542
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
#define AVERROR(e)
Definition: error.h:43
uint8_t rgba_map[4]
Definition: vf_psnr.c:46
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:175
static int config_input_ref(AVFilterLink *inlink)
Definition: vf_psnr.c:241
const char * r
Definition: vf_curves.c:107
void * priv
private data for use by the filter
Definition: avfilter.h:654
FFDualInputContext dinput
Definition: vf_psnr.c:39
#define FFMAX(a, b)
Definition: common.h:64
char comps[4]
Definition: vf_psnr.c:47
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_psnr.c:337
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:384
int planeheight[4]
Definition: vf_psnr.c:50
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:383
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:348
#define FFMIN(a, b)
Definition: common.h:66
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:75
ret
Definition: avfilter.c:974
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
static void set_meta(AVDictionary **metadata, const char *key, char comp, float d)
Definition: vf_psnr.c:135
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:109
#define FF_CEIL_RSHIFT(a, b)
Definition: common.h:57
static int config_output(AVFilterLink *outlink)
Definition: vf_psnr.c:307
uint64_t nb_frames
Definition: vf_psnr.c:41
static av_cold int init(AVFilterContext *ctx)
Definition: vf_psnr.c:195
static void compute_images_mse_16bit(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])
Definition: vf_psnr.c:109
AVFrame *(* process)(AVFilterContext *ctx, AVFrame *main, const AVFrame *second)
Definition: dualinput.h:36
static unsigned pow2(unsigned base)
Definition: vf_psnr.c:69
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:382
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:33
#define INFINITY
Definition: math.h:27
FILE * stats_file
Definition: vf_psnr.c:42
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
#define FLAGS
Definition: vf_psnr.c:59
misc drawing utilities
AVDictionary ** avpriv_frame_get_metadatap(AVFrame *frame)
Definition: frame.c:47
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:199
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
void * buf
Definition: avisynth_c.h:553
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:69
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:69
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:470
static const AVFilterPad inputs[]
Definition: af_ashowinfo.c:239
const char * name
Filter name.
Definition: avfilter.h:474
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])
Definition: vf_psnr.c:52
#define snprintf
Definition: snprintf.h:34
int ff_dualinput_init(AVFilterContext *ctx, FFDualInputContext *s)
Definition: dualinput.c:43
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:381
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:182
double mse
Definition: vf_psnr.c:40
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf.
Definition: error.c:68
static const AVFilterPad psnr_inputs[]
Definition: vf_psnr.c:354
Y , 8bpp.
Definition: pixfmt.h:71
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:287
static double c[64]
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:77
static const AVFilterPad psnr_outputs[]
Definition: vf_psnr.c:368
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:70
static const AVOption psnr_options[]
Definition: vf_psnr.c:61
int nb_components
Definition: vf_psnr.c:48
static int query_formats(AVFilterContext *ctx)
Definition: vf_psnr.c:218
Double input streams helper for filters.
AVFILTER_DEFINE_CLASS(psnr)
A list of supported formats for one end of a filter link.
Definition: formats.h:64
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:290
An instance of a filter.
Definition: avfilter.h:633
int ff_dualinput_request_frame(FFDualInputContext *s, AVFilterLink *outlink)
Definition: dualinput.c:75
AVFilter ff_vf_psnr
Definition: vf_psnr.c:378
int height
Definition: frame.h:220
static void comp(unsigned char *dst, int dst_stride, unsigned char *src, int src_stride, int add)
Definition: eamad.c:83
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:101
int main(int argc, char **argv)
Definition: main.c:22
internal API functions
AVPixelFormat
Pixel format.
Definition: pixfmt.h:61
int average_max
Definition: vf_psnr.c:44