FFmpeg
vf_libvmaf.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Ronald S. Bultje <rsbultje@gmail.com>
3  * Copyright (c) 2017 Ashish Pratap Singh <ashk43712@gmail.com>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * Calculate the VMAF between two input videos.
25  */
26 
27 #include <libvmaf.h>
28 
29 #include "libavutil/avstring.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/pixdesc.h"
32 #include "avfilter.h"
33 #include "drawutils.h"
34 #include "formats.h"
35 #include "framesync.h"
36 #include "internal.h"
37 #include "video.h"
38 
39 typedef struct LIBVMAFContext {
40  const AVClass *class;
42  char *model_path;
43  char *log_path;
44  char *log_fmt;
47  int psnr;
48  int ssim;
49  int ms_ssim;
50  char *pool;
51  int n_threads;
54  char *model_cfg;
55  char *feature_cfg;
56  VmafContext *vmaf;
57  VmafModel **model;
58  unsigned model_cnt;
59  unsigned frame_cnt;
60  unsigned bpc;
62 
63 #define OFFSET(x) offsetof(LIBVMAFContext, x)
64 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
65 
66 static const AVOption libvmaf_options[] = {
67  {"model_path", "use model='path=...'.", OFFSET(model_path), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
68  {"log_path", "Set the file path to be used to write log.", OFFSET(log_path), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
69  {"log_fmt", "Set the format of the log (csv, json, xml, or sub).", OFFSET(log_fmt), AV_OPT_TYPE_STRING, {.str="xml"}, 0, 1, FLAGS},
70  {"enable_transform", "use model='enable_transform=true'.", OFFSET(enable_transform), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
71  {"phone_model", "use model='enable_transform=true'.", OFFSET(phone_model), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
72  {"psnr", "use feature='name=psnr'.", OFFSET(psnr), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
73  {"ssim", "use feature='name=ssim'.", OFFSET(ssim), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
74  {"ms_ssim", "use feature='name=ms_ssim'.", OFFSET(ms_ssim), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
75  {"pool", "Set the pool method to be used for computing vmaf.", OFFSET(pool), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
76  {"n_threads", "Set number of threads to be used when computing vmaf.", OFFSET(n_threads), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT_MAX, FLAGS},
77  {"n_subsample", "Set interval for frame subsampling used when computing vmaf.", OFFSET(n_subsample), AV_OPT_TYPE_INT, {.i64=1}, 1, UINT_MAX, FLAGS},
78  {"enable_conf_interval", "model='enable_conf_interval=true'.", OFFSET(enable_conf_interval), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
79  {"model", "Set the model to be used for computing vmaf.", OFFSET(model_cfg), AV_OPT_TYPE_STRING, {.str="version=vmaf_v0.6.1"}, 0, 1, FLAGS},
80  {"feature", "Set the feature to be used for computing vmaf.", OFFSET(feature_cfg), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
81  { NULL }
82 };
83 
85 
86 static enum VmafPixelFormat pix_fmt_map(enum AVPixelFormat av_pix_fmt)
87 {
88  switch (av_pix_fmt) {
89  case AV_PIX_FMT_YUV420P:
93  return VMAF_PIX_FMT_YUV420P;
94  case AV_PIX_FMT_YUV422P:
98  return VMAF_PIX_FMT_YUV422P;
99  case AV_PIX_FMT_YUV444P:
103  return VMAF_PIX_FMT_YUV444P;
104  default:
105  return VMAF_PIX_FMT_UNKNOWN;
106  }
107 }
108 
109 static int copy_picture_data(AVFrame *src, VmafPicture *dst, unsigned bpc)
110 {
111  int err = vmaf_picture_alloc(dst, pix_fmt_map(src->format), bpc,
112  src->width, src->height);
113  if (err)
114  return AVERROR(ENOMEM);
115 
116  for (unsigned i = 0; i < 3; i++) {
117  uint8_t *src_data = src->data[i];
118  uint8_t *dst_data = dst->data[i];
119  for (unsigned j = 0; j < dst->h[i]; j++) {
120  memcpy(dst_data, src_data, sizeof(*dst_data) * dst->w[i]);
121  src_data += src->linesize[i];
122  dst_data += dst->stride[i];
123  }
124  }
125 
126  return 0;
127 }
128 
129 static int do_vmaf(FFFrameSync *fs)
130 {
131  AVFilterContext *ctx = fs->parent;
132  LIBVMAFContext *s = ctx->priv;
133  VmafPicture pic_ref, pic_dist;
134  AVFrame *ref, *dist;
135  int err = 0;
136 
137  int ret = ff_framesync_dualinput_get(fs, &dist, &ref);
138  if (ret < 0)
139  return ret;
140  if (ctx->is_disabled || !ref)
141  return ff_filter_frame(ctx->outputs[0], dist);
142 
143  err = copy_picture_data(ref, &pic_ref, s->bpc);
144  if (err) {
145  av_log(s, AV_LOG_ERROR, "problem during vmaf_picture_alloc.\n");
146  return AVERROR(ENOMEM);
147  }
148 
149  err = copy_picture_data(dist, &pic_dist, s->bpc);
150  if (err) {
151  av_log(s, AV_LOG_ERROR, "problem during vmaf_picture_alloc.\n");
152  vmaf_picture_unref(&pic_ref);
153  return AVERROR(ENOMEM);
154  }
155 
156  err = vmaf_read_pictures(s->vmaf, &pic_ref, &pic_dist, s->frame_cnt++);
157  if (err) {
158  av_log(s, AV_LOG_ERROR, "problem during vmaf_read_pictures.\n");
159  return AVERROR(EINVAL);
160  }
161 
162  return ff_filter_frame(ctx->outputs[0], dist);
163 }
164 
165 
166 static AVDictionary **delimited_dict_parse(char *str, unsigned *cnt)
167 {
168  AVDictionary **dict = NULL;
169  char *str_copy = NULL;
170  char *saveptr = NULL;
171  unsigned cnt2;
172  int err = 0;
173 
174  if (!str)
175  return NULL;
176 
177  cnt2 = 1;
178  for (char *p = str; *p; p++) {
179  if (*p == '|')
180  cnt2++;
181  }
182 
183  dict = av_calloc(cnt2, sizeof(*dict));
184  if (!dict)
185  goto fail;
186 
187  str_copy = av_strdup(str);
188  if (!str_copy)
189  goto fail;
190 
191  *cnt = 0;
192  for (unsigned i = 0; i < cnt2; i++) {
193  char *s = av_strtok(i == 0 ? str_copy : NULL, "|", &saveptr);
194  if (!s)
195  continue;
196  err = av_dict_parse_string(&dict[(*cnt)++], s, "=", ":", 0);
197  if (err)
198  goto fail;
199  }
200 
201  av_free(str_copy);
202  return dict;
203 
204 fail:
205  if (dict) {
206  for (unsigned i = 0; i < *cnt; i++) {
207  if (dict[i])
208  av_dict_free(&dict[i]);
209  }
210  av_free(dict);
211  }
212 
213  av_free(str_copy);
214  *cnt = 0;
215  return NULL;
216 }
217 
219 {
220  LIBVMAFContext *s = ctx->priv;
221  AVDictionary **dict = NULL;
222  unsigned dict_cnt;
223  int err = 0;
224 
225  if (!s->feature_cfg)
226  return 0;
227 
228  dict = delimited_dict_parse(s->feature_cfg, &dict_cnt);
229  if (!dict) {
231  "could not parse feature config: %s\n", s->feature_cfg);
232  return AVERROR(EINVAL);
233  }
234 
235  for (unsigned i = 0; i < dict_cnt; i++) {
236  char *feature_name = NULL;
237  VmafFeatureDictionary *feature_opts_dict = NULL;
238  AVDictionaryEntry *e = NULL;
239 
240  while (e = av_dict_get(dict[i], "", e, AV_DICT_IGNORE_SUFFIX)) {
241  if (av_stristr(e->key, "name")) {
242  feature_name = e->value;
243  continue;
244  }
245 
246  err = vmaf_feature_dictionary_set(&feature_opts_dict, e->key,
247  e->value);
248  if (err) {
250  "could not set feature option: %s.%s=%s\n",
251  feature_name, e->key, e->value);
252  goto exit;
253  }
254  }
255 
256  err = vmaf_use_feature(s->vmaf, feature_name, feature_opts_dict);
257  if (err) {
259  "problem during vmaf_use_feature: %s\n", feature_name);
260  goto exit;
261  }
262  }
263 
264 exit:
265  for (unsigned i = 0; i < dict_cnt; i++) {
266  if (dict[i])
267  av_dict_free(&dict[i]);
268  }
269  av_free(dict);
270  return err;
271 }
272 
274 {
275  LIBVMAFContext *s = ctx->priv;
276  AVDictionary **dict;
277  unsigned dict_cnt;
278  int err = 0;
279 
280  if (!s->model_cfg) return 0;
281 
282  dict_cnt = 0;
283  dict = delimited_dict_parse(s->model_cfg, &dict_cnt);
284  if (!dict) {
286  "could not parse model config: %s\n", s->model_cfg);
287  return AVERROR(EINVAL);
288  }
289 
290  s->model_cnt = dict_cnt;
291  s->model = av_calloc(s->model_cnt, sizeof(*s->model));
292  if (!s->model)
293  return AVERROR(ENOMEM);
294 
295  for (unsigned i = 0; i < dict_cnt; i++) {
296  VmafModelConfig model_cfg = { 0 };
297  AVDictionaryEntry *e = NULL;
298  char *version = NULL;
299  char *path = NULL;
300 
301  while (e = av_dict_get(dict[i], "", e, AV_DICT_IGNORE_SUFFIX)) {
302  if (av_stristr(e->key, "disable_clip")) {
303  model_cfg.flags |= av_stristr(e->value, "true") ?
304  VMAF_MODEL_FLAG_DISABLE_CLIP : 0;
305  continue;
306  }
307 
308  if (av_stristr(e->key, "enable_transform")) {
309  model_cfg.flags |= av_stristr(e->value, "true") ?
310  VMAF_MODEL_FLAG_ENABLE_TRANSFORM : 0;
311  continue;
312  }
313 
314  if (av_stristr(e->key, "name")) {
315  model_cfg.name = e->value;
316  continue;
317  }
318 
319  if (av_stristr(e->key, "version")) {
320  version = e->value;
321  continue;
322  }
323 
324  if (av_stristr(e->key, "path")) {
325  path = e->value;
326  continue;
327  }
328  }
329 
330  if (version) {
331  err = vmaf_model_load(&s->model[i], &model_cfg, version);
332  if (err) {
334  "could not load libvmaf model with version: %s\n",
335  version);
336  goto exit;
337  }
338  }
339 
340  if (path && !s->model[i]) {
341  err = vmaf_model_load_from_path(&s->model[i], &model_cfg, path);
342  if (err) {
344  "could not load libvmaf model with path: %s\n",
345  path);
346  goto exit;
347  }
348  }
349 
350  if (!s->model[i]) {
352  "could not load libvmaf model with config: %s\n",
353  s->model_cfg);
354  goto exit;
355  }
356 
357  while (e = av_dict_get(dict[i], "", e, AV_DICT_IGNORE_SUFFIX)) {
358  VmafFeatureDictionary *feature_opts_dict = NULL;
359  char *feature_opt = NULL;
360 
361  char *feature_name = av_strtok(e->key, ".", &feature_opt);
362  if (!feature_opt)
363  continue;
364 
365  err = vmaf_feature_dictionary_set(&feature_opts_dict,
366  feature_opt, e->value);
367  if (err) {
369  "could not set feature option: %s.%s=%s\n",
370  feature_name, feature_opt, e->value);
371  err = AVERROR(EINVAL);
372  goto exit;
373  }
374 
375  err = vmaf_model_feature_overload(s->model[i], feature_name,
376  feature_opts_dict);
377  if (err) {
379  "could not overload feature: %s\n", feature_name);
380  err = AVERROR(EINVAL);
381  goto exit;
382  }
383  }
384  }
385 
386  for (unsigned i = 0; i < s->model_cnt; i++) {
387  err = vmaf_use_features_from_model(s->vmaf, s->model[i]);
388  if (err) {
390  "problem during vmaf_use_features_from_model\n");
391  err = AVERROR(EINVAL);
392  goto exit;
393  }
394  }
395 
396 exit:
397  for (unsigned i = 0; i < dict_cnt; i++) {
398  if (dict[i])
399  av_dict_free(&dict[i]);
400  }
401  av_free(dict);
402  return err;
403 }
404 
405 static enum VmafLogLevel log_level_map(int log_level)
406 {
407  switch (log_level) {
408  case AV_LOG_QUIET:
409  return VMAF_LOG_LEVEL_NONE;
410  case AV_LOG_ERROR:
411  return VMAF_LOG_LEVEL_ERROR;
412  case AV_LOG_WARNING:
413  return VMAF_LOG_LEVEL_WARNING;
414  case AV_LOG_INFO:
415  return VMAF_LOG_LEVEL_INFO;
416  case AV_LOG_DEBUG:
417  return VMAF_LOG_LEVEL_DEBUG;
418  default:
419  return VMAF_LOG_LEVEL_INFO;
420  }
421 }
422 
424 {
425  LIBVMAFContext *s = ctx->priv;
426  VmafModel *model = NULL;
427  VmafModelCollection *model_collection = NULL;
428  enum VmafModelFlags flags = VMAF_MODEL_FLAGS_DEFAULT;
429  int err = 0;
430 
431  VmafModelConfig model_cfg = {
432  .name = "vmaf",
433  .flags = flags,
434  };
435 
436  if (s->enable_transform || s->phone_model)
437  flags |= VMAF_MODEL_FLAG_ENABLE_TRANSFORM;
438 
439  if (!s->model_path)
440  goto extra_metrics_only;
441 
442  if (s->enable_conf_interval) {
443  err = vmaf_model_collection_load_from_path(&model, &model_collection,
444  &model_cfg, s->model_path);
445  if (err) {
447  "problem loading model file: %s\n", s->model_path);
448  goto exit;
449  }
450 
451  err = vmaf_use_features_from_model_collection(s->vmaf, model_collection);
452  if (err) {
454  "problem loading feature extractors from model file: %s\n",
455  s->model_path);
456  goto exit;
457  }
458  } else {
459  err = vmaf_model_load_from_path(&model, &model_cfg, s->model_path);
460  if (err) {
462  "problem loading model file: %s\n", s->model_path);
463  goto exit;
464  }
465  err = vmaf_use_features_from_model(s->vmaf, model);
466  if (err) {
468  "problem loading feature extractors from model file: %s\n",
469  s->model_path);
470  goto exit;
471  }
472  }
473 
474 extra_metrics_only:
475  if (s->psnr) {
476  VmafFeatureDictionary *d = NULL;
477  vmaf_feature_dictionary_set(&d, "enable_chroma", "false");
478 
479  err = vmaf_use_feature(s->vmaf, "psnr", d);
480  if (err) {
482  "problem loading feature extractor: psnr\n");
483  goto exit;
484  }
485  }
486 
487  if (s->ssim) {
488  err = vmaf_use_feature(s->vmaf, "float_ssim", NULL);
489  if (err) {
491  "problem loading feature extractor: ssim\n");
492  goto exit;
493  }
494  }
495 
496  if (s->ms_ssim) {
497  err = vmaf_use_feature(s->vmaf, "float_ms_ssim", NULL);
498  if (err) {
500  "problem loading feature extractor: ms_ssim\n");
501  goto exit;
502  }
503  }
504 
505 exit:
506  return err;
507 }
508 
510 {
511  LIBVMAFContext *s = ctx->priv;
512  int err = 0;
513 
514  VmafConfiguration cfg = {
515  .log_level = log_level_map(av_log_get_level()),
516  .n_subsample = s->n_subsample,
517  .n_threads = s->n_threads,
518  };
519 
520  err = vmaf_init(&s->vmaf, cfg);
521  if (err)
522  return AVERROR(EINVAL);
523 
525  if (err)
526  return err;
527 
528  err = parse_models(ctx);
529  if (err)
530  return err;
531 
532  err = parse_features(ctx);
533  if (err)
534  return err;
535 
536  s->fs.on_event = do_vmaf;
537  return 0;
538 }
539 
540 static const enum AVPixelFormat pix_fmts[] = {
544 };
545 
547 {
548  AVFilterContext *ctx = inlink->dst;
549  LIBVMAFContext *s = ctx->priv;
550  const AVPixFmtDescriptor *desc;
551  int err = 0;
552 
553  if (ctx->inputs[0]->w != ctx->inputs[1]->w) {
554  av_log(ctx, AV_LOG_ERROR, "input width must match.\n");
555  err |= AVERROR(EINVAL);
556  }
557 
558  if (ctx->inputs[0]->h != ctx->inputs[1]->h) {
559  av_log(ctx, AV_LOG_ERROR, "input height must match.\n");
560  err |= AVERROR(EINVAL);
561  }
562 
563  if (ctx->inputs[0]->format != ctx->inputs[1]->format) {
564  av_log(ctx, AV_LOG_ERROR, "input pix_fmt must match.\n");
565  err |= AVERROR(EINVAL);
566  }
567 
568  if (err)
569  return err;
570 
571  desc = av_pix_fmt_desc_get(inlink->format);
572  s->bpc = desc->comp[0].depth;
573 
574  return 0;
575 }
576 
577 static int config_output(AVFilterLink *outlink)
578 {
579  AVFilterContext *ctx = outlink->src;
580  LIBVMAFContext *s = ctx->priv;
581  AVFilterLink *mainlink = ctx->inputs[0];
582  int ret;
583 
585  if (ret < 0)
586  return ret;
587  outlink->w = mainlink->w;
588  outlink->h = mainlink->h;
589  outlink->time_base = mainlink->time_base;
590  outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio;
591  outlink->frame_rate = mainlink->frame_rate;
592  if ((ret = ff_framesync_configure(&s->fs)) < 0)
593  return ret;
594 
595  return 0;
596 }
597 
599 {
600  LIBVMAFContext *s = ctx->priv;
601  return ff_framesync_activate(&s->fs);
602 }
603 
604 static enum VmafOutputFormat log_fmt_map(const char *log_fmt)
605 {
606  if (log_fmt) {
607  if (av_stristr(log_fmt, "xml"))
608  return VMAF_OUTPUT_FORMAT_XML;
609  if (av_stristr(log_fmt, "json"))
610  return VMAF_OUTPUT_FORMAT_JSON;
611  if (av_stristr(log_fmt, "csv"))
612  return VMAF_OUTPUT_FORMAT_CSV;
613  if (av_stristr(log_fmt, "sub"))
614  return VMAF_OUTPUT_FORMAT_SUB;
615  }
616 
617  return VMAF_OUTPUT_FORMAT_XML;
618 }
619 
620 static enum VmafPoolingMethod pool_method_map(const char *pool_method)
621 {
622  if (pool_method) {
623  if (av_stristr(pool_method, "min"))
624  return VMAF_POOL_METHOD_MIN;
625  if (av_stristr(pool_method, "mean"))
626  return VMAF_POOL_METHOD_MEAN;
627  if (av_stristr(pool_method, "harmonic_mean"))
628  return VMAF_POOL_METHOD_HARMONIC_MEAN;
629  }
630 
631  return VMAF_POOL_METHOD_MEAN;
632 }
633 
635 {
636  LIBVMAFContext *s = ctx->priv;
637  int err = 0;
638 
639  ff_framesync_uninit(&s->fs);
640 
641  if (!s->frame_cnt)
642  goto clean_up;
643 
644  err = vmaf_read_pictures(s->vmaf, NULL, NULL, 0);
645  if (err) {
647  "problem flushing libvmaf context.\n");
648  }
649 
650  for (unsigned i = 0; i < s->model_cnt; i++) {
651  double vmaf_score;
652  err = vmaf_score_pooled(s->vmaf, s->model[i], pool_method_map(s->pool),
653  &vmaf_score, 0, s->frame_cnt - 1);
654  if (err) {
656  "problem getting pooled vmaf score.\n");
657  }
658 
659  av_log(ctx, AV_LOG_INFO, "VMAF score: %f\n", vmaf_score);
660  }
661 
662  if (s->vmaf) {
663  if (s->log_path && !err)
664  vmaf_write_output(s->vmaf, s->log_path, log_fmt_map(s->log_fmt));
665  }
666 
667 clean_up:
668  if (s->model) {
669  for (unsigned i = 0; i < s->model_cnt; i++) {
670  if (s->model[i])
671  vmaf_model_destroy(s->model[i]);
672  }
673  av_free(s->model);
674  }
675 
676  if (s->vmaf)
677  vmaf_close(s->vmaf);
678 }
679 
680 static const AVFilterPad libvmaf_inputs[] = {
681  {
682  .name = "main",
683  .type = AVMEDIA_TYPE_VIDEO,
684  },{
685  .name = "reference",
686  .type = AVMEDIA_TYPE_VIDEO,
687  .config_props = config_input_ref,
688  },
689 };
690 
691 static const AVFilterPad libvmaf_outputs[] = {
692  {
693  .name = "default",
694  .type = AVMEDIA_TYPE_VIDEO,
695  .config_props = config_output,
696  },
697 };
698 
700  .name = "libvmaf",
701  .description = NULL_IF_CONFIG_SMALL("Calculate the VMAF between two video streams."),
702  .preinit = libvmaf_framesync_preinit,
703  .init = init,
704  .uninit = uninit,
705  .activate = activate,
706  .priv_size = sizeof(LIBVMAFContext),
707  .priv_class = &libvmaf_class,
711 };
ff_framesync_configure
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:134
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
psnr
static double psnr(double d)
Definition: ffmpeg.c:850
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
libvmaf_inputs
static const AVFilterPad libvmaf_inputs[]
Definition: vf_libvmaf.c:680
ff_framesync_uninit
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:304
AV_LOG_QUIET
#define AV_LOG_QUIET
Print no output.
Definition: log.h:162
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:59
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:999
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2703
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:170
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
LIBVMAFContext
Definition: vf_libvmaf.c:39
LIBVMAFContext::enable_conf_interval
int enable_conf_interval
Definition: vf_libvmaf.c:53
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
pixdesc.h
log_fmt_map
static enum VmafOutputFormat log_fmt_map(const char *log_fmt)
Definition: vf_libvmaf.c:604
AVOption
AVOption.
Definition: opt.h:251
AV_DICT_IGNORE_SUFFIX
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition: dict.h:68
AV_PIX_FMT_YUV420P16LE
@ AV_PIX_FMT_YUV420P16LE
planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:121
AVDictionary
Definition: dict.c:30
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:175
FFFrameSync
Frame sync structure.
Definition: framesync.h:168
video.h
AV_PIX_FMT_YUV444P16LE
@ AV_PIX_FMT_YUV444P16LE
planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:125
formats.h
AV_PIX_FMT_YUV420P12LE
@ AV_PIX_FMT_YUV420P12LE
planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:233
fail
#define fail()
Definition: checkasm.h:131
LIBVMAFContext::fs
FFFrameSync fs
Definition: vf_libvmaf.c:41
LIBVMAFContext::n_subsample
int n_subsample
Definition: vf_libvmaf.c:52
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:49
AV_PIX_FMT_YUV420P10LE
@ AV_PIX_FMT_YUV420P10LE
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:149
AV_PIX_FMT_YUV444P12LE
@ AV_PIX_FMT_YUV444P12LE
planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:241
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:40
s
#define s(width, name)
Definition: cbs_vp9.c:256
LIBVMAFContext::model
VmafModel ** model
Definition: vf_libvmaf.c:57
ff_vf_libvmaf
const AVFilter ff_vf_libvmaf
Definition: vf_libvmaf.c:699
config_input_ref
static int config_input_ref(AVFilterLink *inlink)
Definition: vf_libvmaf.c:546
AVDictionaryEntry::key
char * key
Definition: dict.h:80
LIBVMAFContext::ssim
int ssim
Definition: vf_libvmaf.c:48
av_strtok
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition: avstring.c:189
copy_picture_data
static int copy_picture_data(AVFrame *src, VmafPicture *dst, unsigned bpc)
Definition: vf_libvmaf.c:109
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
LIBVMAFContext::model_cnt
unsigned model_cnt
Definition: vf_libvmaf.c:58
LIBVMAFContext::frame_cnt
unsigned frame_cnt
Definition: vf_libvmaf.c:59
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
FRAMESYNC_DEFINE_CLASS
FRAMESYNC_DEFINE_CLASS(libvmaf, LIBVMAFContext, fs)
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:190
AV_PIX_FMT_YUV444P10LE
@ AV_PIX_FMT_YUV444P10LE
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:155
LIBVMAFContext::vmaf
VmafContext * vmaf
Definition: vf_libvmaf.c:56
activate
static int activate(AVFilterContext *ctx)
Definition: vf_libvmaf.c:598
LIBVMAFContext::enable_transform
int enable_transform
Definition: vf_libvmaf.c:45
av_log_get_level
int av_log_get_level(void)
Get the current log level.
Definition: log.c:437
AV_PIX_FMT_YUV422P16LE
@ AV_PIX_FMT_YUV422P16LE
planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:123
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
do_vmaf
static int do_vmaf(FFFrameSync *fs)
Definition: vf_libvmaf.c:129
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:258
LIBVMAFContext::log_fmt
char * log_fmt
Definition: vf_libvmaf.c:44
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_libvmaf.c:634
LIBVMAFContext::feature_cfg
char * feature_cfg
Definition: vf_libvmaf.c:55
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_libvmaf.c:540
pool_method_map
static enum VmafPoolingMethod pool_method_map(const char *pool_method)
Definition: vf_libvmaf.c:620
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_libvmaf.c:577
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
ff_framesync_init_dualinput
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
Definition: framesync.c:372
AV_PIX_FMT_YUV422P10LE
@ AV_PIX_FMT_YUV422P10LE
planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:151
LIBVMAFContext::n_threads
int n_threads
Definition: vf_libvmaf.c:51
LIBVMAFContext::log_path
char * log_path
Definition: vf_libvmaf.c:43
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:203
LIBVMAFContext::model_cfg
char * model_cfg
Definition: vf_libvmaf.c:54
version
version
Definition: libkvazaar.c:313
LIBVMAFContext::bpc
unsigned bpc
Definition: vf_libvmaf.c:60
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
delimited_dict_parse
static AVDictionary ** delimited_dict_parse(char *str, unsigned *cnt)
Definition: vf_libvmaf.c:166
LIBVMAFContext::ms_ssim
int ms_ssim
Definition: vf_libvmaf.c:49
internal.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:55
LIBVMAFContext::psnr
int psnr
Definition: vf_libvmaf.c:47
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
AVFilter
Filter definition.
Definition: avfilter.h:171
ret
ret
Definition: filter_design.txt:187
LIBVMAFContext::model_path
char * model_path
Definition: vf_libvmaf.c:42
libvmaf_outputs
static const AVFilterPad libvmaf_outputs[]
Definition: vf_libvmaf.c:691
pix_fmt_map
static enum VmafPixelFormat pix_fmt_map(enum AVPixelFormat av_pix_fmt)
Definition: vf_libvmaf.c:86
framesync.h
libvmaf_options
static const AVOption libvmaf_options[]
Definition: vf_libvmaf.c:66
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
av_dict_parse_string
int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)
Parse the key/value pairs list and add the parsed entries to a dictionary.
Definition: dict.c:180
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
LIBVMAFContext::pool
char * pool
Definition: vf_libvmaf.c:50
OFFSET
#define OFFSET(x)
Definition: vf_libvmaf.c:63
FLAGS
#define FLAGS
Definition: vf_libvmaf.c:64
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
AVFilterContext
An instance of a filter.
Definition: avfilter.h:408
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:280
desc
const char * desc
Definition: libsvtav1.c:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_libvmaf.c:509
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:79
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:191
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
log_level_map
static enum VmafLogLevel log_level_map(int log_level)
Definition: vf_libvmaf.c:405
d
d
Definition: ffmpeg_filter.c:155
convert_header.str
string str
Definition: convert_header.py:20
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
parse_models
static int parse_models(AVFilterContext *ctx)
Definition: vf_libvmaf.c:273
AVDictionaryEntry::value
char * value
Definition: dict.h:81
ff_framesync_activate
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
Definition: framesync.c:355
LIBVMAFContext::phone_model
int phone_model
Definition: vf_libvmaf.c:46
avstring.h
ff_framesync_dualinput_get
int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1)
Definition: framesync.c:390
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
drawutils.h
parse_features
static int parse_features(AVFilterContext *ctx)
Definition: vf_libvmaf.c:218
AV_PIX_FMT_YUV422P12LE
@ AV_PIX_FMT_YUV422P12LE
planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:237
parse_deprecated_options
static int parse_deprecated_options(AVFilterContext *ctx)
Definition: vf_libvmaf.c:423
AV_OPT_FLAG_DEPRECATED
#define AV_OPT_FLAG_DEPRECATED
set if option is deprecated, users should refer to AVOption.help text for more information
Definition: opt.h:298