FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
vf_libplacebo.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/avassert.h"
20 #include "libavutil/eval.h"
21 #include "libavutil/fifo.h"
22 #include "libavutil/file.h"
23 #include "libavutil/frame.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/parseutils.h"
27 #include "formats.h"
28 #include "filters.h"
29 #include "video.h"
30 #include "vulkan_filter.h"
31 #include "scale_eval.h"
32 
33 #include <libplacebo/renderer.h>
34 #include <libplacebo/utils/libav.h>
35 #include <libplacebo/utils/frame_queue.h>
36 #include <libplacebo/vulkan.h>
37 
38 /* Backwards compatibility with older libplacebo */
39 #if PL_API_VER < 276
40 static inline AVFrame *pl_get_mapped_avframe(const struct pl_frame *frame)
41 {
42  return frame->user_data;
43 }
44 #endif
45 
46 #if PL_API_VER >= 309
47 #include <libplacebo/options.h>
48 #else
49 typedef struct pl_options_t {
50  // Backwards compatibility shim of this struct
51  struct pl_render_params params;
52  struct pl_deinterlace_params deinterlace_params;
53  struct pl_deband_params deband_params;
54  struct pl_sigmoid_params sigmoid_params;
55  struct pl_color_adjustment color_adjustment;
56  struct pl_peak_detect_params peak_detect_params;
57  struct pl_color_map_params color_map_params;
58  struct pl_dither_params dither_params;
59  struct pl_cone_params cone_params;
60 } *pl_options;
61 
62 #define pl_options_alloc(log) av_mallocz(sizeof(struct pl_options_t))
63 #define pl_options_free(ptr) av_freep(ptr)
64 #endif
65 
66 enum {
80 };
81 
82 enum {
93 };
94 
95 static const char *const var_names[] = {
96  "in_idx", "idx",///< index of input
97  "in_w", "iw", ///< width of the input video frame
98  "in_h", "ih", ///< height of the input video frame
99  "out_w", "ow", ///< width of the output video frame
100  "out_h", "oh", ///< height of the output video frame
101  "crop_w", "cw", ///< evaluated input crop width
102  "crop_h", "ch", ///< evaluated input crop height
103  "pos_w", "pw", ///< evaluated output placement width
104  "pos_h", "ph", ///< evaluated output placement height
105  "a", ///< iw/ih
106  "sar", ///< input pixel aspect ratio
107  "dar", ///< output pixel aspect ratio
108  "hsub", ///< input horizontal subsampling factor
109  "vsub", ///< input vertical subsampling factor
110  "ohsub", ///< output horizontal subsampling factor
111  "ovsub", ///< output vertical subsampling factor
112  "in_t", "t", ///< input frame pts
113  "out_t", "ot", ///< output frame pts
114  "n", ///< number of frame
115  NULL,
116 };
117 
118 enum var_name {
139 };
140 
141 /* per-input dynamic filter state */
142 typedef struct LibplaceboInput {
143  int idx;
144  pl_renderer renderer;
145  pl_queue queue;
146  enum pl_queue_status qstatus;
147  struct pl_frame_mix mix; ///< temporary storage
148  AVFifo *out_pts; ///< timestamps of wanted output frames
150  int status;
152 
153 typedef struct LibplaceboContext {
154  /* lavfi vulkan*/
156 
157  /* libplacebo */
158  pl_log log;
159  pl_vulkan vulkan;
160  pl_gpu gpu;
161  pl_tex tex[4];
162 
163  /* input state */
166  int64_t status_pts; ///< tracks status of most recently used input
167  int status;
168 
169  /* settings */
172  uint8_t fillcolor[4];
174  char *w_expr;
175  char *h_expr;
176  char *fps_string;
177  AVRational fps; ///< parsed FPS, or 0/0 for "none"
182  // Parsed expressions for input/output crop
196  int rotation;
198 
199 #if PL_API_VER >= 351
200  pl_cache cache;
201  char *shader_cache;
202 #endif
203 
205 
206  /* pl_render_params */
207  pl_options opts;
208  char *upscaler;
209  char *downscaler;
210  char *frame_mixer;
211  float antiringing;
212  int sigmoid;
213  int skip_aa;
218 
219  /* pl_deinterlace_params */
223 
224  /* pl_deband_params */
225  int deband;
230 
231  /* pl_color_adjustment */
232  float brightness;
233  float contrast;
234  float saturation;
235  float hue;
236  float gamma;
237 
238  /* pl_peak_detect_params */
240  float smoothing;
241  float scene_low;
242  float scene_high;
243  float percentile;
244 
245  /* pl_color_map_params */
253 
254  /* pl_dither_params */
258 
259  /* pl_cone_params */
260  int cones;
261  float cone_str;
262 
263  /* custom shaders */
264  char *shader_path;
265  void *shader_bin;
267  const struct pl_hook *hooks[2];
270 
271 static inline enum pl_log_level get_log_level(void)
272 {
273  int av_lev = av_log_get_level();
274  return av_lev >= AV_LOG_TRACE ? PL_LOG_TRACE :
275  av_lev >= AV_LOG_DEBUG ? PL_LOG_DEBUG :
276  av_lev >= AV_LOG_VERBOSE ? PL_LOG_INFO :
277  av_lev >= AV_LOG_WARNING ? PL_LOG_WARN :
278  av_lev >= AV_LOG_ERROR ? PL_LOG_ERR :
279  av_lev >= AV_LOG_FATAL ? PL_LOG_FATAL :
280  PL_LOG_NONE;
281 }
282 
283 static void pl_av_log(void *log_ctx, enum pl_log_level level, const char *msg)
284 {
285  int av_lev;
286 
287  switch (level) {
288  case PL_LOG_FATAL: av_lev = AV_LOG_FATAL; break;
289  case PL_LOG_ERR: av_lev = AV_LOG_ERROR; break;
290  case PL_LOG_WARN: av_lev = AV_LOG_WARNING; break;
291  case PL_LOG_INFO: av_lev = AV_LOG_VERBOSE; break;
292  case PL_LOG_DEBUG: av_lev = AV_LOG_DEBUG; break;
293  case PL_LOG_TRACE: av_lev = AV_LOG_TRACE; break;
294  default: return;
295  }
296 
297  av_log(log_ctx, av_lev, "%s\n", msg);
298 }
299 
300 static const struct pl_tone_map_function *get_tonemapping_func(int tm) {
301  switch (tm) {
302  case TONE_MAP_AUTO: return &pl_tone_map_auto;
303  case TONE_MAP_CLIP: return &pl_tone_map_clip;
304 #if PL_API_VER >= 246
305  case TONE_MAP_ST2094_40: return &pl_tone_map_st2094_40;
306  case TONE_MAP_ST2094_10: return &pl_tone_map_st2094_10;
307 #endif
308  case TONE_MAP_BT2390: return &pl_tone_map_bt2390;
309  case TONE_MAP_BT2446A: return &pl_tone_map_bt2446a;
310  case TONE_MAP_SPLINE: return &pl_tone_map_spline;
311  case TONE_MAP_REINHARD: return &pl_tone_map_reinhard;
312  case TONE_MAP_MOBIUS: return &pl_tone_map_mobius;
313  case TONE_MAP_HABLE: return &pl_tone_map_hable;
314  case TONE_MAP_GAMMA: return &pl_tone_map_gamma;
315  case TONE_MAP_LINEAR: return &pl_tone_map_linear;
316  default: av_assert0(0);
317  }
318 }
319 
320 static void set_gamut_mode(struct pl_color_map_params *p, int gamut_mode)
321 {
322  switch (gamut_mode) {
323 #if PL_API_VER >= 269
324  case GAMUT_MAP_CLIP: p->gamut_mapping = &pl_gamut_map_clip; return;
325  case GAMUT_MAP_PERCEPTUAL: p->gamut_mapping = &pl_gamut_map_perceptual; return;
326  case GAMUT_MAP_RELATIVE: p->gamut_mapping = &pl_gamut_map_relative; return;
327  case GAMUT_MAP_SATURATION: p->gamut_mapping = &pl_gamut_map_saturation; return;
328  case GAMUT_MAP_ABSOLUTE: p->gamut_mapping = &pl_gamut_map_absolute; return;
329  case GAMUT_MAP_DESATURATE: p->gamut_mapping = &pl_gamut_map_desaturate; return;
330  case GAMUT_MAP_DARKEN: p->gamut_mapping = &pl_gamut_map_darken; return;
331  case GAMUT_MAP_HIGHLIGHT: p->gamut_mapping = &pl_gamut_map_highlight; return;
332  case GAMUT_MAP_LINEAR: p->gamut_mapping = &pl_gamut_map_linear; return;
333 #else
334  case GAMUT_MAP_RELATIVE: p->intent = PL_INTENT_RELATIVE_COLORIMETRIC; return;
335  case GAMUT_MAP_SATURATION: p->intent = PL_INTENT_SATURATION; return;
336  case GAMUT_MAP_ABSOLUTE: p->intent = PL_INTENT_ABSOLUTE_COLORIMETRIC; return;
337  case GAMUT_MAP_DESATURATE: p->gamut_mode = PL_GAMUT_DESATURATE; return;
338  case GAMUT_MAP_DARKEN: p->gamut_mode = PL_GAMUT_DARKEN; return;
339  case GAMUT_MAP_HIGHLIGHT: p->gamut_mode = PL_GAMUT_WARN; return;
340  /* Use defaults for all other cases */
341  default: return;
342 #endif
343  }
344 
345  av_assert0(0);
346 };
347 
348 static int find_scaler(AVFilterContext *avctx,
349  const struct pl_filter_config **opt,
350  const char *name, int frame_mixing)
351 {
352  const struct pl_filter_preset *preset, *presets_avail;
353  presets_avail = frame_mixing ? pl_frame_mixers : pl_scale_filters;
354 
355  if (!strcmp(name, "help")) {
356  av_log(avctx, AV_LOG_INFO, "Available scaler presets:\n");
357  for (preset = presets_avail; preset->name; preset++)
358  av_log(avctx, AV_LOG_INFO, " %s\n", preset->name);
359  return AVERROR_EXIT;
360  }
361 
362  for (preset = presets_avail; preset->name; preset++) {
363  if (!strcmp(name, preset->name)) {
364  *opt = preset->filter;
365  return 0;
366  }
367  }
368 
369  av_log(avctx, AV_LOG_ERROR, "No such scaler preset '%s'.\n", name);
370  return AVERROR(EINVAL);
371 }
372 
374 {
375  int err = 0;
376  LibplaceboContext *s = ctx->priv;
377  AVDictionaryEntry *e = NULL;
378  pl_options opts = s->opts;
379  int gamut_mode = s->gamut_mode;
380 
381  opts->deinterlace_params = *pl_deinterlace_params(
382  .algo = s->deinterlace,
383  .skip_spatial_check = s->skip_spatial_check,
384  );
385 
386  opts->deband_params = *pl_deband_params(
387  .iterations = s->deband_iterations,
388  .threshold = s->deband_threshold,
389  .radius = s->deband_radius,
390  .grain = s->deband_grain,
391  );
392 
393  opts->sigmoid_params = pl_sigmoid_default_params;
394 
395  opts->color_adjustment = (struct pl_color_adjustment) {
396  .brightness = s->brightness,
397  .contrast = s->contrast,
398  .saturation = s->saturation,
399  .hue = s->hue,
400  .gamma = s->gamma,
401  };
402 
403  opts->peak_detect_params = *pl_peak_detect_params(
404  .smoothing_period = s->smoothing,
405  .scene_threshold_low = s->scene_low,
406  .scene_threshold_high = s->scene_high,
407 #if PL_API_VER >= 263
408  .percentile = s->percentile,
409 #endif
410  );
411 
412  opts->color_map_params = *pl_color_map_params(
413  .tone_mapping_function = get_tonemapping_func(s->tonemapping),
414  .tone_mapping_param = s->tonemapping_param,
415  .inverse_tone_mapping = s->inverse_tonemapping,
416  .lut_size = s->tonemapping_lut_size,
417 #if PL_API_VER >= 285
418  .contrast_recovery = s->contrast_recovery,
419  .contrast_smoothness = s->contrast_smoothness,
420 #endif
421  );
422 
423  set_gamut_mode(&opts->color_map_params, gamut_mode);
424 
425  opts->dither_params = *pl_dither_params(
426  .method = s->dithering,
427  .lut_size = s->dither_lut_size,
428  .temporal = s->dither_temporal,
429  );
430 
431  opts->cone_params = *pl_cone_params(
432  .cones = s->cones,
433  .strength = s->cone_str,
434  );
435 
436  opts->params = *pl_render_params(
437  .antiringing_strength = s->antiringing,
438  .background_transparency = 1.0f - (float) s->fillcolor[3] / UINT8_MAX,
439  .background_color = {
440  (float) s->fillcolor[0] / UINT8_MAX,
441  (float) s->fillcolor[1] / UINT8_MAX,
442  (float) s->fillcolor[2] / UINT8_MAX,
443  },
444 #if PL_API_VER >= 277
445  .corner_rounding = s->corner_rounding,
446 #endif
447 
448  .deinterlace_params = &opts->deinterlace_params,
449  .deband_params = s->deband ? &opts->deband_params : NULL,
450  .sigmoid_params = s->sigmoid ? &opts->sigmoid_params : NULL,
451  .color_adjustment = &opts->color_adjustment,
452  .peak_detect_params = s->peakdetect ? &opts->peak_detect_params : NULL,
453  .color_map_params = &opts->color_map_params,
454  .dither_params = s->dithering >= 0 ? &opts->dither_params : NULL,
455  .cone_params = s->cones ? &opts->cone_params : NULL,
456 
457  .hooks = s->hooks,
458  .num_hooks = s->num_hooks,
459 
460  .skip_anti_aliasing = s->skip_aa,
461  .disable_linear_scaling = s->disable_linear,
462  .disable_builtin_scalers = s->disable_builtin,
463  .force_dither = s->force_dither,
464  .disable_fbos = s->disable_fbos,
465  );
466 
467  RET(find_scaler(ctx, &opts->params.upscaler, s->upscaler, 0));
468  RET(find_scaler(ctx, &opts->params.downscaler, s->downscaler, 0));
469  RET(find_scaler(ctx, &opts->params.frame_mixer, s->frame_mixer, 1));
470 
471 #if PL_API_VER >= 309
472  while ((e = av_dict_get(s->extra_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
473  if (!pl_options_set_str(s->opts, e->key, e->value)) {
474  err = AVERROR(EINVAL);
475  goto fail;
476  }
477  }
478 #else
479  (void) e;
480  if (av_dict_count(s->extra_opts) > 0)
481  av_log(s, AV_LOG_WARNING, "extra_opts requires libplacebo >= 6.309!\n");
482 #endif
483 
484  return 0;
485 
486 fail:
487  return err;
488 }
489 
490 static int parse_shader(AVFilterContext *avctx, const void *shader, size_t len)
491 {
492  LibplaceboContext *s = avctx->priv;
493  const struct pl_hook *hook;
494 
495  hook = pl_mpv_user_shader_parse(s->gpu, shader, len);
496  if (!hook) {
497  av_log(s, AV_LOG_ERROR, "Failed parsing custom shader!\n");
498  return AVERROR(EINVAL);
499  }
500 
501  s->hooks[s->num_hooks++] = hook;
502  return update_settings(avctx);
503 }
504 
505 static void libplacebo_uninit(AVFilterContext *avctx);
507 static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwctx);
508 
510 {
511  int err = 0;
512  LibplaceboContext *s = avctx->priv;
513  const AVVulkanDeviceContext *vkhwctx = NULL;
514 
515  /* Create libplacebo log context */
516  s->log = pl_log_create(PL_API_VER, pl_log_params(
517  .log_level = get_log_level(),
518  .log_cb = pl_av_log,
519  .log_priv = s,
520  ));
521 
522  if (!s->log)
523  return AVERROR(ENOMEM);
524 
525  s->opts = pl_options_alloc(s->log);
526  if (!s->opts) {
527  libplacebo_uninit(avctx);
528  return AVERROR(ENOMEM);
529  }
530 
531 #if PL_API_VER >= 351
532  if (s->shader_cache && s->shader_cache[0]) {
533  s->cache = pl_cache_create(pl_cache_params(
534  .log = s->log,
535  .get = pl_cache_get_file,
536  .set = pl_cache_set_file,
537  .priv = s->shader_cache,
538  ));
539  if (!s->cache) {
540  libplacebo_uninit(avctx);
541  return AVERROR(ENOMEM);
542  }
543  }
544 #endif
545 
546  if (s->out_format_string) {
547  s->out_format = av_get_pix_fmt(s->out_format_string);
548  if (s->out_format == AV_PIX_FMT_NONE) {
549  av_log(avctx, AV_LOG_ERROR, "Invalid output format: %s\n",
550  s->out_format_string);
551  libplacebo_uninit(avctx);
552  return AVERROR(EINVAL);
553  }
554  } else {
555  s->out_format = AV_PIX_FMT_NONE;
556  }
557 
558  for (int i = 0; i < s->nb_inputs; i++) {
559  AVFilterPad pad = {
560  .name = av_asprintf("input%d", i),
561  .type = AVMEDIA_TYPE_VIDEO,
562  .config_props = &libplacebo_config_input,
563  };
564  if (!pad.name)
565  return AVERROR(ENOMEM);
566  RET(ff_append_inpad_free_name(avctx, &pad));
567  }
568 
569  RET(update_settings(avctx));
570  RET(av_expr_parse(&s->crop_x_pexpr, s->crop_x_expr, var_names,
571  NULL, NULL, NULL, NULL, 0, s));
572  RET(av_expr_parse(&s->crop_y_pexpr, s->crop_y_expr, var_names,
573  NULL, NULL, NULL, NULL, 0, s));
574  RET(av_expr_parse(&s->crop_w_pexpr, s->crop_w_expr, var_names,
575  NULL, NULL, NULL, NULL, 0, s));
576  RET(av_expr_parse(&s->crop_h_pexpr, s->crop_h_expr, var_names,
577  NULL, NULL, NULL, NULL, 0, s));
578  RET(av_expr_parse(&s->pos_x_pexpr, s->pos_x_expr, var_names,
579  NULL, NULL, NULL, NULL, 0, s));
580  RET(av_expr_parse(&s->pos_y_pexpr, s->pos_y_expr, var_names,
581  NULL, NULL, NULL, NULL, 0, s));
582  RET(av_expr_parse(&s->pos_w_pexpr, s->pos_w_expr, var_names,
583  NULL, NULL, NULL, NULL, 0, s));
584  RET(av_expr_parse(&s->pos_h_pexpr, s->pos_h_expr, var_names,
585  NULL, NULL, NULL, NULL, 0, s));
586 
587  if (strcmp(s->fps_string, "none") != 0)
588  RET(av_parse_video_rate(&s->fps, s->fps_string));
589 
590  if (avctx->hw_device_ctx) {
591  const AVHWDeviceContext *avhwctx = (void *) avctx->hw_device_ctx->data;
592  if (avhwctx->type == AV_HWDEVICE_TYPE_VULKAN)
593  vkhwctx = avhwctx->hwctx;
594  }
595 
596  RET(init_vulkan(avctx, vkhwctx));
597 
598  return 0;
599 
600 fail:
601  return err;
602 }
603 
604 #if PL_API_VER >= 278
605 static void lock_queue(void *priv, uint32_t qf, uint32_t qidx)
606 {
607  AVHWDeviceContext *avhwctx = priv;
608  const AVVulkanDeviceContext *hwctx = avhwctx->hwctx;
609  hwctx->lock_queue(avhwctx, qf, qidx);
610 }
611 
612 static void unlock_queue(void *priv, uint32_t qf, uint32_t qidx)
613 {
614  AVHWDeviceContext *avhwctx = priv;
615  const AVVulkanDeviceContext *hwctx = avhwctx->hwctx;
616  hwctx->unlock_queue(avhwctx, qf, qidx);
617 }
618 #endif
619 
620 static int input_init(AVFilterContext *avctx, LibplaceboInput *input, int idx)
621 {
622  LibplaceboContext *s = avctx->priv;
623 
624  input->out_pts = av_fifo_alloc2(1, sizeof(int64_t), AV_FIFO_FLAG_AUTO_GROW);
625  if (!input->out_pts)
626  return AVERROR(ENOMEM);
627  input->queue = pl_queue_create(s->gpu);
628  input->renderer = pl_renderer_create(s->log, s->gpu);
629  input->idx = idx;
630 
631  return 0;
632 }
633 
635 {
636  pl_renderer_destroy(&input->renderer);
637  pl_queue_destroy(&input->queue);
638  av_fifo_freep2(&input->out_pts);
639 }
640 
641 static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwctx)
642 {
643  int err = 0;
644  LibplaceboContext *s = avctx->priv;
645  uint8_t *buf = NULL;
646  size_t buf_len;
647 
648  if (hwctx) {
649 #if PL_API_VER >= 278
650  /* Import libavfilter vulkan context into libplacebo */
651  s->vulkan = pl_vulkan_import(s->log, pl_vulkan_import_params(
652  .instance = hwctx->inst,
653  .get_proc_addr = hwctx->get_proc_addr,
654  .phys_device = hwctx->phys_dev,
655  .device = hwctx->act_dev,
656  .extensions = hwctx->enabled_dev_extensions,
657  .num_extensions = hwctx->nb_enabled_dev_extensions,
658  .features = &hwctx->device_features,
659  .lock_queue = lock_queue,
660  .unlock_queue = unlock_queue,
661  .queue_ctx = avctx->hw_device_ctx->data,
662  .queue_graphics = {
663  .index = hwctx->queue_family_index,
664  .count = hwctx->nb_graphics_queues,
665  },
666  .queue_compute = {
667  .index = hwctx->queue_family_comp_index,
668  .count = hwctx->nb_comp_queues,
669  },
670  .queue_transfer = {
671  .index = hwctx->queue_family_tx_index,
672  .count = hwctx->nb_tx_queues,
673  },
674  /* This is the highest version created by hwcontext_vulkan.c */
675  .max_api_version = VK_API_VERSION_1_3,
676  ));
677 #else
678  av_log(s, AV_LOG_ERROR, "libplacebo version %s too old to import "
679  "Vulkan device, remove it or upgrade libplacebo to >= 5.278\n",
680  PL_VERSION);
681  err = AVERROR_EXTERNAL;
682  goto fail;
683 #endif
684 
685  s->have_hwdevice = 1;
686  } else {
687  s->vulkan = pl_vulkan_create(s->log, pl_vulkan_params(
688  .queue_count = 0, /* enable all queues for parallelization */
689  ));
690  }
691 
692  if (!s->vulkan) {
693  av_log(s, AV_LOG_ERROR, "Failed %s Vulkan device!\n",
694  hwctx ? "importing" : "creating");
695  err = AVERROR_EXTERNAL;
696  goto fail;
697  }
698 
699  s->gpu = s->vulkan->gpu;
700 #if PL_API_VER >= 351
701  pl_gpu_set_cache(s->gpu, s->cache);
702 #endif
703 
704  /* Parse the user shaders, if requested */
705  if (s->shader_bin_len)
706  RET(parse_shader(avctx, s->shader_bin, s->shader_bin_len));
707 
708  if (s->shader_path && s->shader_path[0]) {
709  RET(av_file_map(s->shader_path, &buf, &buf_len, 0, s));
710  RET(parse_shader(avctx, buf, buf_len));
711  }
712 
713  /* Initialize inputs */
714  s->inputs = av_calloc(s->nb_inputs, sizeof(*s->inputs));
715  if (!s->inputs)
716  return AVERROR(ENOMEM);
717  for (int i = 0; i < s->nb_inputs; i++)
718  RET(input_init(avctx, &s->inputs[i], i));
719 
720  /* fall through */
721 fail:
722  if (buf)
723  av_file_unmap(buf, buf_len);
724  return err;
725 }
726 
728 {
729  LibplaceboContext *s = avctx->priv;
730 
731  for (int i = 0; i < FF_ARRAY_ELEMS(s->tex); i++)
732  pl_tex_destroy(s->gpu, &s->tex[i]);
733  for (int i = 0; i < s->num_hooks; i++)
734  pl_mpv_user_shader_destroy(&s->hooks[i]);
735  if (s->inputs) {
736  for (int i = 0; i < s->nb_inputs; i++)
737  input_uninit(&s->inputs[i]);
738  av_freep(&s->inputs);
739  }
740 
741 #if PL_API_VER >= 351
742  pl_cache_destroy(&s->cache);
743 #endif
744  pl_options_free(&s->opts);
745  pl_vulkan_destroy(&s->vulkan);
746  pl_log_destroy(&s->log);
747  ff_vk_uninit(&s->vkctx);
748  s->gpu = NULL;
749 
750  av_expr_free(s->crop_x_pexpr);
751  av_expr_free(s->crop_y_pexpr);
752  av_expr_free(s->crop_w_pexpr);
753  av_expr_free(s->crop_h_pexpr);
754  av_expr_free(s->pos_x_pexpr);
755  av_expr_free(s->pos_y_pexpr);
756  av_expr_free(s->pos_w_pexpr);
757  av_expr_free(s->pos_h_pexpr);
758 }
759 
760 static int libplacebo_process_command(AVFilterContext *ctx, const char *cmd,
761  const char *arg, char *res, int res_len,
762  int flags)
763 {
764  int err = 0;
765  RET(ff_filter_process_command(ctx, cmd, arg, res, res_len, flags));
767  return 0;
768 
769 fail:
770  return err;
771 }
772 
773 static const AVFrame *ref_frame(const struct pl_frame_mix *mix)
774 {
775  for (int i = 0; i < mix->num_frames; i++) {
776  if (i+1 == mix->num_frames || mix->timestamps[i+1] > 0)
777  return pl_get_mapped_avframe(mix->frames[i]);
778  }
779  return NULL;
780 }
781 
783  struct pl_frame *target, double target_pts)
784 {
785  FilterLink *outl = ff_filter_link(ctx->outputs[0]);
786  LibplaceboContext *s = ctx->priv;
787  const AVFilterLink *inlink = ctx->inputs[in->idx];
788  const AVFrame *ref = ref_frame(&in->mix);
789 
790  for (int i = 0; i < in->mix.num_frames; i++) {
791  // Mutate the `pl_frame.crop` fields in-place. This is fine because we
792  // own the entire pl_queue, and hence, the pointed-at frames.
793  struct pl_frame *image = (struct pl_frame *) in->mix.frames[i];
794  const AVFrame *src = pl_get_mapped_avframe(image);
795  double image_pts = src->pts * av_q2d(inlink->time_base);
796 
797  /* Update dynamic variables */
798  s->var_values[VAR_IN_IDX] = s->var_values[VAR_IDX] = in->idx;
799  s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = inlink->w;
800  s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = inlink->h;
801  s->var_values[VAR_A] = (double) inlink->w / inlink->h;
802  s->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
803  av_q2d(inlink->sample_aspect_ratio) : 1.0;
804  s->var_values[VAR_IN_T] = s->var_values[VAR_T] = image_pts;
805  s->var_values[VAR_OUT_T] = s->var_values[VAR_OT] = target_pts;
806  s->var_values[VAR_N] = outl->frame_count_out;
807 
808  /* Clear these explicitly to avoid leaking previous frames' state */
809  s->var_values[VAR_CROP_W] = s->var_values[VAR_CW] = NAN;
810  s->var_values[VAR_CROP_H] = s->var_values[VAR_CH] = NAN;
811  s->var_values[VAR_POS_W] = s->var_values[VAR_PW] = NAN;
812  s->var_values[VAR_POS_H] = s->var_values[VAR_PH] = NAN;
813 
814  /* Compute dimensions first and placement second */
815  s->var_values[VAR_CROP_W] = s->var_values[VAR_CW] =
816  av_expr_eval(s->crop_w_pexpr, s->var_values, NULL);
817  s->var_values[VAR_CROP_H] = s->var_values[VAR_CH] =
818  av_expr_eval(s->crop_h_pexpr, s->var_values, NULL);
819  s->var_values[VAR_CROP_W] = s->var_values[VAR_CW] =
820  av_expr_eval(s->crop_w_pexpr, s->var_values, NULL);
821  s->var_values[VAR_POS_W] = s->var_values[VAR_PW] =
822  av_expr_eval(s->pos_w_pexpr, s->var_values, NULL);
823  s->var_values[VAR_POS_H] = s->var_values[VAR_PH] =
824  av_expr_eval(s->pos_h_pexpr, s->var_values, NULL);
825  s->var_values[VAR_POS_W] = s->var_values[VAR_PW] =
826  av_expr_eval(s->pos_w_pexpr, s->var_values, NULL);
827 
828  image->crop.x0 = av_expr_eval(s->crop_x_pexpr, s->var_values, NULL);
829  image->crop.y0 = av_expr_eval(s->crop_y_pexpr, s->var_values, NULL);
830  image->crop.x1 = image->crop.x0 + s->var_values[VAR_CROP_W];
831  image->crop.y1 = image->crop.y0 + s->var_values[VAR_CROP_H];
832  image->rotation = s->rotation;
833  if (s->rotation % PL_ROTATION_180 == PL_ROTATION_90) {
834  /* Libplacebo expects the input crop relative to the actual frame
835  * dimensions, so un-transpose them here */
836  FFSWAP(float, image->crop.x0, image->crop.y0);
837  FFSWAP(float, image->crop.x1, image->crop.y1);
838  }
839 
840  if (src == ref) {
841  /* Only update the target crop once, for the 'reference' frame */
842  target->crop.x0 = av_expr_eval(s->pos_x_pexpr, s->var_values, NULL);
843  target->crop.y0 = av_expr_eval(s->pos_y_pexpr, s->var_values, NULL);
844  target->crop.x1 = target->crop.x0 + s->var_values[VAR_POS_W];
845  target->crop.y1 = target->crop.y0 + s->var_values[VAR_POS_H];
846  if (s->normalize_sar) {
847  float aspect = pl_rect2df_aspect(&image->crop);
848  aspect *= av_q2d(inlink->sample_aspect_ratio);
849  pl_rect2df_aspect_set(&target->crop, aspect, s->pad_crop_ratio);
850  }
851  }
852  }
853 }
854 
855 /* Construct and emit an output frame for a given timestamp */
857 {
858  int err = 0, ok, changed = 0;
859  LibplaceboContext *s = ctx->priv;
860  pl_options opts = s->opts;
861  AVFilterLink *outlink = ctx->outputs[0];
862  const AVPixFmtDescriptor *outdesc = av_pix_fmt_desc_get(outlink->format);
863  struct pl_frame target;
864  const AVFrame *ref = NULL;
865  AVFrame *out;
866 
867  /* Use the first active input as metadata reference */
868  for (int i = 0; i < s->nb_inputs; i++) {
869  const LibplaceboInput *in = &s->inputs[i];
870  if (in->qstatus == PL_QUEUE_OK && (ref = ref_frame(&in->mix)))
871  break;
872  }
873  if (!ref)
874  return 0;
875 
876  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
877  if (!out)
878  return AVERROR(ENOMEM);
879 
881  out->pts = pts;
882  out->width = outlink->w;
883  out->height = outlink->h;
884  out->colorspace = outlink->colorspace;
885  out->color_range = outlink->color_range;
886  if (s->fps.num)
887  out->duration = 1;
888  if (s->deinterlace)
890 
892  /* Output of dovi reshaping is always BT.2020+PQ, so infer the correct
893  * output colorspace defaults */
894  out->color_primaries = AVCOL_PRI_BT2020;
895  out->color_trc = AVCOL_TRC_SMPTE2084;
897  }
898 
899  if (s->color_trc >= 0)
900  out->color_trc = s->color_trc;
901  if (s->color_primaries >= 0)
902  out->color_primaries = s->color_primaries;
903 
904  /* Strip side data if no longer relevant */
905  if (out->width != ref->width || out->height != ref->height)
907  if (ref->color_trc != out->color_trc || ref->color_primaries != out->color_primaries)
909  av_frame_side_data_remove_by_props(&out->side_data, &out->nb_side_data, changed);
910 
911  if (s->apply_filmgrain)
913 
914  /* Map, render and unmap output frame */
915  if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
916  ok = pl_map_avframe_ex(s->gpu, &target, pl_avframe_params(
917  .frame = out,
918  .map_dovi = false,
919  ));
920  } else {
921  ok = pl_frame_recreate_from_avframe(s->gpu, &target, s->tex, out);
922  }
923  if (!ok) {
924  err = AVERROR_EXTERNAL;
925  goto fail;
926  }
927 
928  /* Draw first frame opaque, others with blending */
929  opts->params.blend_params = NULL;
930 #if PL_API_VER >= 346
931  opts->params.background = opts->params.border = PL_CLEAR_COLOR;
932 #else
933  opts->params.skip_target_clearing = false;
934 #endif
935  for (int i = 0; i < s->nb_inputs; i++) {
936  LibplaceboInput *in = &s->inputs[i];
937  FilterLink *il = ff_filter_link(ctx->inputs[in->idx]);
938  FilterLink *ol = ff_filter_link(outlink);
939  int high_fps = av_cmp_q(il->frame_rate, ol->frame_rate) >= 0;
940  if (in->qstatus != PL_QUEUE_OK)
941  continue;
942  opts->params.skip_caching_single_frame = high_fps;
943  update_crops(ctx, in, &target, out->pts * av_q2d(outlink->time_base));
944  pl_render_image_mix(in->renderer, &in->mix, &target, &opts->params);
945 
946  /* Force straight output and set correct blend mode */
947  target.repr.alpha = PL_ALPHA_INDEPENDENT;
948  opts->params.blend_params = &pl_alpha_overlay;
949 #if PL_API_VER >= 346
950  opts->params.background = opts->params.border = PL_CLEAR_SKIP;
951 #else
952  opts->params.skip_target_clearing = true;
953 #endif
954  }
955 
956  if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
957  pl_unmap_avframe(s->gpu, &target);
958  } else if (!pl_download_avframe(s->gpu, &target, out)) {
959  err = AVERROR_EXTERNAL;
960  goto fail;
961  }
962  return ff_filter_frame(outlink, out);
963 
964 fail:
965  av_frame_free(&out);
966  return err;
967 }
968 
969 static bool map_frame(pl_gpu gpu, pl_tex *tex,
970  const struct pl_source_frame *src,
971  struct pl_frame *out)
972 {
973  AVFrame *avframe = src->frame_data;
974  LibplaceboContext *s = avframe->opaque;
975  bool ok = pl_map_avframe_ex(gpu, out, pl_avframe_params(
976  .frame = avframe,
977  .tex = tex,
978  .map_dovi = s->apply_dovi,
979  ));
980 
981  if (!s->apply_filmgrain)
982  out->film_grain.type = PL_FILM_GRAIN_NONE;
983 
984  av_frame_free(&avframe);
985  return ok;
986 }
987 
988 static void unmap_frame(pl_gpu gpu, struct pl_frame *frame,
989  const struct pl_source_frame *src)
990 {
991  pl_unmap_avframe(gpu, frame);
992 }
993 
994 static void discard_frame(const struct pl_source_frame *src)
995 {
996  AVFrame *avframe = src->frame_data;
997  av_frame_free(&avframe);
998 }
999 
1001 {
1002  int ret, status;
1003  LibplaceboContext *s = ctx->priv;
1004  AVFilterLink *outlink = ctx->outputs[0];
1005  AVFilterLink *inlink = ctx->inputs[input->idx];
1006  AVFrame *in;
1007  int64_t pts;
1008 
1009  while ((ret = ff_inlink_consume_frame(inlink, &in)) > 0) {
1010  struct pl_source_frame src = {
1011  .pts = in->pts * av_q2d(inlink->time_base),
1012  .duration = in->duration * av_q2d(inlink->time_base),
1013  .first_field = s->deinterlace ? pl_field_from_avframe(in) : PL_FIELD_NONE,
1014  .frame_data = in,
1015  .map = map_frame,
1016  .unmap = unmap_frame,
1017  .discard = discard_frame,
1018  };
1019 
1020  in->opaque = s;
1021  pl_queue_push(input->queue, &src);
1022 
1023  if (!s->fps.num) {
1024  /* Internally queue an output frame for the same PTS */
1025  pts = av_rescale_q(in->pts, inlink->time_base, outlink->time_base);
1026  av_fifo_write(input->out_pts, &pts, 1);
1027 
1028  if (s->send_fields && src.first_field != PL_FIELD_NONE) {
1029  /* Queue the second field for interlaced content */
1030  pts += av_rescale_q(in->duration, inlink->time_base, outlink->time_base) / 2;
1031  av_fifo_write(input->out_pts, &pts, 1);
1032  }
1033  }
1034  }
1035 
1036  if (ret < 0)
1037  return ret;
1038 
1039  if (!input->status && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
1040  pts = av_rescale_q_rnd(pts, inlink->time_base, outlink->time_base,
1041  AV_ROUND_UP);
1042  pl_queue_push(input->queue, NULL); /* Signal EOF to pl_queue */
1043  input->status = status;
1044  input->status_pts = pts;
1045  if (!s->status || pts >= s->status_pts) {
1046  /* Also propagate to output unless overwritten by later status change */
1047  s->status = status;
1048  s->status_pts = pts;
1049  }
1050  }
1051 
1052  return 0;
1053 }
1054 
1055 static void drain_input_pts(LibplaceboInput *in, int64_t until)
1056 {
1057  int64_t pts;
1058  while (av_fifo_peek(in->out_pts, &pts, 1, 0) >= 0 && pts <= until)
1059  av_fifo_drain2(in->out_pts, 1);
1060 }
1061 
1063 {
1064  int ret, ok = 0, retry = 0;
1065  LibplaceboContext *s = ctx->priv;
1066  AVFilterLink *outlink = ctx->outputs[0];
1067  FilterLink *outl = ff_filter_link(outlink);
1068  int64_t pts, out_pts;
1069 
1071  pl_log_level_update(s->log, get_log_level());
1072 
1073  for (int i = 0; i < s->nb_inputs; i++) {
1074  if ((ret = handle_input(ctx, &s->inputs[i])) < 0)
1075  return ret;
1076  }
1077 
1078  if (ff_outlink_frame_wanted(outlink)) {
1079  if (s->fps.num) {
1080  out_pts = outl->frame_count_out;
1081  } else {
1082  /* Determine the PTS of the next frame from any active input */
1083  out_pts = INT64_MAX;
1084  for (int i = 0; i < s->nb_inputs; i++) {
1085  LibplaceboInput *in = &s->inputs[i];
1086  if (av_fifo_peek(in->out_pts, &pts, 1, 0) >= 0) {
1087  out_pts = FFMIN(out_pts, pts);
1088  } else if (!in->status) {
1089  ff_inlink_request_frame(ctx->inputs[in->idx]);
1090  retry = true;
1091  }
1092  }
1093 
1094  if (retry) /* some inputs are incomplete */
1095  return 0;
1096  }
1097 
1098  /* Update all input queues to the chosen out_pts */
1099  for (int i = 0; i < s->nb_inputs; i++) {
1100  LibplaceboInput *in = &s->inputs[i];
1101  FilterLink *l = ff_filter_link(outlink);
1102  if (in->status && out_pts >= in->status_pts) {
1103  in->qstatus = PL_QUEUE_EOF;
1104  continue;
1105  }
1106 
1107  in->qstatus = pl_queue_update(in->queue, &in->mix, pl_queue_params(
1108  .pts = out_pts * av_q2d(outlink->time_base),
1109  .radius = pl_frame_mix_radius(&s->opts->params),
1110  .vsync_duration = l->frame_rate.num ? av_q2d(av_inv_q(l->frame_rate)) : 0,
1111  ));
1112 
1113  switch (in->qstatus) {
1114  case PL_QUEUE_MORE:
1115  ff_inlink_request_frame(ctx->inputs[in->idx]);
1116  retry = true;
1117  break;
1118  case PL_QUEUE_OK:
1119  ok = true;
1120  break;
1121  case PL_QUEUE_ERR:
1122  return AVERROR_EXTERNAL;
1123  }
1124  }
1125 
1126  if (retry) {
1127  return 0;
1128  } else if (ok) {
1129  /* Got any valid frame mixes, drain PTS queue and render output */
1130  for (int i = 0; i < s->nb_inputs; i++)
1131  drain_input_pts(&s->inputs[i], out_pts);
1132  return output_frame(ctx, out_pts);
1133  } else if (s->status) {
1134  ff_outlink_set_status(outlink, s->status, s->status_pts);
1135  return 0;
1136  }
1137 
1138  return AVERROR_BUG;
1139  }
1140 
1141  return FFERROR_NOT_READY;
1142 }
1143 
1145  AVFilterFormatsConfig **cfg_in,
1146  AVFilterFormatsConfig **cfg_out)
1147 {
1148  int err;
1149  const LibplaceboContext *s = ctx->priv;
1150  const AVPixFmtDescriptor *desc = NULL;
1151  AVFilterFormats *infmts = NULL, *outfmts = NULL;
1152 
1153  while ((desc = av_pix_fmt_desc_next(desc))) {
1155 
1156 #if PL_API_VER < 232
1157  // Older libplacebo can't handle >64-bit pixel formats, so safe-guard
1158  // this to prevent triggering an assertion
1159  if (av_get_bits_per_pixel(desc) > 64)
1160  continue;
1161 #endif
1162 
1163  if (pixfmt == AV_PIX_FMT_VULKAN && !s->have_hwdevice)
1164  continue;
1165 
1166  if (!pl_test_pixfmt(s->gpu, pixfmt))
1167  continue;
1168 
1169  RET(ff_add_format(&infmts, pixfmt));
1170 
1171  /* Filter for supported output pixel formats */
1172  if (desc->flags & AV_PIX_FMT_FLAG_BE)
1173  continue; /* BE formats are not supported by pl_download_avframe */
1174 
1175  /* Mask based on user specified format */
1176  if (s->out_format != AV_PIX_FMT_NONE) {
1177  if (pixfmt == AV_PIX_FMT_VULKAN && av_vkfmt_from_pixfmt(s->out_format)) {
1178  /* OK */
1179  } else if (pixfmt == s->out_format) {
1180  /* OK */
1181  } else {
1182  continue; /* Not OK */
1183  }
1184  }
1185 
1186 #if PL_API_VER >= 293
1187  if (!pl_test_pixfmt_caps(s->gpu, pixfmt, PL_FMT_CAP_RENDERABLE))
1188  continue;
1189 #endif
1190 
1191  RET(ff_add_format(&outfmts, pixfmt));
1192  }
1193 
1194  if (!infmts || !outfmts) {
1195  err = AVERROR(EINVAL);
1196  goto fail;
1197  }
1198 
1199  for (int i = 0; i < s->nb_inputs; i++) {
1200  if (i > 0) {
1201  /* Duplicate the format list for each subsequent input */
1202  infmts = NULL;
1203  for (int n = 0; n < cfg_in[0]->formats->nb_formats; n++)
1204  RET(ff_add_format(&infmts, cfg_in[0]->formats->formats[n]));
1205  }
1206  RET(ff_formats_ref(infmts, &cfg_in[i]->formats));
1207  RET(ff_formats_ref(ff_all_color_spaces(), &cfg_in[i]->color_spaces));
1208  RET(ff_formats_ref(ff_all_color_ranges(), &cfg_in[i]->color_ranges));
1209  }
1210 
1211  RET(ff_formats_ref(outfmts, &cfg_out[0]->formats));
1212 
1213  outfmts = s->colorspace > 0 ? ff_make_formats_list_singleton(s->colorspace)
1214  : ff_all_color_spaces();
1215  RET(ff_formats_ref(outfmts, &cfg_out[0]->color_spaces));
1216 
1217  outfmts = s->color_range > 0 ? ff_make_formats_list_singleton(s->color_range)
1218  : ff_all_color_ranges();
1219  RET(ff_formats_ref(outfmts, &cfg_out[0]->color_ranges));
1220  return 0;
1221 
1222 fail:
1223  if (infmts && !infmts->refcount)
1224  ff_formats_unref(&infmts);
1225  if (outfmts && !outfmts->refcount)
1226  ff_formats_unref(&outfmts);
1227  return err;
1228 }
1229 
1231 {
1232  AVFilterContext *avctx = inlink->dst;
1233  LibplaceboContext *s = avctx->priv;
1234 
1235  if (s->rotation % PL_ROTATION_180 == PL_ROTATION_90) {
1236  /* Swap width and height for 90 degree rotations to make the size and
1237  * scaling calculations work out correctly */
1238  FFSWAP(int, inlink->w, inlink->h);
1239  if (inlink->sample_aspect_ratio.num)
1240  inlink->sample_aspect_ratio = av_inv_q(inlink->sample_aspect_ratio);
1241  }
1242 
1243  if (inlink->format == AV_PIX_FMT_VULKAN)
1245 
1246  /* Forward this to the vkctx for format selection */
1247  s->vkctx.input_format = inlink->format;
1248 
1249  return 0;
1250 }
1251 
1253 {
1254  return av_cmp_q(a, b) < 0 ? b : a;
1255 }
1256 
1258 {
1259  int err;
1260  FilterLink *l = ff_filter_link(outlink);
1261  AVFilterContext *avctx = outlink->src;
1262  LibplaceboContext *s = avctx->priv;
1263  AVFilterLink *inlink = outlink->src->inputs[0];
1264  FilterLink *ol = ff_filter_link(outlink);
1266  const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format);
1267  AVHWFramesContext *hwfc;
1268  AVVulkanFramesContext *vkfc;
1269 
1270  /* Frame dimensions */
1271  RET(ff_scale_eval_dimensions(s, s->w_expr, s->h_expr, inlink, outlink,
1272  &outlink->w, &outlink->h));
1273 
1274  ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h,
1275  s->force_original_aspect_ratio,
1276  s->force_divisible_by, 1.f);
1277 
1278  if (s->normalize_sar || s->nb_inputs > 1) {
1279  /* SAR is normalized, or we have multiple inputs, set out to 1:1 */
1280  outlink->sample_aspect_ratio = (AVRational){ 1, 1 };
1281  } else {
1282  /* This is consistent with other scale_* filters, which only
1283  * set the outlink SAR to be equal to the scale SAR iff the input SAR
1284  * was set to something nonzero */
1285  if (inlink->sample_aspect_ratio.num)
1286  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
1287  }
1288 
1289  /* Frame rate */
1290  if (s->fps.num) {
1291  ol->frame_rate = s->fps;
1292  outlink->time_base = av_inv_q(s->fps);
1293  } else {
1294  FilterLink *il = ff_filter_link(avctx->inputs[0]);
1295  ol->frame_rate = il->frame_rate;
1296  outlink->time_base = avctx->inputs[0]->time_base;
1297  for (int i = 1; i < s->nb_inputs; i++) {
1298  il = ff_filter_link(avctx->inputs[i]);
1299  ol->frame_rate = max_q(ol->frame_rate, il->frame_rate);
1300  outlink->time_base = av_gcd_q(outlink->time_base,
1301  avctx->inputs[i]->time_base,
1303  }
1304 
1305  if (s->deinterlace && s->send_fields) {
1306  const AVRational q2 = { 2, 1 };
1307  ol->frame_rate = av_mul_q(ol->frame_rate, q2);
1308  /* Ensure output frame timestamps are divisible by two */
1309  outlink->time_base = av_div_q(outlink->time_base, q2);
1310  }
1311  }
1312 
1313  /* Static variables */
1314  s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = outlink->w;
1315  s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = outlink->h;
1316  s->var_values[VAR_DAR] = outlink->sample_aspect_ratio.num ?
1317  av_q2d(outlink->sample_aspect_ratio) : 1.0;
1318  s->var_values[VAR_HSUB] = 1 << desc->log2_chroma_w;
1319  s->var_values[VAR_VSUB] = 1 << desc->log2_chroma_h;
1320  s->var_values[VAR_OHSUB] = 1 << out_desc->log2_chroma_w;
1321  s->var_values[VAR_OVSUB] = 1 << out_desc->log2_chroma_h;
1322 
1323  if (outlink->format != AV_PIX_FMT_VULKAN)
1324  return 0;
1325 
1326  s->vkctx.output_width = outlink->w;
1327  s->vkctx.output_height = outlink->h;
1328  /* Default to re-using the input format */
1329  if (s->out_format == AV_PIX_FMT_NONE || s->out_format == AV_PIX_FMT_VULKAN) {
1330  s->vkctx.output_format = s->vkctx.input_format;
1331  } else {
1332  s->vkctx.output_format = s->out_format;
1333  }
1334  RET(ff_vk_filter_config_output(outlink));
1335  hwfc = (AVHWFramesContext *)l->hw_frames_ctx->data;
1336  vkfc = hwfc->hwctx;
1337  vkfc->usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1338 
1339  return 0;
1340 
1341 fail:
1342  return err;
1343 }
1344 
1345 #define OFFSET(x) offsetof(LibplaceboContext, x)
1346 #define STATIC (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
1347 #define DYNAMIC (STATIC | AV_OPT_FLAG_RUNTIME_PARAM)
1348 
1349 static const AVOption libplacebo_options[] = {
1350  { "inputs", "Number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags = STATIC },
1351  { "w", "Output video frame width", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = STATIC },
1352  { "h", "Output video frame height", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = STATIC },
1353  { "fps", "Output video frame rate", OFFSET(fps_string), AV_OPT_TYPE_STRING, {.str = "none"}, .flags = STATIC },
1354  { "crop_x", "Input video crop x", OFFSET(crop_x_expr), AV_OPT_TYPE_STRING, {.str = "(iw-cw)/2"}, .flags = DYNAMIC },
1355  { "crop_y", "Input video crop y", OFFSET(crop_y_expr), AV_OPT_TYPE_STRING, {.str = "(ih-ch)/2"}, .flags = DYNAMIC },
1356  { "crop_w", "Input video crop w", OFFSET(crop_w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = DYNAMIC },
1357  { "crop_h", "Input video crop h", OFFSET(crop_h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = DYNAMIC },
1358  { "pos_x", "Output video placement x", OFFSET(pos_x_expr), AV_OPT_TYPE_STRING, {.str = "(ow-pw)/2"}, .flags = DYNAMIC },
1359  { "pos_y", "Output video placement y", OFFSET(pos_y_expr), AV_OPT_TYPE_STRING, {.str = "(oh-ph)/2"}, .flags = DYNAMIC },
1360  { "pos_w", "Output video placement w", OFFSET(pos_w_expr), AV_OPT_TYPE_STRING, {.str = "ow"}, .flags = DYNAMIC },
1361  { "pos_h", "Output video placement h", OFFSET(pos_h_expr), AV_OPT_TYPE_STRING, {.str = "oh"}, .flags = DYNAMIC },
1362  { "format", "Output video format", OFFSET(out_format_string), AV_OPT_TYPE_STRING, .flags = STATIC },
1363  { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, STATIC, .unit = "force_oar" },
1364  { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, STATIC, .unit = "force_oar" },
1365  { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, STATIC, .unit = "force_oar" },
1366  { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, STATIC, .unit = "force_oar" },
1367  { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 256, STATIC },
1368  { "normalize_sar", "force SAR normalization to 1:1 by adjusting pos_x/y/w/h", OFFSET(normalize_sar), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, STATIC },
1369  { "pad_crop_ratio", "ratio between padding and cropping when normalizing SAR (0=pad, 1=crop)", OFFSET(pad_crop_ratio), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, 1.0, DYNAMIC },
1370  { "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_COLOR, {.str = "black@0"}, .flags = DYNAMIC },
1371  { "corner_rounding", "Corner rounding radius", OFFSET(corner_rounding), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, .flags = DYNAMIC },
1372  { "extra_opts", "Pass extra libplacebo-specific options using a :-separated list of key=value pairs", OFFSET(extra_opts), AV_OPT_TYPE_DICT, .flags = DYNAMIC },
1373 #if PL_API_VER >= 351
1374  { "shader_cache", "Set shader cache path", OFFSET(shader_cache), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = STATIC },
1375 #endif
1376 
1377  {"colorspace", "select colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_SPC_NB-1, DYNAMIC, .unit = "colorspace"},
1378  {"auto", "keep the same colorspace", 0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1379  {"gbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_RGB}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1380  {"bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT709}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1381  {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_UNSPECIFIED}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1382  {"bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT470BG}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1383  {"smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_SMPTE170M}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1384  {"smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_SMPTE240M}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1385  {"ycgco", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_YCGCO}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1386  {"bt2020nc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT2020_NCL}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1387  {"bt2020c", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT2020_CL}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1388  {"ictcp", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_ICTCP}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1389 
1390  {"range", "select color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_RANGE_NB-1, DYNAMIC, .unit = "range"},
1391  {"auto", "keep the same color range", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, STATIC, .unit = "range"},
1392  {"unspecified", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED}, 0, 0, STATIC, .unit = "range"},
1393  {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED}, 0, 0, STATIC, .unit = "range"},
1394  {"limited", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, STATIC, .unit = "range"},
1395  {"tv", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, STATIC, .unit = "range"},
1396  {"mpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, STATIC, .unit = "range"},
1397  {"full", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, STATIC, .unit = "range"},
1398  {"pc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, STATIC, .unit = "range"},
1399  {"jpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, STATIC, .unit = "range"},
1400 
1401  {"color_primaries", "select color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_PRI_NB-1, DYNAMIC, .unit = "color_primaries"},
1402  {"auto", "keep the same color primaries", 0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1403  {"bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT709}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1404  {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_UNSPECIFIED}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1405  {"bt470m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT470M}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1406  {"bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT470BG}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1407  {"smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE170M}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1408  {"smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE240M}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1409  {"film", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_FILM}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1410  {"bt2020", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT2020}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1411  {"smpte428", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE428}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1412  {"smpte431", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE431}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1413  {"smpte432", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE432}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1414  {"jedec-p22", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_JEDEC_P22}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1415  {"ebu3213", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_EBU3213}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1416 
1417  {"color_trc", "select color transfer", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_TRC_NB-1, DYNAMIC, .unit = "color_trc"},
1418  {"auto", "keep the same color transfer", 0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1419  {"bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT709}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1420  {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_UNSPECIFIED}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1421  {"bt470m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_GAMMA22}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1422  {"bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_GAMMA28}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1423  {"smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE170M}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1424  {"smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE240M}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1425  {"linear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_LINEAR}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1426  {"iec61966-2-4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_IEC61966_2_4}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1427  {"bt1361e", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT1361_ECG}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1428  {"iec61966-2-1", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_IEC61966_2_1}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1429  {"bt2020-10", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT2020_10}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1430  {"bt2020-12", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT2020_12}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1431  {"smpte2084", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE2084}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1432  {"arib-std-b67", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_ARIB_STD_B67}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1433 
1434  {"rotate", "rotate the input clockwise", OFFSET(rotation), AV_OPT_TYPE_INT, {.i64=PL_ROTATION_0}, PL_ROTATION_0, PL_ROTATION_360, DYNAMIC, .unit = "rotation"},
1435  {"0", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_0}, .flags = STATIC, .unit = "rotation"},
1436  {"90", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_90}, .flags = STATIC, .unit = "rotation"},
1437  {"180", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_180}, .flags = STATIC, .unit = "rotation"},
1438  {"270", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_270}, .flags = STATIC, .unit = "rotation"},
1439  {"360", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_360}, .flags = STATIC, .unit = "rotation"},
1440 
1441  { "upscaler", "Upscaler function", OFFSET(upscaler), AV_OPT_TYPE_STRING, {.str = "spline36"}, .flags = DYNAMIC },
1442  { "downscaler", "Downscaler function", OFFSET(downscaler), AV_OPT_TYPE_STRING, {.str = "mitchell"}, .flags = DYNAMIC },
1443  { "frame_mixer", "Frame mixing function", OFFSET(frame_mixer), AV_OPT_TYPE_STRING, {.str = "none"}, .flags = DYNAMIC },
1444  { "antiringing", "Antiringing strength (for non-EWA filters)", OFFSET(antiringing), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, DYNAMIC },
1445  { "sigmoid", "Enable sigmoid upscaling", OFFSET(sigmoid), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
1446  { "apply_filmgrain", "Apply film grain metadata", OFFSET(apply_filmgrain), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
1447  { "apply_dolbyvision", "Apply Dolby Vision metadata", OFFSET(apply_dovi), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
1448 
1449  { "deinterlace", "Deinterlacing mode", OFFSET(deinterlace), AV_OPT_TYPE_INT, {.i64 = PL_DEINTERLACE_WEAVE}, 0, PL_DEINTERLACE_ALGORITHM_COUNT - 1, DYNAMIC, .unit = "deinterlace" },
1450  { "weave", "Weave fields together (no-op)", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_WEAVE}, 0, 0, STATIC, .unit = "deinterlace" },
1451  { "bob", "Naive bob deinterlacing", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_BOB}, 0, 0, STATIC, .unit = "deinterlace" },
1452  { "yadif", "Yet another deinterlacing filter", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_YADIF}, 0, 0, STATIC, .unit = "deinterlace" },
1453  { "skip_spatial_check", "Skip yadif spatial check", OFFSET(skip_spatial_check), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1454  { "send_fields", "Output a frame for each field", OFFSET(send_fields), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1455 
1456  { "deband", "Enable debanding", OFFSET(deband), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1457  { "deband_iterations", "Deband iterations", OFFSET(deband_iterations), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 16, DYNAMIC },
1458  { "deband_threshold", "Deband threshold", OFFSET(deband_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 4.0}, 0.0, 1024.0, DYNAMIC },
1459  { "deband_radius", "Deband radius", OFFSET(deband_radius), AV_OPT_TYPE_FLOAT, {.dbl = 16.0}, 0.0, 1024.0, DYNAMIC },
1460  { "deband_grain", "Deband grain", OFFSET(deband_grain), AV_OPT_TYPE_FLOAT, {.dbl = 6.0}, 0.0, 1024.0, DYNAMIC },
1461 
1462  { "brightness", "Brightness boost", OFFSET(brightness), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, -1.0, 1.0, DYNAMIC },
1463  { "contrast", "Contrast gain", OFFSET(contrast), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 16.0, DYNAMIC },
1464  { "saturation", "Saturation gain", OFFSET(saturation), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 16.0, DYNAMIC },
1465  { "hue", "Hue shift", OFFSET(hue), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, -M_PI, M_PI, DYNAMIC },
1466  { "gamma", "Gamma adjustment", OFFSET(gamma), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 16.0, DYNAMIC },
1467 
1468  { "peak_detect", "Enable dynamic peak detection for HDR tone-mapping", OFFSET(peakdetect), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
1469  { "smoothing_period", "Peak detection smoothing period", OFFSET(smoothing), AV_OPT_TYPE_FLOAT, {.dbl = 100.0}, 0.0, 1000.0, DYNAMIC },
1470  { "scene_threshold_low", "Scene change low threshold", OFFSET(scene_low), AV_OPT_TYPE_FLOAT, {.dbl = 5.5}, -1.0, 100.0, DYNAMIC },
1471  { "scene_threshold_high", "Scene change high threshold", OFFSET(scene_high), AV_OPT_TYPE_FLOAT, {.dbl = 10.0}, -1.0, 100.0, DYNAMIC },
1472  { "percentile", "Peak detection percentile", OFFSET(percentile), AV_OPT_TYPE_FLOAT, {.dbl = 99.995}, 0.0, 100.0, DYNAMIC },
1473 
1474  { "gamut_mode", "Gamut-mapping mode", OFFSET(gamut_mode), AV_OPT_TYPE_INT, {.i64 = GAMUT_MAP_PERCEPTUAL}, 0, GAMUT_MAP_COUNT - 1, DYNAMIC, .unit = "gamut_mode" },
1475  { "clip", "Hard-clip (RGB per-channel)", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_CLIP}, 0, 0, STATIC, .unit = "gamut_mode" },
1476  { "perceptual", "Colorimetric soft clipping", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_PERCEPTUAL}, 0, 0, STATIC, .unit = "gamut_mode" },
1477  { "relative", "Relative colorimetric clipping", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_RELATIVE}, 0, 0, STATIC, .unit = "gamut_mode" },
1478  { "saturation", "Saturation mapping (RGB -> RGB)", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_SATURATION}, 0, 0, STATIC, .unit = "gamut_mode" },
1479  { "absolute", "Absolute colorimetric clipping", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_ABSOLUTE}, 0, 0, STATIC, .unit = "gamut_mode" },
1480  { "desaturate", "Colorimetrically desaturate colors towards white", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_DESATURATE}, 0, 0, STATIC, .unit = "gamut_mode" },
1481  { "darken", "Colorimetric clip with bias towards darkening image to fit gamut", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_DARKEN}, 0, 0, STATIC, .unit = "gamut_mode" },
1482  { "warn", "Highlight out-of-gamut colors", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_HIGHLIGHT}, 0, 0, STATIC, .unit = "gamut_mode" },
1483  { "linear", "Linearly reduce chromaticity to fit gamut", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_LINEAR}, 0, 0, STATIC, .unit = "gamut_mode" },
1484  { "tonemapping", "Tone-mapping algorithm", OFFSET(tonemapping), AV_OPT_TYPE_INT, {.i64 = TONE_MAP_AUTO}, 0, TONE_MAP_COUNT - 1, DYNAMIC, .unit = "tonemap" },
1485  { "auto", "Automatic selection", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_AUTO}, 0, 0, STATIC, .unit = "tonemap" },
1486  { "clip", "No tone mapping (clip", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_CLIP}, 0, 0, STATIC, .unit = "tonemap" },
1487 #if PL_API_VER >= 246
1488  { "st2094-40", "SMPTE ST 2094-40", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_ST2094_40}, 0, 0, STATIC, .unit = "tonemap" },
1489  { "st2094-10", "SMPTE ST 2094-10", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_ST2094_10}, 0, 0, STATIC, .unit = "tonemap" },
1490 #endif
1491  { "bt.2390", "ITU-R BT.2390 EETF", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_BT2390}, 0, 0, STATIC, .unit = "tonemap" },
1492  { "bt.2446a", "ITU-R BT.2446 Method A", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_BT2446A}, 0, 0, STATIC, .unit = "tonemap" },
1493  { "spline", "Single-pivot polynomial spline", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_SPLINE}, 0, 0, STATIC, .unit = "tonemap" },
1494  { "reinhard", "Reinhard", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_REINHARD}, 0, 0, STATIC, .unit = "tonemap" },
1495  { "mobius", "Mobius", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_MOBIUS}, 0, 0, STATIC, .unit = "tonemap" },
1496  { "hable", "Filmic tone-mapping (Hable)", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_HABLE}, 0, 0, STATIC, .unit = "tonemap" },
1497  { "gamma", "Gamma function with knee", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_GAMMA}, 0, 0, STATIC, .unit = "tonemap" },
1498  { "linear", "Perceptually linear stretch", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_LINEAR}, 0, 0, STATIC, .unit = "tonemap" },
1499  { "tonemapping_param", "Tunable parameter for some tone-mapping functions", OFFSET(tonemapping_param), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 100.0, .flags = DYNAMIC },
1500  { "inverse_tonemapping", "Inverse tone mapping (range expansion)", OFFSET(inverse_tonemapping), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1501  { "tonemapping_lut_size", "Tone-mapping LUT size", OFFSET(tonemapping_lut_size), AV_OPT_TYPE_INT, {.i64 = 256}, 2, 1024, DYNAMIC },
1502  { "contrast_recovery", "HDR contrast recovery strength", OFFSET(contrast_recovery), AV_OPT_TYPE_FLOAT, {.dbl = 0.30}, 0.0, 3.0, DYNAMIC },
1503  { "contrast_smoothness", "HDR contrast recovery smoothness", OFFSET(contrast_smoothness), AV_OPT_TYPE_FLOAT, {.dbl = 3.50}, 1.0, 32.0, DYNAMIC },
1504 
1505  { "dithering", "Dither method to use", OFFSET(dithering), AV_OPT_TYPE_INT, {.i64 = PL_DITHER_BLUE_NOISE}, -1, PL_DITHER_METHOD_COUNT - 1, DYNAMIC, .unit = "dither" },
1506  { "none", "Disable dithering", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, STATIC, .unit = "dither" },
1507  { "blue", "Blue noise", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_BLUE_NOISE}, 0, 0, STATIC, .unit = "dither" },
1508  { "ordered", "Ordered LUT", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_ORDERED_LUT}, 0, 0, STATIC, .unit = "dither" },
1509  { "ordered_fixed", "Fixed function ordered", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_ORDERED_FIXED}, 0, 0, STATIC, .unit = "dither" },
1510  { "white", "White noise", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_WHITE_NOISE}, 0, 0, STATIC, .unit = "dither" },
1511  { "dither_lut_size", "Dithering LUT size", OFFSET(dither_lut_size), AV_OPT_TYPE_INT, {.i64 = 6}, 1, 8, STATIC },
1512  { "dither_temporal", "Enable temporal dithering", OFFSET(dither_temporal), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1513 
1514  { "cones", "Colorblindness adaptation model", OFFSET(cones), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, PL_CONE_LMS, DYNAMIC, .unit = "cone" },
1515  { "l", "L cone", 0, AV_OPT_TYPE_CONST, {.i64 = PL_CONE_L}, 0, 0, STATIC, .unit = "cone" },
1516  { "m", "M cone", 0, AV_OPT_TYPE_CONST, {.i64 = PL_CONE_M}, 0, 0, STATIC, .unit = "cone" },
1517  { "s", "S cone", 0, AV_OPT_TYPE_CONST, {.i64 = PL_CONE_S}, 0, 0, STATIC, .unit = "cone" },
1518  { "cone-strength", "Colorblindness adaptation strength", OFFSET(cone_str), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 10.0, DYNAMIC },
1519 
1520  { "custom_shader_path", "Path to custom user shader (mpv .hook format)", OFFSET(shader_path), AV_OPT_TYPE_STRING, .flags = STATIC },
1521  { "custom_shader_bin", "Custom user shader as binary (mpv .hook format)", OFFSET(shader_bin), AV_OPT_TYPE_BINARY, .flags = STATIC },
1522 
1523  /* Performance/quality tradeoff options */
1524  { "skip_aa", "Skip anti-aliasing", OFFSET(skip_aa), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1525  { "disable_linear", "Disable linear scaling", OFFSET(disable_linear), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1526  { "disable_builtin", "Disable built-in scalers", OFFSET(disable_builtin), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1527  { "force_dither", "Force dithering", OFFSET(force_dither), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1528  { "disable_fbos", "Force-disable FBOs", OFFSET(disable_fbos), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1529  { NULL },
1530 };
1531 
1532 AVFILTER_DEFINE_CLASS(libplacebo);
1533 
1535  {
1536  .name = "default",
1537  .type = AVMEDIA_TYPE_VIDEO,
1538  .config_props = &libplacebo_config_output,
1539  },
1540 };
1541 
1543  .p.name = "libplacebo",
1544  .p.description = NULL_IF_CONFIG_SMALL("Apply various GPU filters from libplacebo"),
1545  .p.priv_class = &libplacebo_class,
1547  .priv_size = sizeof(LibplaceboContext),
1548  .init = &libplacebo_init,
1554  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
1555 };
flags
const SwsFlags flags[]
Definition: swscale.c:61
formats
formats
Definition: signature.h:47
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:116
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:86
AV_ROUND_UP
@ AV_ROUND_UP
Round toward +infinity.
Definition: mathematics.h:134
av_fifo_drain2
void av_fifo_drain2(AVFifo *f, size_t size)
Discard the specified amount of data from an AVFifo.
Definition: fifo.c:266
LibplaceboContext::colorspace
int colorspace
Definition: vf_libplacebo.c:192
dithering
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion dithering
Definition: swscale-v2.txt:9
VAR_IH
@ VAR_IH
Definition: vf_libplacebo.c:121
LibplaceboContext::out_format
enum AVPixelFormat out_format
Definition: vf_libplacebo.c:171
AVVulkanDeviceContext::phys_dev
VkPhysicalDevice phys_dev
Physical device.
Definition: hwcontext_vulkan.h:79
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
level
uint8_t level
Definition: svq3.c:208
AVCOL_PRI_EBU3213
@ AVCOL_PRI_EBU3213
EBU Tech. 3213-E (nothing there) / one of JEDEC P22 group phosphors.
Definition: pixfmt.h:635
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
LibplaceboContext::fps_string
char * fps_string
Definition: vf_libplacebo.c:176
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
LibplaceboContext::percentile
float percentile
Definition: vf_libplacebo.c:243
LibplaceboContext::deband
int deband
Definition: vf_libplacebo.c:225
var_name
var_name
Definition: noise.c:47
GAMUT_MAP_DESATURATE
@ GAMUT_MAP_DESATURATE
Definition: vf_libplacebo.c:88
LibplaceboContext::deband_iterations
int deband_iterations
Definition: vf_libplacebo.c:226
LibplaceboContext::deband_threshold
float deband_threshold
Definition: vf_libplacebo.c:227
LibplaceboContext::gamut_mode
int gamut_mode
Definition: vf_libplacebo.c:246
out
FILE * out
Definition: movenc.c:55
VAR_IN_H
@ VAR_IN_H
Definition: vf_libplacebo.c:121
LibplaceboContext::crop_y_pexpr
AVExpr * crop_y_pexpr
Definition: vf_libplacebo.c:183
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:657
LibplaceboContext::deinterlace
int deinterlace
Definition: vf_libplacebo.c:220
LibplaceboContext::contrast
float contrast
Definition: vf_libplacebo.c:233
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1062
AVFrame::duration
int64_t duration
Duration of the frame, in the same units as pts.
Definition: frame.h:758
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3341
VAR_OUT_T
@ VAR_OUT_T
Definition: vf_libplacebo.c:136
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
RET
#define RET(x)
Definition: vulkan.h:66
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
AVCOL_TRC_LINEAR
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition: pixfmt.h:653
av_dict_count
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition: dict.c:37
av_div_q
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition: rational.c:88
pl_options_t::sigmoid_params
struct pl_sigmoid_params sigmoid_params
Definition: vf_libplacebo.c:54
saturation
static IPT saturation(const CmsCtx *ctx, IPT ipt)
Definition: cms.c:559
AV_FRAME_DATA_DOVI_METADATA
@ AV_FRAME_DATA_DOVI_METADATA
Parsed Dolby Vision metadata, suitable for passing to a software implementation.
Definition: frame.h:208
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
int64_t
long long int64_t
Definition: coverity.c:34
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
av_asprintf
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:115
GAMUT_MAP_RELATIVE
@ GAMUT_MAP_RELATIVE
Definition: vf_libplacebo.c:85
AV_FRAME_DATA_FILM_GRAIN_PARAMS
@ AV_FRAME_DATA_FILM_GRAIN_PARAMS
Film grain parameters for a frame, described by AVFilmGrainParams.
Definition: frame.h:188
VAR_OHSUB
@ VAR_OHSUB
Definition: vf_libplacebo.c:133
TONE_MAP_ST2094_40
@ TONE_MAP_ST2094_40
Definition: vf_libplacebo.c:69
LibplaceboContext::apply_filmgrain
int apply_filmgrain
Definition: vf_libplacebo.c:190
find_scaler
static int find_scaler(AVFilterContext *avctx, const struct pl_filter_config **opt, const char *name, int frame_mixing)
Definition: vf_libplacebo.c:348
normalize.log
log
Definition: normalize.py:21
GAMUT_MAP_COUNT
@ GAMUT_MAP_COUNT
Definition: vf_libplacebo.c:92
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:63
VAR_IN_IDX
@ VAR_IN_IDX
Definition: vf_libplacebo.c:119
AVFrame::opaque
void * opaque
Frame owner's private data.
Definition: frame.h:548
update_settings
static int update_settings(AVFilterContext *ctx)
Definition: vf_libplacebo.c:373
av_fifo_peek
int av_fifo_peek(const AVFifo *f, void *buf, size_t nb_elems, size_t offset)
Read data from a FIFO without modifying FIFO state.
Definition: fifo.c:255
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
AVCOL_TRC_NB
@ AVCOL_TRC_NB
Not part of ABI.
Definition: pixfmt.h:666
pl_options_t::deband_params
struct pl_deband_params deband_params
Definition: vf_libplacebo.c:53
AVVulkanDeviceContext::get_proc_addr
PFN_vkGetInstanceProcAddr get_proc_addr
Pointer to a vkGetInstanceProcAddr loading function.
Definition: hwcontext_vulkan.h:69
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:512
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:750
pl_av_log
static void pl_av_log(void *log_ctx, enum pl_log_level level, const char *msg)
Definition: vf_libplacebo.c:283
AVOption
AVOption.
Definition: opt.h:429
AVCOL_SPC_NB
@ AVCOL_SPC_NB
Not part of ABI.
Definition: pixfmt.h:693
b
#define b
Definition: input.c:42
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:647
GAMUT_MAP_LINEAR
@ GAMUT_MAP_LINEAR
Definition: vf_libplacebo.c:91
LibplaceboContext
Definition: vf_libplacebo.c:153
LibplaceboInput::status
int status
Definition: vf_libplacebo.c:150
LibplaceboContext::crop_h_pexpr
AVExpr * crop_h_pexpr
Definition: vf_libplacebo.c:183
av_pix_fmt_desc_next
const AVPixFmtDescriptor * av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev)
Iterate over all pixel format descriptors known to libavutil.
Definition: pixdesc.c:3348
AVVulkanDeviceContext::inst
VkInstance inst
Vulkan instance.
Definition: hwcontext_vulkan.h:74
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:75
AVCOL_PRI_JEDEC_P22
@ AVCOL_PRI_JEDEC_P22
Definition: pixfmt.h:636
TONE_MAP_SPLINE
@ TONE_MAP_SPLINE
Definition: vf_libplacebo.c:73
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
LibplaceboContext::tex
pl_tex tex[4]
Definition: vf_libplacebo.c:161
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition: pixfmt.h:674
ff_scale_eval_dimensions
int ff_scale_eval_dimensions(void *log_ctx, const char *w_expr, const char *h_expr, AVFilterLink *inlink, AVFilterLink *outlink, int *ret_w, int *ret_h)
Parse and evaluate string expressions for width and height.
Definition: scale_eval.c:57
AVCOL_TRC_BT2020_12
@ AVCOL_TRC_BT2020_12
ITU-R BT2020 for 12-bit system.
Definition: pixfmt.h:660
handle_input
static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
Definition: vf_libplacebo.c:1000
AVFilterContext::hw_device_ctx
AVBufferRef * hw_device_ctx
For filters which will create hardware frames, sets the device the filter should create them in.
Definition: avfilter.h:351
av_get_bits_per_pixel
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel used by the pixel format described by pixdesc.
Definition: pixdesc.c:3293
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2924
LibplaceboContext::sigmoid
int sigmoid
Definition: vf_libplacebo.c:212
LibplaceboContext::crop_h_expr
char * crop_h_expr
Definition: vf_libplacebo.c:179
AVDictionary
Definition: dict.c:32
pl_get_mapped_avframe
static AVFrame * pl_get_mapped_avframe(const struct pl_frame *frame)
Definition: vf_libplacebo.c:40
map_frame
static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src, struct pl_frame *out)
Definition: vf_libplacebo.c:969
VAR_OT
@ VAR_OT
Definition: vf_libplacebo.c:136
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:215
GAMUT_MAP_SATURATION
@ GAMUT_MAP_SATURATION
Definition: vf_libplacebo.c:86
pl_options_t::color_adjustment
struct pl_color_adjustment color_adjustment
Definition: vf_libplacebo.c:55
video.h
LibplaceboContext::vkctx
FFVulkanContext vkctx
Definition: vf_libplacebo.c:155
AVCOL_SPC_BT2020_CL
@ AVCOL_SPC_BT2020_CL
ITU-R BT2020 constant luminance system.
Definition: pixfmt.h:685
ff_make_formats_list_singleton
AVFilterFormats * ff_make_formats_list_singleton(int fmt)
Equivalent to ff_make_format_list({const int[]}{ fmt, -1 })
Definition: formats.c:529
VAR_CROP_H
@ VAR_CROP_H
Definition: vf_libplacebo.c:125
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:379
libplacebo_activate
static int libplacebo_activate(AVFilterContext *ctx)
Definition: vf_libplacebo.c:1062
AV_HWDEVICE_TYPE_VULKAN
@ AV_HWDEVICE_TYPE_VULKAN
Definition: hwcontext.h:39
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
AV_FRAME_FLAG_TOP_FIELD_FIRST
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition: frame.h:638
formats.h
av_expr_parse
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:710
unmap_frame
static void unmap_frame(pl_gpu gpu, struct pl_frame *frame, const struct pl_source_frame *src)
Definition: vf_libplacebo.c:988
VAR_VSUB
@ VAR_VSUB
Definition: vf_libplacebo.c:132
TONE_MAP_LINEAR
@ TONE_MAP_LINEAR
Definition: vf_libplacebo.c:78
libplacebo_config_output
static int libplacebo_config_output(AVFilterLink *outlink)
Definition: vf_libplacebo.c:1257
VAR_PH
@ VAR_PH
Definition: vf_libplacebo.c:127
ff_inlink_consume_frame
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1492
AVCOL_SPC_BT470BG
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition: pixfmt.h:679
FF_FILTER_FORWARD_STATUS_BACK_ALL
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
Definition: filters.h:650
fifo.h
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:286
AVCOL_TRC_IEC61966_2_1
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:658
av_file_map
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, int log_offset, void *log_ctx)
Read the file with name filename, and put its content in a newly allocated buffer or map it with mmap...
Definition: file.c:55
LibplaceboContext::pos_w_pexpr
AVExpr * pos_w_pexpr
Definition: vf_libplacebo.c:184
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:284
LibplaceboContext::shader_bin_len
int shader_bin_len
Definition: vf_libplacebo.c:266
fail
#define fail()
Definition: checkasm.h:196
av_fifo_write
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition: fifo.c:188
vulkan_filter.h
AV_PIX_FMT_FLAG_HWACCEL
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:128
AVCOL_RANGE_NB
@ AVCOL_RANGE_NB
Not part of ABI.
Definition: pixfmt.h:751
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:650
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:208
LibplaceboContext::nb_inputs
int nb_inputs
Definition: vf_libplacebo.c:165
lock_queue
static void lock_queue(AVHWDeviceContext *ctx, uint32_t queue_family, uint32_t index)
Definition: hwcontext_vulkan.c:1733
LibplaceboContext::pos_y_expr
char * pos_y_expr
Definition: vf_libplacebo.c:180
pts
static int64_t pts
Definition: transcode_aac.c:644
LibplaceboContext::crop_y_expr
char * crop_y_expr
Definition: vf_libplacebo.c:178
AVFILTER_FLAG_DYNAMIC_INPUTS
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition: avfilter.h:151
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:358
AVRational::num
int num
Numerator.
Definition: rational.h:59
LibplaceboContext::contrast_smoothness
float contrast_smoothness
Definition: vf_libplacebo.c:252
VAR_CROP_W
@ VAR_CROP_W
Definition: vf_libplacebo.c:124
AV_SIDE_DATA_PROP_SIZE_DEPENDENT
@ AV_SIDE_DATA_PROP_SIZE_DEPENDENT
Side data depends on the video dimensions.
Definition: frame.h:292
LibplaceboInput::renderer
pl_renderer renderer
Definition: vf_libplacebo.c:144
AVCOL_TRC_GAMMA22
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:649
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
GAMUT_MAP_PERCEPTUAL
@ GAMUT_MAP_PERCEPTUAL
Definition: vf_libplacebo.c:84
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
LibplaceboContext::extra_opts
AVDictionary * extra_opts
Definition: vf_libplacebo.c:197
VAR_OW
@ VAR_OW
Definition: vf_libplacebo.c:122
LibplaceboContext::antiringing
float antiringing
Definition: vf_libplacebo.c:211
preset
preset
Definition: vf_curves.c:47
avassert.h
LibplaceboContext::pos_w_expr
char * pos_w_expr
Definition: vf_libplacebo.c:181
LibplaceboContext::disable_linear
int disable_linear
Definition: vf_libplacebo.c:214
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
VAR_VARS_NB
@ VAR_VARS_NB
Definition: vf_libplacebo.c:138
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
LibplaceboContext::crop_x_expr
char * crop_x_expr
Definition: vf_libplacebo.c:178
FFFilter
Definition: filters.h:265
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:60
ff_outlink_set_status
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:627
ff_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1595
ref_frame
static const AVFrame * ref_frame(const struct pl_frame_mix *mix)
Definition: vf_libplacebo.c:773
output_frame
static int output_frame(AVFilterContext *ctx, int64_t pts)
Definition: vf_libplacebo.c:856
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVCOL_PRI_NB
@ AVCOL_PRI_NB
Not part of ABI.
Definition: pixfmt.h:637
LibplaceboContext::force_original_aspect_ratio
int force_original_aspect_ratio
Definition: vf_libplacebo.c:187
AVCOL_TRC_BT1361_ECG
@ AVCOL_TRC_BT1361_ECG
ITU-R BT1361 Extended Colour Gamut.
Definition: pixfmt.h:657
LibplaceboContext::force_dither
int force_dither
Definition: vf_libplacebo.c:216
LibplaceboContext::inputs
LibplaceboInput * inputs
Definition: vf_libplacebo.c:164
discard_frame
static void discard_frame(const struct pl_source_frame *src)
Definition: vf_libplacebo.c:994
AVCOL_SPC_SMPTE170M
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
Definition: pixfmt.h:680
AVDictionaryEntry::key
char * key
Definition: dict.h:91
LibplaceboContext::opts
pl_options opts
Definition: vf_libplacebo.c:207
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:678
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
libplacebo_uninit
static void libplacebo_uninit(AVFilterContext *avctx)
Definition: vf_libplacebo.c:727
LibplaceboContext::frame_mixer
char * frame_mixer
Definition: vf_libplacebo.c:210
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
filters.h
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
AVFormatContext * ctx
Definition: movenc.c:49
av_expr_eval
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:792
LibplaceboContext::tonemapping
int tonemapping
Definition: vf_libplacebo.c:247
AVCOL_PRI_SMPTE428
@ AVCOL_PRI_SMPTE428
SMPTE ST 428-1 (CIE 1931 XYZ)
Definition: pixfmt.h:631
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
AVExpr
Definition: eval.c:158
LibplaceboContext::crop_w_expr
char * crop_w_expr
Definition: vf_libplacebo.c:179
LibplaceboContext::disable_builtin
int disable_builtin
Definition: vf_libplacebo.c:215
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
TONE_MAP_BT2446A
@ TONE_MAP_BT2446A
Definition: vf_libplacebo.c:72
LibplaceboContext::color_trc
int color_trc
Definition: vf_libplacebo.c:195
libplacebo_process_command
static int libplacebo_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Definition: vf_libplacebo.c:760
TONE_MAP_MOBIUS
@ TONE_MAP_MOBIUS
Definition: vf_libplacebo.c:75
VAR_IN_T
@ VAR_IN_T
Definition: vf_libplacebo.c:135
ff_vf_libplacebo
const FFFilter ff_vf_libplacebo
Definition: vf_libplacebo.c:1542
LibplaceboContext::w_expr
char * w_expr
Definition: vf_libplacebo.c:174
AVCOL_PRI_SMPTE240M
@ AVCOL_PRI_SMPTE240M
identical to above, also called "SMPTE C" even though it uses D65
Definition: pixfmt.h:628
LibplaceboInput
Definition: vf_libplacebo.c:142
color_range
color_range
Definition: vf_selectivecolor.c:43
pl_options_t::peak_detect_params
struct pl_peak_detect_params peak_detect_params
Definition: vf_libplacebo.c:56
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
LibplaceboContext::force_divisible_by
int force_divisible_by
Definition: vf_libplacebo.c:188
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:622
NAN
#define NAN
Definition: mathematics.h:115
av_file_unmap
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
Definition: file.c:142
AVCOL_PRI_BT470BG
@ AVCOL_PRI_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:626
TONE_MAP_BT2390
@ TONE_MAP_BT2390
Definition: vf_libplacebo.c:71
TONE_MAP_GAMMA
@ TONE_MAP_GAMMA
Definition: vf_libplacebo.c:77
arg
const char * arg
Definition: jacosubdec.c:67
AVCOL_PRI_SMPTE170M
@ AVCOL_PRI_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
Definition: pixfmt.h:627
if
if(ret)
Definition: filter_design.txt:179
av_log_get_level
int av_log_get_level(void)
Get the current log level.
Definition: log.c:469
get_tonemapping_func
static const struct pl_tone_map_function * get_tonemapping_func(int tm)
Definition: vf_libplacebo.c:300
VAR_IW
@ VAR_IW
Definition: vf_libplacebo.c:120
AVVulkanDeviceContext
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_vulkan.h:59
opts
AVDictionary * opts
Definition: movenc.c:51
TONE_MAP_ST2094_10
@ TONE_MAP_ST2094_10
Definition: vf_libplacebo.c:70
VAR_PW
@ VAR_PW
Definition: vf_libplacebo.c:126
NULL
#define NULL
Definition: coverity.c:32
LibplaceboContext::dither_temporal
int dither_temporal
Definition: vf_libplacebo.c:257
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:597
TONE_MAP_HABLE
@ TONE_MAP_HABLE
Definition: vf_libplacebo.c:76
AVVulkanDeviceContext::nb_enabled_dev_extensions
int nb_enabled_dev_extensions
Definition: hwcontext_vulkan.h:113
LibplaceboContext::skip_aa
int skip_aa
Definition: vf_libplacebo.c:213
LibplaceboContext::shader_bin
void * shader_bin
Definition: vf_libplacebo.c:265
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
LibplaceboContext::cones
int cones
Definition: vf_libplacebo.c:260
AVCOL_TRC_IEC61966_2_4
@ AVCOL_TRC_IEC61966_2_4
IEC 61966-2-4.
Definition: pixfmt.h:656
ff_append_inpad_free_name
int ff_append_inpad_free_name(AVFilterContext *f, AVFilterPad *p)
Definition: avfilter.c:132
LibplaceboContext::brightness
float brightness
Definition: vf_libplacebo.c:232
activate
filter_frame For filters that do not use the activate() callback
AV_OPT_TYPE_COLOR
@ AV_OPT_TYPE_COLOR
Underlying C type is uint8_t[4].
Definition: opt.h:323
AVVulkanDeviceContext::unlock_queue
void(* unlock_queue)(struct AVHWDeviceContext *ctx, uint32_t queue_family, uint32_t index)
Similar to lock_queue(), unlocks a queue.
Definition: hwcontext_vulkan.h:178
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition: opt.h:290
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:277
LibplaceboContext::gpu
pl_gpu gpu
Definition: vf_libplacebo.c:160
AVCOL_PRI_BT709
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition: pixfmt.h:621
ff_add_format
int ff_add_format(AVFilterFormats **avff, int64_t fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:504
parseutils.h
VAR_OUT_W
@ VAR_OUT_W
Definition: vf_libplacebo.c:122
AVFilterFormats::nb_formats
unsigned nb_formats
number of formats
Definition: formats.h:65
ff_vk_filter_config_output
int ff_vk_filter_config_output(AVFilterLink *outlink)
Definition: vulkan_filter.c:209
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:227
LibplaceboContext::fillcolor
uint8_t fillcolor[4]
Definition: vf_libplacebo.c:172
double
double
Definition: af_crystalizer.c:132
AVCOL_TRC_BT2020_10
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:659
AVCOL_SPC_YCGCO
@ AVCOL_SPC_YCGCO
used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
Definition: pixfmt.h:682
VAR_OUT_H
@ VAR_OUT_H
Definition: vf_libplacebo.c:123
input_init
static int input_init(AVFilterContext *avctx, LibplaceboInput *input, int idx)
Definition: vf_libplacebo.c:620
LibplaceboContext::status_pts
int64_t status_pts
tracks status of most recently used input
Definition: vf_libplacebo.c:166
FFVulkanContext
Definition: vulkan.h:274
ff_all_color_spaces
AVFilterFormats * ff_all_color_spaces(void)
Construct an AVFilterFormats representing all possible color spaces.
Definition: formats.c:630
AVFilterFormats::refcount
unsigned refcount
number of references to this list
Definition: formats.h:68
AVPixFmtDescriptor::flags
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:94
ff_inlink_acknowledge_status
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1439
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:716
parse_shader
static int parse_shader(AVFilterContext *avctx, const void *shader, size_t len)
Definition: vf_libplacebo.c:490
set_gamut_mode
static void set_gamut_mode(struct pl_color_map_params *p, int gamut_mode)
Definition: vf_libplacebo.c:320
libplacebo_config_input
static int libplacebo_config_input(AVFilterLink *inlink)
Definition: vf_libplacebo.c:1230
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:121
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:197
VAR_CW
@ VAR_CW
Definition: vf_libplacebo.c:124
AVCOL_PRI_BT2020
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition: pixfmt.h:630
LibplaceboInput::status_pts
int64_t status_pts
Definition: vf_libplacebo.c:149
FF_FILTER_FLAG_HWFRAME_AWARE
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
Definition: filters.h:206
LibplaceboContext::cone_str
float cone_str
Definition: vf_libplacebo.c:261
LibplaceboContext::have_hwdevice
int have_hwdevice
Definition: vf_libplacebo.c:204
color_primaries
static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB]
Definition: csp.c:76
init_vulkan
static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwctx)
Definition: vf_libplacebo.c:641
LibplaceboContext::hue
float hue
Definition: vf_libplacebo.c:235
AVCOL_TRC_SMPTE2084
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition: pixfmt.h:661
AVCOL_PRI_SMPTE431
@ AVCOL_PRI_SMPTE431
SMPTE ST 431-2 (2011) / DCI P3.
Definition: pixfmt.h:633
eval.h
GAMUT_MAP_ABSOLUTE
@ GAMUT_MAP_ABSOLUTE
Definition: vf_libplacebo.c:87
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
AVFifo
Definition: fifo.c:35
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:94
AVCOL_TRC_SMPTE240M
@ AVCOL_TRC_SMPTE240M
Definition: pixfmt.h:652
AVCOL_PRI_FILM
@ AVCOL_PRI_FILM
colour filters using Illuminant C
Definition: pixfmt.h:629
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: af_acrusher.c:307
TONE_MAP_REINHARD
@ TONE_MAP_REINHARD
Definition: vf_libplacebo.c:74
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(libplacebo)
LibplaceboContext::deband_grain
float deband_grain
Definition: vf_libplacebo.c:229
LibplaceboInput::mix
struct pl_frame_mix mix
temporary storage
Definition: vf_libplacebo.c:147
AVFILTER_FLAG_HWDEVICE
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition: avfilter.h:183
LibplaceboContext::out_format_string
char * out_format_string
Definition: vf_libplacebo.c:170
LibplaceboContext::disable_fbos
int disable_fbos
Definition: vf_libplacebo.c:217
LibplaceboContext::saturation
float saturation
Definition: vf_libplacebo.c:234
GAMUT_MAP_DARKEN
@ GAMUT_MAP_DARKEN
Definition: vf_libplacebo.c:89
LibplaceboContext::num_hooks
int num_hooks
Definition: vf_libplacebo.c:268
LibplaceboContext::status
int status
Definition: vf_libplacebo.c:167
TONE_MAP_CLIP
@ TONE_MAP_CLIP
Definition: vf_libplacebo.c:68
libplacebo_options
static const AVOption libplacebo_options[]
Definition: vf_libplacebo.c:1349
scale_eval.h
sigmoid
static float sigmoid(float x)
Definition: vf_dnn_detect.c:90
frame.h
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:900
av_frame_remove_side_data
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
Remove and free all side data instances of the given type.
Definition: frame.c:723
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
pl_options_alloc
#define pl_options_alloc(log)
Definition: vf_libplacebo.c:62
ff_all_color_ranges
AVFilterFormats * ff_all_color_ranges(void)
Construct an AVFilterFormats representing all possible color ranges.
Definition: formats.c:646
LibplaceboContext::var_values
double var_values[VAR_VARS_NB]
Definition: vf_libplacebo.c:173
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
LibplaceboContext::normalize_sar
int normalize_sar
Definition: vf_libplacebo.c:189
av_pix_fmt_desc_get_id
enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc)
Definition: pixdesc.c:3360
LibplaceboContext::corner_rounding
float corner_rounding
Definition: vf_libplacebo.c:186
LibplaceboContext::apply_dovi
int apply_dovi
Definition: vf_libplacebo.c:191
VAR_POS_H
@ VAR_POS_H
Definition: vf_libplacebo.c:127
av_frame_side_data_remove_by_props
void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd, int props)
Remove and free all side data instances that match any of the given side data properties.
Definition: side_data.c:115
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
LibplaceboContext::downscaler
char * downscaler
Definition: vf_libplacebo.c:209
LibplaceboContext::log
pl_log log
Definition: vf_libplacebo.c:158
LibplaceboContext::vulkan
pl_vulkan vulkan
Definition: vf_libplacebo.c:159
M_PI
#define M_PI
Definition: mathematics.h:67
AVVulkanDeviceContext::lock_queue
void(* lock_queue)(struct AVHWDeviceContext *ctx, uint32_t queue_family, uint32_t index)
Locks a queue, preventing other threads from submitting any command buffers to this queue.
Definition: hwcontext_vulkan.h:173
LibplaceboContext::pos_h_pexpr
AVExpr * pos_h_pexpr
Definition: vf_libplacebo.c:184
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
AVCOL_TRC_BT709
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition: pixfmt.h:646
av_vkfmt_from_pixfmt
const VkFormat * av_vkfmt_from_pixfmt(enum AVPixelFormat p)
Returns the optimal per-plane Vulkan format for a given sw_format, one for each plane.
Definition: hwcontext_stub.c:30
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition: opt.h:271
GAMUT_MAP_HIGHLIGHT
@ GAMUT_MAP_HIGHLIGHT
Definition: vf_libplacebo.c:90
AVCOL_SPC_SMPTE240M
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
Definition: pixfmt.h:681
av_parse_video_rate
int av_parse_video_rate(AVRational *rate, const char *arg)
Parse str and store the detected values in *rate.
Definition: parseutils.c:181
get_log_level
static enum pl_log_level get_log_level(void)
Definition: vf_libplacebo.c:271
ff_formats_unref
void ff_formats_unref(AVFilterFormats **ref)
If *ref is non-NULL, remove *ref as a reference to the format list it currently points to,...
Definition: formats.c:717
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
LibplaceboContext::pos_x_expr
char * pos_x_expr
Definition: vf_libplacebo.c:180
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
LibplaceboContext::upscaler
char * upscaler
Definition: vf_libplacebo.c:208
pl_options_t::params
struct pl_render_params params
Definition: vf_libplacebo.c:51
AVCOL_SPC_BT2020_NCL
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:684
pl_options_free
#define pl_options_free(ptr)
Definition: vf_libplacebo.c:63
av_gcd_q
AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def)
Return the best rational so that a and b are multiple of it.
Definition: rational.c:184
LibplaceboContext::gamma
float gamma
Definition: vf_libplacebo.c:236
algo
Definition: dct.c:57
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
VAR_OVSUB
@ VAR_OVSUB
Definition: vf_libplacebo.c:134
LibplaceboInput::qstatus
enum pl_queue_status qstatus
Definition: vf_libplacebo.c:146
FILTER_QUERY_FUNC2
#define FILTER_QUERY_FUNC2(func)
Definition: filters.h:239
LibplaceboContext::tonemapping_lut_size
int tonemapping_lut_size
Definition: vf_libplacebo.c:250
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
LibplaceboContext::tonemapping_param
float tonemapping_param
Definition: vf_libplacebo.c:248
AV_PIX_FMT_FLAG_BE
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
Definition: pixdesc.h:116
LibplaceboContext::pos_h_expr
char * pos_h_expr
Definition: vf_libplacebo.c:181
LibplaceboContext::color_primaries
int color_primaries
Definition: vf_libplacebo.c:194
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
len
int len
Definition: vorbis_enc_data.h:426
var_names
static const char *const var_names[]
Definition: vf_libplacebo.c:95
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:676
LibplaceboContext::dithering
int dithering
Definition: vf_libplacebo.c:255
LibplaceboContext::scene_high
float scene_high
Definition: vf_libplacebo.c:242
STATIC
#define STATIC
Definition: vf_libplacebo.c:1346
drain_input_pts
static void drain_input_pts(LibplaceboInput *in, int64_t until)
Definition: vf_libplacebo.c:1055
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:633
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:733
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
LibplaceboContext::skip_spatial_check
int skip_spatial_check
Definition: vf_libplacebo.c:221
AV_SIDE_DATA_PROP_COLOR_DEPENDENT
@ AV_SIDE_DATA_PROP_COLOR_DEPENDENT
Side data depends on the video color space.
Definition: frame.h:299
LibplaceboInput::queue
pl_queue queue
Definition: vf_libplacebo.c:145
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
pl_options_t::dither_params
struct pl_dither_params dither_params
Definition: vf_libplacebo.c:58
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:116
AVCOL_PRI_BT470M
@ AVCOL_PRI_BT470M
also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:624
ret
ret
Definition: filter_design.txt:187
pl_options_t::deinterlace_params
struct pl_deinterlace_params deinterlace_params
Definition: vf_libplacebo.c:52
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:204
pixfmt
enum AVPixelFormat pixfmt
Definition: kmsgrab.c:367
AVHWDeviceContext::type
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:73
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
LibplaceboContext::scene_low
float scene_low
Definition: vf_libplacebo.c:241
VAR_OH
@ VAR_OH
Definition: vf_libplacebo.c:123
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:151
VAR_CH
@ VAR_CH
Definition: vf_libplacebo.c:125
unlock_queue
static void unlock_queue(AVHWDeviceContext *ctx, uint32_t queue_family, uint32_t index)
Definition: hwcontext_vulkan.c:1739
av_fifo_alloc2
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition: fifo.c:47
VAR_T
@ VAR_T
Definition: vf_libplacebo.c:135
LibplaceboContext::peakdetect
int peakdetect
Definition: vf_libplacebo.c:239
av_get_pix_fmt
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:3273
LibplaceboContext::deband_radius
float deband_radius
Definition: vf_libplacebo.c:228
LibplaceboInput::idx
int idx
Definition: vf_libplacebo.c:143
AVCOL_TRC_ARIB_STD_B67
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:665
status
ov_status_e status
Definition: dnn_backend_openvino.c:100
LibplaceboContext::contrast_recovery
float contrast_recovery
Definition: vf_libplacebo.c:251
VAR_IN_W
@ VAR_IN_W
Definition: vf_libplacebo.c:120
update_crops
static void update_crops(AVFilterContext *ctx, LibplaceboInput *in, struct pl_frame *target, double target_pts)
Definition: vf_libplacebo.c:782
libplacebo_outputs
static const AVFilterPad libplacebo_outputs[]
Definition: vf_libplacebo.c:1534
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
VAR_HSUB
@ VAR_HSUB
Definition: vf_libplacebo.c:131
LibplaceboContext::inverse_tonemapping
int inverse_tonemapping
Definition: vf_libplacebo.c:249
TONE_MAP_COUNT
@ TONE_MAP_COUNT
Definition: vf_libplacebo.c:79
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
LibplaceboContext::rotation
int rotation
Definition: vf_libplacebo.c:196
AVCOL_TRC_SMPTE170M
@ AVCOL_TRC_SMPTE170M
also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC
Definition: pixfmt.h:651
file.h
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
OFFSET
#define OFFSET(x)
Definition: vf_libplacebo.c:1345
VAR_SAR
@ VAR_SAR
Definition: vf_libplacebo.c:129
LibplaceboContext::fps
AVRational fps
parsed FPS, or 0/0 for "none"
Definition: vf_libplacebo.c:177
input_uninit
static void input_uninit(LibplaceboInput *input)
Definition: vf_libplacebo.c:634
AVFilterContext
An instance of a filter.
Definition: avfilter.h:269
desc
const char * desc
Definition: libsvtav1.c:79
AVVulkanDeviceContext::enabled_dev_extensions
const char *const * enabled_dev_extensions
Enabled device extensions.
Definition: hwcontext_vulkan.h:112
ff_vk_filter_config_input
int ff_vk_filter_config_input(AVFilterLink *inlink)
Definition: vulkan_filter.c:176
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:269
libplacebo_query_format
static int libplacebo_query_format(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: vf_libplacebo.c:1144
mem.h
VAR_IDX
@ VAR_IDX
Definition: vf_libplacebo.c:119
AVFilterFormatsConfig::formats
AVFilterFormats * formats
List of supported formats (pixel or sample).
Definition: avfilter.h:126
LibplaceboInput::out_pts
AVFifo * out_pts
timestamps of wanted output frames
Definition: vf_libplacebo.c:148
LibplaceboContext::crop_w_pexpr
AVExpr * crop_w_pexpr
Definition: vf_libplacebo.c:183
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
LibplaceboContext::pad_crop_ratio
float pad_crop_ratio
Definition: vf_libplacebo.c:185
AVVulkanDeviceContext::act_dev
VkDevice act_dev
Active device.
Definition: hwcontext_vulkan.h:84
AVCOL_PRI_SMPTE432
@ AVCOL_PRI_SMPTE432
SMPTE ST 432-1 (2010) / P3 D65 / Display P3.
Definition: pixfmt.h:634
AVDictionaryEntry
Definition: dict.h:90
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
VAR_POS_W
@ VAR_POS_W
Definition: vf_libplacebo.c:126
max_q
static AVRational max_q(AVRational a, AVRational b)
Definition: vf_libplacebo.c:1252
LibplaceboContext::smoothing
float smoothing
Definition: vf_libplacebo.c:240
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition: opt.h:255
pl_options_t::color_map_params
struct pl_color_map_params color_map_params
Definition: vf_libplacebo.c:57
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
DYNAMIC
#define DYNAMIC
Definition: vf_libplacebo.c:1347
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
VAR_N
@ VAR_N
Definition: vf_libplacebo.c:137
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
LibplaceboContext::shader_path
char * shader_path
Definition: vf_libplacebo.c:264
VAR_A
@ VAR_A
Definition: vf_libplacebo.c:128
LibplaceboContext::crop_x_pexpr
AVExpr * crop_x_pexpr
Definition: vf_libplacebo.c:183
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
ff_outlink_frame_wanted
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the ff_outlink_frame_wanted() function. If this function returns true
AVVulkanDeviceContext::device_features
VkPhysicalDeviceFeatures2 device_features
This structure should be set to the set of features that present and enabled during device creation.
Definition: hwcontext_vulkan.h:92
LibplaceboContext::color_range
int color_range
Definition: vf_libplacebo.c:193
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
LibplaceboContext::dither_lut_size
int dither_lut_size
Definition: vf_libplacebo.c:256
LibplaceboContext::pos_x_pexpr
AVExpr * pos_x_pexpr
Definition: vf_libplacebo.c:184
libplacebo_init
static int libplacebo_init(AVFilterContext *avctx)
Definition: vf_libplacebo.c:509
TONE_MAP_AUTO
@ TONE_MAP_AUTO
Definition: vf_libplacebo.c:67
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition: pixfmt.h:675
LibplaceboContext::h_expr
char * h_expr
Definition: vf_libplacebo.c:175
VAR_DAR
@ VAR_DAR
Definition: vf_libplacebo.c:130
pl_options_t::cone_params
struct pl_cone_params cone_params
Definition: vf_libplacebo.c:59
AVCOL_SPC_ICTCP
@ AVCOL_SPC_ICTCP
ITU-R BT.2100-0, ICtCp.
Definition: pixfmt.h:689
LibplaceboContext::hooks
const struct pl_hook * hooks[2]
Definition: vf_libplacebo.c:267
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
ff_scale_adjust_dimensions
int ff_scale_adjust_dimensions(AVFilterLink *inlink, int *ret_w, int *ret_h, int force_original_aspect_ratio, int force_divisible_by, double w_adj)
Transform evaluated width and height obtained from ff_scale_eval_dimensions into actual target width ...
Definition: scale_eval.c:113
av_rescale_q_rnd
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, enum AVRounding rnd)
Rescale a 64-bit integer by 2 rational numbers with specified rounding.
Definition: mathematics.c:134
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
LibplaceboContext::pos_y_pexpr
AVExpr * pos_y_pexpr
Definition: vf_libplacebo.c:184
src
#define src
Definition: vp8dsp.c:248
AV_FIFO_FLAG_AUTO_GROW
#define AV_FIFO_FLAG_AUTO_GROW
Automatically resize the FIFO on writes, so that the data fits.
Definition: fifo.h:63
log_cb
static void log_cb(cmsContext ctx, cmsUInt32Number error, const char *str)
Definition: fflcms2.c:24
pl_options_t
Definition: vf_libplacebo.c:49
LibplaceboContext::send_fields
int send_fields
Definition: vf_libplacebo.c:222
GAMUT_MAP_CLIP
@ GAMUT_MAP_CLIP
Definition: vf_libplacebo.c:83