FFmpeg
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/mem.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/parseutils.h"
26 #include "formats.h"
27 #include "internal.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_deband_params deband_params;
53  struct pl_sigmoid_params sigmoid_params;
54  struct pl_color_adjustment color_adjustment;
55  struct pl_peak_detect_params peak_detect_params;
56  struct pl_color_map_params color_map_params;
57  struct pl_dither_params dither_params;
58  struct pl_cone_params cone_params;
59 } *pl_options;
60 
61 #define pl_options_alloc(log) av_mallocz(sizeof(struct pl_options_t))
62 #define pl_options_free(ptr) av_freep(ptr)
63 #endif
64 
65 enum {
79 };
80 
81 enum {
92 };
93 
94 static const char *const var_names[] = {
95  "in_idx", "idx",///< index of input
96  "in_w", "iw", ///< width of the input video frame
97  "in_h", "ih", ///< height of the input video frame
98  "out_w", "ow", ///< width of the output video frame
99  "out_h", "oh", ///< height of the output video frame
100  "crop_w", "cw", ///< evaluated input crop width
101  "crop_h", "ch", ///< evaluated input crop height
102  "pos_w", "pw", ///< evaluated output placement width
103  "pos_h", "ph", ///< evaluated output placement height
104  "a", ///< iw/ih
105  "sar", ///< input pixel aspect ratio
106  "dar", ///< output pixel aspect ratio
107  "hsub", ///< input horizontal subsampling factor
108  "vsub", ///< input vertical subsampling factor
109  "ohsub", ///< output horizontal subsampling factor
110  "ovsub", ///< output vertical subsampling factor
111  "in_t", "t", ///< input frame pts
112  "out_t", "ot", ///< output frame pts
113  "n", ///< number of frame
114  NULL,
115 };
116 
117 enum var_name {
138 };
139 
140 /* per-input dynamic filter state */
141 typedef struct LibplaceboInput {
142  int idx;
143  pl_renderer renderer;
144  pl_queue queue;
145  enum pl_queue_status qstatus;
146  struct pl_frame_mix mix; ///< temporary storage
148  AVFifo *out_pts; ///< timestamps of wanted output frames
149  int64_t status_pts;
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  char *fillcolor;
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
197 
198  /* pl_render_params */
199  pl_options opts;
200  char *upscaler;
201  char *downscaler;
202  char *frame_mixer;
204  float antiringing;
205  int sigmoid;
206  int skip_aa;
212 
213  /* pl_deband_params */
214  int deband;
219 
220  /* pl_color_adjustment */
221  float brightness;
222  float contrast;
223  float saturation;
224  float hue;
225  float gamma;
226 
227  /* pl_peak_detect_params */
229  float smoothing;
230  float min_peak;
231  float scene_low;
232  float scene_high;
233  float percentile;
234 
235  /* pl_color_map_params */
243 
244  /* pl_dither_params */
248 
249  /* pl_cone_params */
250  int cones;
251  float cone_str;
252 
253  /* custom shaders */
254  char *shader_path;
255  void *shader_bin;
257  const struct pl_hook *hooks[2];
260 
261 static inline enum pl_log_level get_log_level(void)
262 {
263  int av_lev = av_log_get_level();
264  return av_lev >= AV_LOG_TRACE ? PL_LOG_TRACE :
265  av_lev >= AV_LOG_DEBUG ? PL_LOG_DEBUG :
266  av_lev >= AV_LOG_VERBOSE ? PL_LOG_INFO :
267  av_lev >= AV_LOG_WARNING ? PL_LOG_WARN :
268  av_lev >= AV_LOG_ERROR ? PL_LOG_ERR :
269  av_lev >= AV_LOG_FATAL ? PL_LOG_FATAL :
270  PL_LOG_NONE;
271 }
272 
273 static void pl_av_log(void *log_ctx, enum pl_log_level level, const char *msg)
274 {
275  int av_lev;
276 
277  switch (level) {
278  case PL_LOG_FATAL: av_lev = AV_LOG_FATAL; break;
279  case PL_LOG_ERR: av_lev = AV_LOG_ERROR; break;
280  case PL_LOG_WARN: av_lev = AV_LOG_WARNING; break;
281  case PL_LOG_INFO: av_lev = AV_LOG_VERBOSE; break;
282  case PL_LOG_DEBUG: av_lev = AV_LOG_DEBUG; break;
283  case PL_LOG_TRACE: av_lev = AV_LOG_TRACE; break;
284  default: return;
285  }
286 
287  av_log(log_ctx, av_lev, "%s\n", msg);
288 }
289 
290 static const struct pl_tone_map_function *get_tonemapping_func(int tm) {
291  switch (tm) {
292  case TONE_MAP_AUTO: return &pl_tone_map_auto;
293  case TONE_MAP_CLIP: return &pl_tone_map_clip;
294 #if PL_API_VER >= 246
295  case TONE_MAP_ST2094_40: return &pl_tone_map_st2094_40;
296  case TONE_MAP_ST2094_10: return &pl_tone_map_st2094_10;
297 #endif
298  case TONE_MAP_BT2390: return &pl_tone_map_bt2390;
299  case TONE_MAP_BT2446A: return &pl_tone_map_bt2446a;
300  case TONE_MAP_SPLINE: return &pl_tone_map_spline;
301  case TONE_MAP_REINHARD: return &pl_tone_map_reinhard;
302  case TONE_MAP_MOBIUS: return &pl_tone_map_mobius;
303  case TONE_MAP_HABLE: return &pl_tone_map_hable;
304  case TONE_MAP_GAMMA: return &pl_tone_map_gamma;
305  case TONE_MAP_LINEAR: return &pl_tone_map_linear;
306  default: av_assert0(0);
307  }
308 }
309 
310 static void set_gamut_mode(struct pl_color_map_params *p, int gamut_mode)
311 {
312  switch (gamut_mode) {
313 #if PL_API_VER >= 269
314  case GAMUT_MAP_CLIP: p->gamut_mapping = &pl_gamut_map_clip; return;
315  case GAMUT_MAP_PERCEPTUAL: p->gamut_mapping = &pl_gamut_map_perceptual; return;
316  case GAMUT_MAP_RELATIVE: p->gamut_mapping = &pl_gamut_map_relative; return;
317  case GAMUT_MAP_SATURATION: p->gamut_mapping = &pl_gamut_map_saturation; return;
318  case GAMUT_MAP_ABSOLUTE: p->gamut_mapping = &pl_gamut_map_absolute; return;
319  case GAMUT_MAP_DESATURATE: p->gamut_mapping = &pl_gamut_map_desaturate; return;
320  case GAMUT_MAP_DARKEN: p->gamut_mapping = &pl_gamut_map_darken; return;
321  case GAMUT_MAP_HIGHLIGHT: p->gamut_mapping = &pl_gamut_map_highlight; return;
322  case GAMUT_MAP_LINEAR: p->gamut_mapping = &pl_gamut_map_linear; return;
323 #else
324  case GAMUT_MAP_RELATIVE: p->intent = PL_INTENT_RELATIVE_COLORIMETRIC; return;
325  case GAMUT_MAP_SATURATION: p->intent = PL_INTENT_SATURATION; return;
326  case GAMUT_MAP_ABSOLUTE: p->intent = PL_INTENT_ABSOLUTE_COLORIMETRIC; return;
327  case GAMUT_MAP_DESATURATE: p->gamut_mode = PL_GAMUT_DESATURATE; return;
328  case GAMUT_MAP_DARKEN: p->gamut_mode = PL_GAMUT_DARKEN; return;
329  case GAMUT_MAP_HIGHLIGHT: p->gamut_mode = PL_GAMUT_WARN; return;
330  /* Use defaults for all other cases */
331  default: return;
332 #endif
333  }
334 
335  av_assert0(0);
336 };
337 
338 static int find_scaler(AVFilterContext *avctx,
339  const struct pl_filter_config **opt,
340  const char *name, int frame_mixing)
341 {
342  const struct pl_filter_preset *preset, *presets_avail;
343  presets_avail = frame_mixing ? pl_frame_mixers : pl_scale_filters;
344 
345  if (!strcmp(name, "help")) {
346  av_log(avctx, AV_LOG_INFO, "Available scaler presets:\n");
347  for (preset = presets_avail; preset->name; preset++)
348  av_log(avctx, AV_LOG_INFO, " %s\n", preset->name);
349  return AVERROR_EXIT;
350  }
351 
352  for (preset = presets_avail; preset->name; preset++) {
353  if (!strcmp(name, preset->name)) {
354  *opt = preset->filter;
355  return 0;
356  }
357  }
358 
359  av_log(avctx, AV_LOG_ERROR, "No such scaler preset '%s'.\n", name);
360  return AVERROR(EINVAL);
361 }
362 
364 {
365  int err = 0;
366  LibplaceboContext *s = ctx->priv;
367  AVDictionaryEntry *e = NULL;
368  pl_options opts = s->opts;
369  int gamut_mode = s->gamut_mode;
370  uint8_t color_rgba[4];
371 
372  RET(av_parse_color(color_rgba, s->fillcolor, -1, s));
373 
374  opts->deband_params = *pl_deband_params(
375  .iterations = s->deband_iterations,
376  .threshold = s->deband_threshold,
377  .radius = s->deband_radius,
378  .grain = s->deband_grain,
379  );
380 
381  opts->sigmoid_params = pl_sigmoid_default_params;
382 
383  opts->color_adjustment = (struct pl_color_adjustment) {
384  .brightness = s->brightness,
385  .contrast = s->contrast,
386  .saturation = s->saturation,
387  .hue = s->hue,
388  .gamma = s->gamma,
389  };
390 
391  opts->peak_detect_params = *pl_peak_detect_params(
392  .smoothing_period = s->smoothing,
393  .minimum_peak = s->min_peak,
394  .scene_threshold_low = s->scene_low,
395  .scene_threshold_high = s->scene_high,
396 #if PL_API_VER >= 263
397  .percentile = s->percentile,
398 #endif
399  );
400 
401  opts->color_map_params = *pl_color_map_params(
402  .tone_mapping_function = get_tonemapping_func(s->tonemapping),
403  .tone_mapping_param = s->tonemapping_param,
404  .inverse_tone_mapping = s->inverse_tonemapping,
405  .lut_size = s->tonemapping_lut_size,
406 #if PL_API_VER >= 285
407  .contrast_recovery = s->contrast_recovery,
408  .contrast_smoothness = s->contrast_smoothness,
409 #endif
410  );
411 
412  set_gamut_mode(&opts->color_map_params, gamut_mode);
413 
414  opts->dither_params = *pl_dither_params(
415  .method = s->dithering,
416  .lut_size = s->dither_lut_size,
417  .temporal = s->dither_temporal,
418  );
419 
420  opts->cone_params = *pl_cone_params(
421  .cones = s->cones,
422  .strength = s->cone_str,
423  );
424 
425  opts->params = *pl_render_params(
426  .lut_entries = s->lut_entries,
427  .antiringing_strength = s->antiringing,
428  .background_transparency = 1.0f - (float) color_rgba[3] / UINT8_MAX,
429  .background_color = {
430  (float) color_rgba[0] / UINT8_MAX,
431  (float) color_rgba[1] / UINT8_MAX,
432  (float) color_rgba[2] / UINT8_MAX,
433  },
434 #if PL_API_VER >= 277
435  .corner_rounding = s->corner_rounding,
436 #endif
437 
438  .deband_params = s->deband ? &opts->deband_params : NULL,
439  .sigmoid_params = s->sigmoid ? &opts->sigmoid_params : NULL,
440  .color_adjustment = &opts->color_adjustment,
441  .peak_detect_params = s->peakdetect ? &opts->peak_detect_params : NULL,
442  .color_map_params = &opts->color_map_params,
443  .dither_params = s->dithering >= 0 ? &opts->dither_params : NULL,
444  .cone_params = s->cones ? &opts->cone_params : NULL,
445 
446  .hooks = s->hooks,
447  .num_hooks = s->num_hooks,
448 
449  .skip_anti_aliasing = s->skip_aa,
450  .polar_cutoff = s->polar_cutoff,
451  .disable_linear_scaling = s->disable_linear,
452  .disable_builtin_scalers = s->disable_builtin,
453  .force_dither = s->force_dither,
454  .disable_fbos = s->disable_fbos,
455  );
456 
457  RET(find_scaler(ctx, &opts->params.upscaler, s->upscaler, 0));
458  RET(find_scaler(ctx, &opts->params.downscaler, s->downscaler, 0));
459  RET(find_scaler(ctx, &opts->params.frame_mixer, s->frame_mixer, 1));
460 
461 #if PL_API_VER >= 309
462  while ((e = av_dict_get(s->extra_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
463  if (!pl_options_set_str(s->opts, e->key, e->value)) {
464  err = AVERROR(EINVAL);
465  goto fail;
466  }
467  }
468 #else
469  (void) e;
470  if (av_dict_count(s->extra_opts) > 0)
471  av_log(s, AV_LOG_WARNING, "extra_opts requires libplacebo >= 6.309!\n");
472 #endif
473 
474  return 0;
475 
476 fail:
477  return err;
478 }
479 
480 static int parse_shader(AVFilterContext *avctx, const void *shader, size_t len)
481 {
482  LibplaceboContext *s = avctx->priv;
483  const struct pl_hook *hook;
484 
485  hook = pl_mpv_user_shader_parse(s->gpu, shader, len);
486  if (!hook) {
487  av_log(s, AV_LOG_ERROR, "Failed parsing custom shader!\n");
488  return AVERROR(EINVAL);
489  }
490 
491  s->hooks[s->num_hooks++] = hook;
492  return update_settings(avctx);
493 }
494 
495 static void libplacebo_uninit(AVFilterContext *avctx);
497 
499 {
500  int err = 0;
501  LibplaceboContext *s = avctx->priv;
502 
503  /* Create libplacebo log context */
504  s->log = pl_log_create(PL_API_VER, pl_log_params(
505  .log_level = get_log_level(),
506  .log_cb = pl_av_log,
507  .log_priv = s,
508  ));
509 
510  if (!s->log)
511  return AVERROR(ENOMEM);
512 
513  s->opts = pl_options_alloc(s->log);
514  if (!s->opts) {
515  libplacebo_uninit(avctx);
516  return AVERROR(ENOMEM);
517  }
518 
519  if (s->out_format_string) {
520  s->out_format = av_get_pix_fmt(s->out_format_string);
521  if (s->out_format == AV_PIX_FMT_NONE) {
522  av_log(avctx, AV_LOG_ERROR, "Invalid output format: %s\n",
523  s->out_format_string);
524  libplacebo_uninit(avctx);
525  return AVERROR(EINVAL);
526  }
527  } else {
528  s->out_format = AV_PIX_FMT_NONE;
529  }
530 
531  for (int i = 0; i < s->nb_inputs; i++) {
532  AVFilterPad pad = {
533  .name = av_asprintf("input%d", i),
534  .type = AVMEDIA_TYPE_VIDEO,
535  .config_props = &libplacebo_config_input,
536  };
537  if (!pad.name)
538  return AVERROR(ENOMEM);
539  RET(ff_append_inpad_free_name(avctx, &pad));
540  }
541 
542  RET(update_settings(avctx));
543  RET(av_expr_parse(&s->crop_x_pexpr, s->crop_x_expr, var_names,
544  NULL, NULL, NULL, NULL, 0, s));
545  RET(av_expr_parse(&s->crop_y_pexpr, s->crop_y_expr, var_names,
546  NULL, NULL, NULL, NULL, 0, s));
547  RET(av_expr_parse(&s->crop_w_pexpr, s->crop_w_expr, var_names,
548  NULL, NULL, NULL, NULL, 0, s));
549  RET(av_expr_parse(&s->crop_h_pexpr, s->crop_h_expr, var_names,
550  NULL, NULL, NULL, NULL, 0, s));
551  RET(av_expr_parse(&s->pos_x_pexpr, s->pos_x_expr, var_names,
552  NULL, NULL, NULL, NULL, 0, s));
553  RET(av_expr_parse(&s->pos_y_pexpr, s->pos_y_expr, var_names,
554  NULL, NULL, NULL, NULL, 0, s));
555  RET(av_expr_parse(&s->pos_w_pexpr, s->pos_w_expr, var_names,
556  NULL, NULL, NULL, NULL, 0, s));
557  RET(av_expr_parse(&s->pos_h_pexpr, s->pos_h_expr, var_names,
558  NULL, NULL, NULL, NULL, 0, s));
559 
560  if (strcmp(s->fps_string, "none") != 0)
561  RET(av_parse_video_rate(&s->fps, s->fps_string));
562 
563  /* Note: s->vulkan etc. are initialized later, when hwctx is available */
564  return 0;
565 
566 fail:
567  return err;
568 }
569 
570 #if PL_API_VER >= 278
571 static void lock_queue(void *priv, uint32_t qf, uint32_t qidx)
572 {
573  AVHWDeviceContext *avhwctx = priv;
574  const AVVulkanDeviceContext *hwctx = avhwctx->hwctx;
575  hwctx->lock_queue(avhwctx, qf, qidx);
576 }
577 
578 static void unlock_queue(void *priv, uint32_t qf, uint32_t qidx)
579 {
580  AVHWDeviceContext *avhwctx = priv;
581  const AVVulkanDeviceContext *hwctx = avhwctx->hwctx;
582  hwctx->unlock_queue(avhwctx, qf, qidx);
583 }
584 #endif
585 
587  LibplaceboInput *input, int idx)
588 {
589  LibplaceboContext *s = avctx->priv;
590 
591  input->out_pts = av_fifo_alloc2(1, sizeof(int64_t), AV_FIFO_FLAG_AUTO_GROW);
592  if (!input->out_pts)
593  return AVERROR(ENOMEM);
594  input->queue = pl_queue_create(s->gpu);
595  input->renderer = pl_renderer_create(s->log, s->gpu);
596  input->link = link;
597  input->idx = idx;
598 
599  return 0;
600 }
601 
603 {
604  pl_renderer_destroy(&input->renderer);
605  pl_queue_destroy(&input->queue);
606  av_fifo_freep2(&input->out_pts);
607 }
608 
609 static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwctx)
610 {
611  int err = 0;
612  LibplaceboContext *s = avctx->priv;
613  uint8_t *buf = NULL;
614  size_t buf_len;
615 
616  if (hwctx) {
617 #if PL_API_VER >= 278
618  /* Import libavfilter vulkan context into libplacebo */
619  s->vulkan = pl_vulkan_import(s->log, pl_vulkan_import_params(
620  .instance = hwctx->inst,
621  .get_proc_addr = hwctx->get_proc_addr,
622  .phys_device = hwctx->phys_dev,
623  .device = hwctx->act_dev,
624  .extensions = hwctx->enabled_dev_extensions,
625  .num_extensions = hwctx->nb_enabled_dev_extensions,
626  .features = &hwctx->device_features,
627  .lock_queue = lock_queue,
628  .unlock_queue = unlock_queue,
629  .queue_ctx = avctx->hw_device_ctx->data,
630  .queue_graphics = {
631  .index = hwctx->queue_family_index,
632  .count = hwctx->nb_graphics_queues,
633  },
634  .queue_compute = {
635  .index = hwctx->queue_family_comp_index,
636  .count = hwctx->nb_comp_queues,
637  },
638  .queue_transfer = {
639  .index = hwctx->queue_family_tx_index,
640  .count = hwctx->nb_tx_queues,
641  },
642  /* This is the highest version created by hwcontext_vulkan.c */
643  .max_api_version = VK_API_VERSION_1_3,
644  ));
645 #else
646  av_log(s, AV_LOG_ERROR, "libplacebo version %s too old to import "
647  "Vulkan device, remove it or upgrade libplacebo to >= 5.278\n",
648  PL_VERSION);
649  err = AVERROR_EXTERNAL;
650  goto fail;
651 #endif
652  } else {
653  s->vulkan = pl_vulkan_create(s->log, pl_vulkan_params(
654  .queue_count = 0, /* enable all queues for parallelization */
655  ));
656  }
657 
658  if (!s->vulkan) {
659  av_log(s, AV_LOG_ERROR, "Failed %s Vulkan device!\n",
660  hwctx ? "importing" : "creating");
661  err = AVERROR_EXTERNAL;
662  goto fail;
663  }
664 
665  s->gpu = s->vulkan->gpu;
666 
667  /* Parse the user shaders, if requested */
668  if (s->shader_bin_len)
669  RET(parse_shader(avctx, s->shader_bin, s->shader_bin_len));
670 
671  if (s->shader_path && s->shader_path[0]) {
672  RET(av_file_map(s->shader_path, &buf, &buf_len, 0, s));
673  RET(parse_shader(avctx, buf, buf_len));
674  }
675 
676  /* Initialize inputs */
677  s->inputs = av_calloc(s->nb_inputs, sizeof(*s->inputs));
678  if (!s->inputs)
679  return AVERROR(ENOMEM);
680  for (int i = 0; i < s->nb_inputs; i++)
681  RET(input_init(avctx, avctx->inputs[i], &s->inputs[i], i));
682 
683  /* fall through */
684 fail:
685  if (buf)
686  av_file_unmap(buf, buf_len);
687  return err;
688 }
689 
691 {
692  LibplaceboContext *s = avctx->priv;
693 
694  for (int i = 0; i < FF_ARRAY_ELEMS(s->tex); i++)
695  pl_tex_destroy(s->gpu, &s->tex[i]);
696  for (int i = 0; i < s->num_hooks; i++)
697  pl_mpv_user_shader_destroy(&s->hooks[i]);
698  if (s->inputs) {
699  for (int i = 0; i < s->nb_inputs; i++)
700  input_uninit(&s->inputs[i]);
701  av_freep(&s->inputs);
702  }
703 
704  pl_options_free(&s->opts);
705  pl_vulkan_destroy(&s->vulkan);
706  pl_log_destroy(&s->log);
707  ff_vk_uninit(&s->vkctx);
708  s->gpu = NULL;
709 
710  av_expr_free(s->crop_x_pexpr);
711  av_expr_free(s->crop_y_pexpr);
712  av_expr_free(s->crop_w_pexpr);
713  av_expr_free(s->crop_h_pexpr);
714  av_expr_free(s->pos_x_pexpr);
715  av_expr_free(s->pos_y_pexpr);
716  av_expr_free(s->pos_w_pexpr);
717  av_expr_free(s->pos_h_pexpr);
718 }
719 
720 static int libplacebo_process_command(AVFilterContext *ctx, const char *cmd,
721  const char *arg, char *res, int res_len,
722  int flags)
723 {
724  int err = 0;
725  RET(ff_filter_process_command(ctx, cmd, arg, res, res_len, flags));
727  return 0;
728 
729 fail:
730  return err;
731 }
732 
733 static const AVFrame *ref_frame(const struct pl_frame_mix *mix)
734 {
735  for (int i = 0; i < mix->num_frames; i++) {
736  if (i+1 == mix->num_frames || mix->timestamps[i+1] > 0)
737  return pl_get_mapped_avframe(mix->frames[i]);
738  }
739  return NULL;
740 }
741 
743  struct pl_frame *target, double target_pts)
744 {
745  LibplaceboContext *s = ctx->priv;
746  const AVFrame *ref = ref_frame(&in->mix);
747 
748  for (int i = 0; i < in->mix.num_frames; i++) {
749  // Mutate the `pl_frame.crop` fields in-place. This is fine because we
750  // own the entire pl_queue, and hence, the pointed-at frames.
751  struct pl_frame *image = (struct pl_frame *) in->mix.frames[i];
752  const AVFrame *src = pl_get_mapped_avframe(image);
753  double image_pts = src->pts * av_q2d(in->link->time_base);
754 
755  /* Update dynamic variables */
756  s->var_values[VAR_IN_IDX] = s->var_values[VAR_IDX] = in->idx;
757  s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = in->link->w;
758  s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = in->link->h;
759  s->var_values[VAR_A] = (double) in->link->w / in->link->h;
760  s->var_values[VAR_SAR] = in->link->sample_aspect_ratio.num ?
761  av_q2d(in->link->sample_aspect_ratio) : 1.0;
762  s->var_values[VAR_IN_T] = s->var_values[VAR_T] = image_pts;
763  s->var_values[VAR_OUT_T] = s->var_values[VAR_OT] = target_pts;
764  s->var_values[VAR_N] = ctx->outputs[0]->frame_count_out;
765 
766  /* Clear these explicitly to avoid leaking previous frames' state */
767  s->var_values[VAR_CROP_W] = s->var_values[VAR_CW] = NAN;
768  s->var_values[VAR_CROP_H] = s->var_values[VAR_CH] = NAN;
769  s->var_values[VAR_POS_W] = s->var_values[VAR_PW] = NAN;
770  s->var_values[VAR_POS_H] = s->var_values[VAR_PH] = NAN;
771 
772  /* Compute dimensions first and placement second */
773  s->var_values[VAR_CROP_W] = s->var_values[VAR_CW] =
774  av_expr_eval(s->crop_w_pexpr, s->var_values, NULL);
775  s->var_values[VAR_CROP_H] = s->var_values[VAR_CH] =
776  av_expr_eval(s->crop_h_pexpr, s->var_values, NULL);
777  s->var_values[VAR_CROP_W] = s->var_values[VAR_CW] =
778  av_expr_eval(s->crop_w_pexpr, s->var_values, NULL);
779  s->var_values[VAR_POS_W] = s->var_values[VAR_PW] =
780  av_expr_eval(s->pos_w_pexpr, s->var_values, NULL);
781  s->var_values[VAR_POS_H] = s->var_values[VAR_PH] =
782  av_expr_eval(s->pos_h_pexpr, s->var_values, NULL);
783  s->var_values[VAR_POS_W] = s->var_values[VAR_PW] =
784  av_expr_eval(s->pos_w_pexpr, s->var_values, NULL);
785 
786  image->crop.x0 = av_expr_eval(s->crop_x_pexpr, s->var_values, NULL);
787  image->crop.y0 = av_expr_eval(s->crop_y_pexpr, s->var_values, NULL);
788  image->crop.x1 = image->crop.x0 + s->var_values[VAR_CROP_W];
789  image->crop.y1 = image->crop.y0 + s->var_values[VAR_CROP_H];
790 
791  if (src == ref) {
792  /* Only update the target crop once, for the 'reference' frame */
793  target->crop.x0 = av_expr_eval(s->pos_x_pexpr, s->var_values, NULL);
794  target->crop.y0 = av_expr_eval(s->pos_y_pexpr, s->var_values, NULL);
795  target->crop.x1 = target->crop.x0 + s->var_values[VAR_POS_W];
796  target->crop.y1 = target->crop.y0 + s->var_values[VAR_POS_H];
797  if (s->normalize_sar) {
798  float aspect = pl_rect2df_aspect(&image->crop);
799  aspect *= av_q2d(in->link->sample_aspect_ratio);
800  pl_rect2df_aspect_set(&target->crop, aspect, s->pad_crop_ratio);
801  }
802  }
803  }
804 }
805 
806 /* Construct and emit an output frame for a given timestamp */
807 static int output_frame(AVFilterContext *ctx, int64_t pts)
808 {
809  int err = 0, ok, changed_csp;
810  LibplaceboContext *s = ctx->priv;
811  pl_options opts = s->opts;
812  AVFilterLink *outlink = ctx->outputs[0];
813  const AVPixFmtDescriptor *outdesc = av_pix_fmt_desc_get(outlink->format);
814  struct pl_frame target;
815  const AVFrame *ref = NULL;
816  AVFrame *out;
817 
818  /* Use the first active input as metadata reference */
819  for (int i = 0; i < s->nb_inputs; i++) {
820  const LibplaceboInput *in = &s->inputs[i];
821  if (in->qstatus == PL_QUEUE_OK && (ref = ref_frame(&in->mix)))
822  break;
823  }
824  if (!ref)
825  return 0;
826 
827  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
828  if (!out)
829  return AVERROR(ENOMEM);
830 
832  out->pts = pts;
833  out->width = outlink->w;
834  out->height = outlink->h;
835  out->colorspace = outlink->colorspace;
836  out->color_range = outlink->color_range;
837  if (s->fps.num)
838  out->duration = 1;
839 
841  /* Output of dovi reshaping is always BT.2020+PQ, so infer the correct
842  * output colorspace defaults */
843  out->color_primaries = AVCOL_PRI_BT2020;
844  out->color_trc = AVCOL_TRC_SMPTE2084;
845  }
846 
847  if (s->color_trc >= 0)
848  out->color_trc = s->color_trc;
849  if (s->color_primaries >= 0)
850  out->color_primaries = s->color_primaries;
851 
852  changed_csp = ref->colorspace != out->colorspace ||
853  ref->color_range != out->color_range ||
854  ref->color_trc != out->color_trc ||
855  ref->color_primaries != out->color_primaries;
856 
857  /* Strip side data if no longer relevant */
858  if (changed_csp) {
862  }
863  if (s->apply_dovi || changed_csp) {
866  }
867  if (s->apply_filmgrain)
869 
870  /* Map, render and unmap output frame */
871  if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
872  ok = pl_map_avframe_ex(s->gpu, &target, pl_avframe_params(
873  .frame = out,
874  .map_dovi = false,
875  ));
876  } else {
877  ok = pl_frame_recreate_from_avframe(s->gpu, &target, s->tex, out);
878  }
879  if (!ok) {
880  err = AVERROR_EXTERNAL;
881  goto fail;
882  }
883 
884  /* Draw first frame opaque, others with blending */
885  opts->params.skip_target_clearing = false;
886  opts->params.blend_params = NULL;
887  for (int i = 0; i < s->nb_inputs; i++) {
888  LibplaceboInput *in = &s->inputs[i];
889  int high_fps = av_cmp_q(in->link->frame_rate, outlink->frame_rate) >= 0;
890  if (in->qstatus != PL_QUEUE_OK)
891  continue;
892  opts->params.skip_caching_single_frame = high_fps;
893  update_crops(ctx, in, &target, out->pts * av_q2d(outlink->time_base));
894  pl_render_image_mix(in->renderer, &in->mix, &target, &opts->params);
895  opts->params.skip_target_clearing = true;
896  opts->params.blend_params = &pl_alpha_overlay;
897  }
898 
899  if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
900  pl_unmap_avframe(s->gpu, &target);
901  } else if (!pl_download_avframe(s->gpu, &target, out)) {
902  err = AVERROR_EXTERNAL;
903  goto fail;
904  }
905  return ff_filter_frame(outlink, out);
906 
907 fail:
908  av_frame_free(&out);
909  return err;
910 }
911 
912 static bool map_frame(pl_gpu gpu, pl_tex *tex,
913  const struct pl_source_frame *src,
914  struct pl_frame *out)
915 {
916  AVFrame *avframe = src->frame_data;
917  LibplaceboContext *s = avframe->opaque;
918  bool ok = pl_map_avframe_ex(gpu, out, pl_avframe_params(
919  .frame = avframe,
920  .tex = tex,
921  .map_dovi = s->apply_dovi,
922  ));
923 
924  if (!s->apply_filmgrain)
925  out->film_grain.type = PL_FILM_GRAIN_NONE;
926 
927  av_frame_free(&avframe);
928  return ok;
929 }
930 
931 static void unmap_frame(pl_gpu gpu, struct pl_frame *frame,
932  const struct pl_source_frame *src)
933 {
934  pl_unmap_avframe(gpu, frame);
935 }
936 
937 static void discard_frame(const struct pl_source_frame *src)
938 {
939  AVFrame *avframe = src->frame_data;
940  av_frame_free(&avframe);
941 }
942 
944 {
945  int ret, status;
946  LibplaceboContext *s = ctx->priv;
947  AVFilterLink *outlink = ctx->outputs[0];
948  AVFrame *in;
949  int64_t pts;
950 
951  while ((ret = ff_inlink_consume_frame(input->link, &in)) > 0) {
952  in->opaque = s;
953  pl_queue_push(input->queue, &(struct pl_source_frame) {
954  .pts = in->pts * av_q2d(input->link->time_base),
955  .duration = in->duration * av_q2d(input->link->time_base),
956  .first_field = pl_field_from_avframe(in),
957  .frame_data = in,
958  .map = map_frame,
959  .unmap = unmap_frame,
960  .discard = discard_frame,
961  });
962 
963  if (!s->fps.num) {
964  /* Internally queue an output frame for the same PTS */
965  pts = av_rescale_q(in->pts, input->link->time_base, outlink->time_base);
966  av_fifo_write(input->out_pts, &pts, 1);
967  }
968  }
969 
970  if (ret < 0)
971  return ret;
972 
973  if (!input->status && ff_inlink_acknowledge_status(input->link, &status, &pts)) {
974  pts = av_rescale_q_rnd(pts, input->link->time_base, outlink->time_base,
975  AV_ROUND_UP);
976  pl_queue_push(input->queue, NULL); /* Signal EOF to pl_queue */
977  input->status = status;
978  input->status_pts = pts;
979  if (!s->status || pts >= s->status_pts) {
980  /* Also propagate to output unless overwritten by later status change */
981  s->status = status;
982  s->status_pts = pts;
983  }
984  }
985 
986  return 0;
987 }
988 
989 static void drain_input_pts(LibplaceboInput *in, int64_t until)
990 {
991  int64_t pts;
992  while (av_fifo_peek(in->out_pts, &pts, 1, 0) >= 0 && pts <= until)
993  av_fifo_drain2(in->out_pts, 1);
994 }
995 
997 {
998  int ret, ok = 0, retry = 0;
999  LibplaceboContext *s = ctx->priv;
1000  AVFilterLink *outlink = ctx->outputs[0];
1001  int64_t pts, out_pts;
1002 
1004  pl_log_level_update(s->log, get_log_level());
1005 
1006  for (int i = 0; i < s->nb_inputs; i++) {
1007  if ((ret = handle_input(ctx, &s->inputs[i])) < 0)
1008  return ret;
1009  }
1010 
1011  if (ff_outlink_frame_wanted(outlink)) {
1012  if (s->fps.num) {
1013  out_pts = outlink->frame_count_out;
1014  } else {
1015  /* Determine the PTS of the next frame from any active input */
1016  out_pts = INT64_MAX;
1017  for (int i = 0; i < s->nb_inputs; i++) {
1018  LibplaceboInput *in = &s->inputs[i];
1019  if (av_fifo_peek(in->out_pts, &pts, 1, 0) >= 0) {
1020  out_pts = FFMIN(out_pts, pts);
1021  } else if (!in->status) {
1023  retry = true;
1024  }
1025  }
1026 
1027  if (retry) /* some inputs are incomplete */
1028  return 0;
1029  }
1030 
1031  /* Update all input queues to the chosen out_pts */
1032  for (int i = 0; i < s->nb_inputs; i++) {
1033  LibplaceboInput *in = &s->inputs[i];
1034  if (in->status && out_pts >= in->status_pts) {
1035  in->qstatus = PL_QUEUE_EOF;
1036  continue;
1037  }
1038 
1039  in->qstatus = pl_queue_update(in->queue, &in->mix, pl_queue_params(
1040  .pts = out_pts * av_q2d(outlink->time_base),
1041  .radius = pl_frame_mix_radius(&s->opts->params),
1042  .vsync_duration = av_q2d(av_inv_q(outlink->frame_rate)),
1043  ));
1044 
1045  switch (in->qstatus) {
1046  case PL_QUEUE_MORE:
1048  retry = true;
1049  break;
1050  case PL_QUEUE_OK:
1051  ok = true;
1052  break;
1053  case PL_QUEUE_ERR:
1054  return AVERROR_EXTERNAL;
1055  }
1056  }
1057 
1058  if (retry) {
1059  return 0;
1060  } else if (ok) {
1061  /* Got any valid frame mixes, drain PTS queue and render output */
1062  for (int i = 0; i < s->nb_inputs; i++)
1063  drain_input_pts(&s->inputs[i], out_pts);
1064  return output_frame(ctx, out_pts);
1065  } else if (s->status) {
1066  ff_outlink_set_status(outlink, s->status, s->status_pts);
1067  return 0;
1068  }
1069 
1070  return AVERROR_BUG;
1071  }
1072 
1073  return FFERROR_NOT_READY;
1074 }
1075 
1077 {
1078  int err;
1079  LibplaceboContext *s = ctx->priv;
1080  const AVVulkanDeviceContext *vkhwctx = NULL;
1081  const AVPixFmtDescriptor *desc = NULL;
1082  AVFilterFormats *infmts = NULL, *outfmts = NULL;
1083 
1084  if (ctx->hw_device_ctx) {
1085  const AVHWDeviceContext *avhwctx = (void *) ctx->hw_device_ctx->data;
1086  if (avhwctx->type == AV_HWDEVICE_TYPE_VULKAN)
1087  vkhwctx = avhwctx->hwctx;
1088  }
1089 
1090  RET(init_vulkan(ctx, vkhwctx));
1091 
1092  while ((desc = av_pix_fmt_desc_next(desc))) {
1094 
1095 #if PL_API_VER < 232
1096  // Older libplacebo can't handle >64-bit pixel formats, so safe-guard
1097  // this to prevent triggering an assertion
1098  if (av_get_bits_per_pixel(desc) > 64)
1099  continue;
1100 #endif
1101 
1102  if (pixfmt == AV_PIX_FMT_VULKAN) {
1103  if (!vkhwctx || vkhwctx->act_dev != s->vulkan->device)
1104  continue;
1105  }
1106 
1107  if (!pl_test_pixfmt(s->gpu, pixfmt))
1108  continue;
1109 
1110  RET(ff_add_format(&infmts, pixfmt));
1111 
1112  /* Filter for supported output pixel formats */
1113  if (desc->flags & AV_PIX_FMT_FLAG_BE)
1114  continue; /* BE formats are not supported by pl_download_avframe */
1115 
1116  /* Mask based on user specified format */
1117  if (s->out_format != AV_PIX_FMT_NONE) {
1118  if (pixfmt == AV_PIX_FMT_VULKAN && av_vkfmt_from_pixfmt(s->out_format)) {
1119  /* OK */
1120  } else if (pixfmt == s->out_format) {
1121  /* OK */
1122  } else {
1123  continue; /* Not OK */
1124  }
1125  }
1126 
1127 #if PL_API_VER >= 293
1128  if (!pl_test_pixfmt_caps(s->gpu, pixfmt, PL_FMT_CAP_RENDERABLE))
1129  continue;
1130 #endif
1131 
1132  RET(ff_add_format(&outfmts, pixfmt));
1133  }
1134 
1135  if (!infmts || !outfmts) {
1136  if (s->out_format) {
1137  av_log(s, AV_LOG_ERROR, "Invalid output format '%s'!\n",
1138  av_get_pix_fmt_name(s->out_format));
1139  }
1140  err = AVERROR(EINVAL);
1141  goto fail;
1142  }
1143 
1144  for (int i = 0; i < s->nb_inputs; i++)
1145  RET(ff_formats_ref(infmts, &ctx->inputs[i]->outcfg.formats));
1146  RET(ff_formats_ref(outfmts, &ctx->outputs[0]->incfg.formats));
1147 
1148  /* Set colorspace properties */
1149  RET(ff_formats_ref(ff_all_color_spaces(), &ctx->inputs[0]->outcfg.color_spaces));
1150  RET(ff_formats_ref(ff_all_color_ranges(), &ctx->inputs[0]->outcfg.color_ranges));
1151 
1152  outfmts = s->colorspace > 0 ? ff_make_formats_list_singleton(s->colorspace)
1153  : ff_all_color_spaces();
1154  RET(ff_formats_ref(outfmts, &ctx->outputs[0]->incfg.color_spaces));
1155 
1156  outfmts = s->color_range > 0 ? ff_make_formats_list_singleton(s->color_range)
1157  : ff_all_color_ranges();
1158  RET(ff_formats_ref(outfmts, &ctx->outputs[0]->incfg.color_ranges));
1159  return 0;
1160 
1161 fail:
1162  if (infmts && !infmts->refcount)
1163  ff_formats_unref(&infmts);
1164  if (outfmts && !outfmts->refcount)
1165  ff_formats_unref(&outfmts);
1166  return err;
1167 }
1168 
1170 {
1171  AVFilterContext *avctx = inlink->dst;
1172  LibplaceboContext *s = avctx->priv;
1173 
1174  if (inlink->format == AV_PIX_FMT_VULKAN)
1176 
1177  /* Forward this to the vkctx for format selection */
1178  s->vkctx.input_format = inlink->format;
1179 
1180  return 0;
1181 }
1182 
1184 {
1185  return av_cmp_q(a, b) < 0 ? b : a;
1186 }
1187 
1189 {
1190  int err;
1191  AVFilterContext *avctx = outlink->src;
1192  LibplaceboContext *s = avctx->priv;
1193  AVFilterLink *inlink = outlink->src->inputs[0];
1195  const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format);
1196  AVHWFramesContext *hwfc;
1197  AVVulkanFramesContext *vkfc;
1198 
1199  /* Frame dimensions */
1200  RET(ff_scale_eval_dimensions(s, s->w_expr, s->h_expr, inlink, outlink,
1201  &outlink->w, &outlink->h));
1202 
1203  ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h,
1204  s->force_original_aspect_ratio,
1205  s->force_divisible_by);
1206 
1207  if (s->normalize_sar || s->nb_inputs > 1) {
1208  /* SAR is normalized, or we have multiple inputs, set out to 1:1 */
1209  outlink->sample_aspect_ratio = (AVRational){ 1, 1 };
1210  } else {
1211  /* This is consistent with other scale_* filters, which only
1212  * set the outlink SAR to be equal to the scale SAR iff the input SAR
1213  * was set to something nonzero */
1214  if (inlink->sample_aspect_ratio.num)
1215  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
1216  }
1217 
1218  /* Frame rate */
1219  if (s->fps.num) {
1220  outlink->frame_rate = s->fps;
1221  outlink->time_base = av_inv_q(s->fps);
1222  } else {
1223  outlink->frame_rate = avctx->inputs[0]->frame_rate;
1224  outlink->time_base = avctx->inputs[0]->time_base;
1225  for (int i = 1; i < s->nb_inputs; i++) {
1226  outlink->frame_rate = max_q(outlink->frame_rate,
1227  avctx->inputs[i]->frame_rate);
1228  outlink->time_base = av_gcd_q(outlink->time_base,
1229  avctx->inputs[i]->time_base,
1231  }
1232  }
1233 
1234  /* Static variables */
1235  s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = outlink->w;
1236  s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = outlink->h;
1237  s->var_values[VAR_DAR] = outlink->sample_aspect_ratio.num ?
1238  av_q2d(outlink->sample_aspect_ratio) : 1.0;
1239  s->var_values[VAR_HSUB] = 1 << desc->log2_chroma_w;
1240  s->var_values[VAR_VSUB] = 1 << desc->log2_chroma_h;
1241  s->var_values[VAR_OHSUB] = 1 << out_desc->log2_chroma_w;
1242  s->var_values[VAR_OVSUB] = 1 << out_desc->log2_chroma_h;
1243 
1244  if (outlink->format != AV_PIX_FMT_VULKAN)
1245  return 0;
1246 
1247  s->vkctx.output_width = outlink->w;
1248  s->vkctx.output_height = outlink->h;
1249  /* Default to re-using the input format */
1250  if (s->out_format == AV_PIX_FMT_NONE || s->out_format == AV_PIX_FMT_VULKAN) {
1251  s->vkctx.output_format = s->vkctx.input_format;
1252  } else {
1253  s->vkctx.output_format = s->out_format;
1254  }
1255  RET(ff_vk_filter_config_output(outlink));
1256  hwfc = (AVHWFramesContext *) outlink->hw_frames_ctx->data;
1257  vkfc = hwfc->hwctx;
1258  vkfc->usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1259 
1260  return 0;
1261 
1262 fail:
1263  return err;
1264 }
1265 
1266 #define OFFSET(x) offsetof(LibplaceboContext, x)
1267 #define STATIC (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
1268 #define DYNAMIC (STATIC | AV_OPT_FLAG_RUNTIME_PARAM)
1269 
1270 static const AVOption libplacebo_options[] = {
1271  { "inputs", "Number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags = STATIC },
1272  { "w", "Output video frame width", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = STATIC },
1273  { "h", "Output video frame height", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = STATIC },
1274  { "fps", "Output video frame rate", OFFSET(fps_string), AV_OPT_TYPE_STRING, {.str = "none"}, .flags = STATIC },
1275  { "crop_x", "Input video crop x", OFFSET(crop_x_expr), AV_OPT_TYPE_STRING, {.str = "(iw-cw)/2"}, .flags = DYNAMIC },
1276  { "crop_y", "Input video crop y", OFFSET(crop_y_expr), AV_OPT_TYPE_STRING, {.str = "(ih-ch)/2"}, .flags = DYNAMIC },
1277  { "crop_w", "Input video crop w", OFFSET(crop_w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = DYNAMIC },
1278  { "crop_h", "Input video crop h", OFFSET(crop_h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = DYNAMIC },
1279  { "pos_x", "Output video placement x", OFFSET(pos_x_expr), AV_OPT_TYPE_STRING, {.str = "(ow-pw)/2"}, .flags = DYNAMIC },
1280  { "pos_y", "Output video placement y", OFFSET(pos_y_expr), AV_OPT_TYPE_STRING, {.str = "(oh-ph)/2"}, .flags = DYNAMIC },
1281  { "pos_w", "Output video placement w", OFFSET(pos_w_expr), AV_OPT_TYPE_STRING, {.str = "ow"}, .flags = DYNAMIC },
1282  { "pos_h", "Output video placement h", OFFSET(pos_h_expr), AV_OPT_TYPE_STRING, {.str = "oh"}, .flags = DYNAMIC },
1283  { "format", "Output video format", OFFSET(out_format_string), AV_OPT_TYPE_STRING, .flags = STATIC },
1284  { "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" },
1285  { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, STATIC, .unit = "force_oar" },
1286  { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, STATIC, .unit = "force_oar" },
1287  { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, STATIC, .unit = "force_oar" },
1288  { "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 },
1289  { "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 },
1290  { "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 },
1291  { "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_STRING, {.str = "black"}, .flags = DYNAMIC },
1292  { "corner_rounding", "Corner rounding radius", OFFSET(corner_rounding), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, .flags = DYNAMIC },
1293  { "extra_opts", "Pass extra libplacebo-specific options using a :-separated list of key=value pairs", OFFSET(extra_opts), AV_OPT_TYPE_DICT, .flags = DYNAMIC },
1294 
1295  {"colorspace", "select colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_SPC_NB-1, DYNAMIC, .unit = "colorspace"},
1296  {"auto", "keep the same colorspace", 0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1297  {"gbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_RGB}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1298  {"bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT709}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1299  {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_UNSPECIFIED}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1300  {"bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT470BG}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1301  {"smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_SMPTE170M}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1302  {"smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_SMPTE240M}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1303  {"ycgco", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_YCGCO}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1304  {"bt2020nc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT2020_NCL}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1305  {"bt2020c", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT2020_CL}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1306  {"ictcp", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_ICTCP}, INT_MIN, INT_MAX, STATIC, .unit = "colorspace"},
1307 
1308  {"range", "select color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_RANGE_NB-1, DYNAMIC, .unit = "range"},
1309  {"auto", "keep the same color range", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, STATIC, .unit = "range"},
1310  {"unspecified", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED}, 0, 0, STATIC, .unit = "range"},
1311  {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED}, 0, 0, STATIC, .unit = "range"},
1312  {"limited", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, STATIC, .unit = "range"},
1313  {"tv", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, STATIC, .unit = "range"},
1314  {"mpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, STATIC, .unit = "range"},
1315  {"full", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, STATIC, .unit = "range"},
1316  {"pc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, STATIC, .unit = "range"},
1317  {"jpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, STATIC, .unit = "range"},
1318 
1319  {"color_primaries", "select color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_PRI_NB-1, DYNAMIC, .unit = "color_primaries"},
1320  {"auto", "keep the same color primaries", 0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1321  {"bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT709}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1322  {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_UNSPECIFIED}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1323  {"bt470m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT470M}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1324  {"bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT470BG}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1325  {"smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE170M}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1326  {"smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE240M}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1327  {"film", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_FILM}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1328  {"bt2020", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT2020}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1329  {"smpte428", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE428}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1330  {"smpte431", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE431}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1331  {"smpte432", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE432}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1332  {"jedec-p22", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_JEDEC_P22}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1333  {"ebu3213", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_EBU3213}, INT_MIN, INT_MAX, STATIC, .unit = "color_primaries"},
1334 
1335  {"color_trc", "select color transfer", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_TRC_NB-1, DYNAMIC, .unit = "color_trc"},
1336  {"auto", "keep the same color transfer", 0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1337  {"bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT709}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1338  {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_UNSPECIFIED}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1339  {"bt470m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_GAMMA22}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1340  {"bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_GAMMA28}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1341  {"smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE170M}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1342  {"smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE240M}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1343  {"linear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_LINEAR}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1344  {"iec61966-2-4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_IEC61966_2_4}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1345  {"bt1361e", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT1361_ECG}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1346  {"iec61966-2-1", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_IEC61966_2_1}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1347  {"bt2020-10", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT2020_10}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1348  {"bt2020-12", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT2020_12}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1349  {"smpte2084", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE2084}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1350  {"arib-std-b67", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_ARIB_STD_B67}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
1351 
1352  { "upscaler", "Upscaler function", OFFSET(upscaler), AV_OPT_TYPE_STRING, {.str = "spline36"}, .flags = DYNAMIC },
1353  { "downscaler", "Downscaler function", OFFSET(downscaler), AV_OPT_TYPE_STRING, {.str = "mitchell"}, .flags = DYNAMIC },
1354  { "frame_mixer", "Frame mixing function", OFFSET(frame_mixer), AV_OPT_TYPE_STRING, {.str = "none"}, .flags = DYNAMIC },
1355  { "lut_entries", "Number of scaler LUT entries", OFFSET(lut_entries), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 256, DYNAMIC },
1356  { "antiringing", "Antiringing strength (for non-EWA filters)", OFFSET(antiringing), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, DYNAMIC },
1357  { "sigmoid", "Enable sigmoid upscaling", OFFSET(sigmoid), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
1358  { "apply_filmgrain", "Apply film grain metadata", OFFSET(apply_filmgrain), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
1359  { "apply_dolbyvision", "Apply Dolby Vision metadata", OFFSET(apply_dovi), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
1360 
1361  { "deband", "Enable debanding", OFFSET(deband), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1362  { "deband_iterations", "Deband iterations", OFFSET(deband_iterations), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 16, DYNAMIC },
1363  { "deband_threshold", "Deband threshold", OFFSET(deband_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 4.0}, 0.0, 1024.0, DYNAMIC },
1364  { "deband_radius", "Deband radius", OFFSET(deband_radius), AV_OPT_TYPE_FLOAT, {.dbl = 16.0}, 0.0, 1024.0, DYNAMIC },
1365  { "deband_grain", "Deband grain", OFFSET(deband_grain), AV_OPT_TYPE_FLOAT, {.dbl = 6.0}, 0.0, 1024.0, DYNAMIC },
1366 
1367  { "brightness", "Brightness boost", OFFSET(brightness), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, -1.0, 1.0, DYNAMIC },
1368  { "contrast", "Contrast gain", OFFSET(contrast), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 16.0, DYNAMIC },
1369  { "saturation", "Saturation gain", OFFSET(saturation), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 16.0, DYNAMIC },
1370  { "hue", "Hue shift", OFFSET(hue), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, -M_PI, M_PI, DYNAMIC },
1371  { "gamma", "Gamma adjustment", OFFSET(gamma), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 16.0, DYNAMIC },
1372 
1373  { "peak_detect", "Enable dynamic peak detection for HDR tone-mapping", OFFSET(peakdetect), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
1374  { "smoothing_period", "Peak detection smoothing period", OFFSET(smoothing), AV_OPT_TYPE_FLOAT, {.dbl = 100.0}, 0.0, 1000.0, DYNAMIC },
1375  { "minimum_peak", "Peak detection minimum peak", OFFSET(min_peak), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 100.0, DYNAMIC },
1376  { "scene_threshold_low", "Scene change low threshold", OFFSET(scene_low), AV_OPT_TYPE_FLOAT, {.dbl = 5.5}, -1.0, 100.0, DYNAMIC },
1377  { "scene_threshold_high", "Scene change high threshold", OFFSET(scene_high), AV_OPT_TYPE_FLOAT, {.dbl = 10.0}, -1.0, 100.0, DYNAMIC },
1378  { "percentile", "Peak detection percentile", OFFSET(percentile), AV_OPT_TYPE_FLOAT, {.dbl = 99.995}, 0.0, 100.0, DYNAMIC },
1379 
1380  { "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" },
1381  { "clip", "Hard-clip (RGB per-channel)", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_CLIP}, 0, 0, STATIC, .unit = "gamut_mode" },
1382  { "perceptual", "Colorimetric soft clipping", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_PERCEPTUAL}, 0, 0, STATIC, .unit = "gamut_mode" },
1383  { "relative", "Relative colorimetric clipping", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_RELATIVE}, 0, 0, STATIC, .unit = "gamut_mode" },
1384  { "saturation", "Saturation mapping (RGB -> RGB)", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_SATURATION}, 0, 0, STATIC, .unit = "gamut_mode" },
1385  { "absolute", "Absolute colorimetric clipping", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_ABSOLUTE}, 0, 0, STATIC, .unit = "gamut_mode" },
1386  { "desaturate", "Colorimetrically desaturate colors towards white", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_DESATURATE}, 0, 0, STATIC, .unit = "gamut_mode" },
1387  { "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" },
1388  { "warn", "Highlight out-of-gamut colors", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_HIGHLIGHT}, 0, 0, STATIC, .unit = "gamut_mode" },
1389  { "linear", "Linearly reduce chromaticity to fit gamut", 0, AV_OPT_TYPE_CONST, {.i64 = GAMUT_MAP_LINEAR}, 0, 0, STATIC, .unit = "gamut_mode" },
1390  { "tonemapping", "Tone-mapping algorithm", OFFSET(tonemapping), AV_OPT_TYPE_INT, {.i64 = TONE_MAP_AUTO}, 0, TONE_MAP_COUNT - 1, DYNAMIC, .unit = "tonemap" },
1391  { "auto", "Automatic selection", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_AUTO}, 0, 0, STATIC, .unit = "tonemap" },
1392  { "clip", "No tone mapping (clip", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_CLIP}, 0, 0, STATIC, .unit = "tonemap" },
1393 #if PL_API_VER >= 246
1394  { "st2094-40", "SMPTE ST 2094-40", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_ST2094_40}, 0, 0, STATIC, .unit = "tonemap" },
1395  { "st2094-10", "SMPTE ST 2094-10", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_ST2094_10}, 0, 0, STATIC, .unit = "tonemap" },
1396 #endif
1397  { "bt.2390", "ITU-R BT.2390 EETF", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_BT2390}, 0, 0, STATIC, .unit = "tonemap" },
1398  { "bt.2446a", "ITU-R BT.2446 Method A", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_BT2446A}, 0, 0, STATIC, .unit = "tonemap" },
1399  { "spline", "Single-pivot polynomial spline", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_SPLINE}, 0, 0, STATIC, .unit = "tonemap" },
1400  { "reinhard", "Reinhard", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_REINHARD}, 0, 0, STATIC, .unit = "tonemap" },
1401  { "mobius", "Mobius", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_MOBIUS}, 0, 0, STATIC, .unit = "tonemap" },
1402  { "hable", "Filmic tone-mapping (Hable)", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_HABLE}, 0, 0, STATIC, .unit = "tonemap" },
1403  { "gamma", "Gamma function with knee", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_GAMMA}, 0, 0, STATIC, .unit = "tonemap" },
1404  { "linear", "Perceptually linear stretch", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_LINEAR}, 0, 0, STATIC, .unit = "tonemap" },
1405  { "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 },
1406  { "inverse_tonemapping", "Inverse tone mapping (range expansion)", OFFSET(inverse_tonemapping), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1407  { "tonemapping_lut_size", "Tone-mapping LUT size", OFFSET(tonemapping_lut_size), AV_OPT_TYPE_INT, {.i64 = 256}, 2, 1024, DYNAMIC },
1408  { "contrast_recovery", "HDR contrast recovery strength", OFFSET(contrast_recovery), AV_OPT_TYPE_FLOAT, {.dbl = 0.30}, 0.0, 3.0, DYNAMIC },
1409  { "contrast_smoothness", "HDR contrast recovery smoothness", OFFSET(contrast_smoothness), AV_OPT_TYPE_FLOAT, {.dbl = 3.50}, 1.0, 32.0, DYNAMIC },
1410 
1411  { "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" },
1412  { "none", "Disable dithering", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, STATIC, .unit = "dither" },
1413  { "blue", "Blue noise", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_BLUE_NOISE}, 0, 0, STATIC, .unit = "dither" },
1414  { "ordered", "Ordered LUT", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_ORDERED_LUT}, 0, 0, STATIC, .unit = "dither" },
1415  { "ordered_fixed", "Fixed function ordered", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_ORDERED_FIXED}, 0, 0, STATIC, .unit = "dither" },
1416  { "white", "White noise", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_WHITE_NOISE}, 0, 0, STATIC, .unit = "dither" },
1417  { "dither_lut_size", "Dithering LUT size", OFFSET(dither_lut_size), AV_OPT_TYPE_INT, {.i64 = 6}, 1, 8, STATIC },
1418  { "dither_temporal", "Enable temporal dithering", OFFSET(dither_temporal), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1419 
1420  { "cones", "Colorblindness adaptation model", OFFSET(cones), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, PL_CONE_LMS, DYNAMIC, .unit = "cone" },
1421  { "l", "L cone", 0, AV_OPT_TYPE_CONST, {.i64 = PL_CONE_L}, 0, 0, STATIC, .unit = "cone" },
1422  { "m", "M cone", 0, AV_OPT_TYPE_CONST, {.i64 = PL_CONE_M}, 0, 0, STATIC, .unit = "cone" },
1423  { "s", "S cone", 0, AV_OPT_TYPE_CONST, {.i64 = PL_CONE_S}, 0, 0, STATIC, .unit = "cone" },
1424  { "cone-strength", "Colorblindness adaptation strength", OFFSET(cone_str), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 10.0, DYNAMIC },
1425 
1426  { "custom_shader_path", "Path to custom user shader (mpv .hook format)", OFFSET(shader_path), AV_OPT_TYPE_STRING, .flags = STATIC },
1427  { "custom_shader_bin", "Custom user shader as binary (mpv .hook format)", OFFSET(shader_bin), AV_OPT_TYPE_BINARY, .flags = STATIC },
1428 
1429  /* Performance/quality tradeoff options */
1430  { "skip_aa", "Skip anti-aliasing", OFFSET(skip_aa), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1431  { "polar_cutoff", "Polar LUT cutoff", OFFSET(polar_cutoff), AV_OPT_TYPE_FLOAT, {.dbl = 0}, 0.0, 1.0, DYNAMIC },
1432  { "disable_linear", "Disable linear scaling", OFFSET(disable_linear), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1433  { "disable_builtin", "Disable built-in scalers", OFFSET(disable_builtin), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1434  { "force_dither", "Force dithering", OFFSET(force_dither), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1435  { "disable_fbos", "Force-disable FBOs", OFFSET(disable_fbos), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1436  { NULL },
1437 };
1438 
1439 AVFILTER_DEFINE_CLASS(libplacebo);
1440 
1442  {
1443  .name = "default",
1444  .type = AVMEDIA_TYPE_VIDEO,
1445  .config_props = &libplacebo_config_output,
1446  },
1447 };
1448 
1450  .name = "libplacebo",
1451  .description = NULL_IF_CONFIG_SMALL("Apply various GPU filters from libplacebo"),
1452  .priv_size = sizeof(LibplaceboContext),
1453  .init = &libplacebo_init,
1459  .priv_class = &libplacebo_class,
1460  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
1462 };
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:112
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:85
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
TONE_MAP_ST2094_40
@ TONE_MAP_ST2094_40
Definition: vf_libplacebo.c:68
VAR_IH
@ VAR_IH
Definition: vf_libplacebo.c:120
LibplaceboContext::out_format
enum AVPixelFormat out_format
Definition: vf_libplacebo.c:171
AVVulkanDeviceContext::phys_dev
VkPhysicalDevice phys_dev
Physical device.
Definition: hwcontext_vulkan.h:66
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
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
GAMUT_MAP_PERCEPTUAL
@ GAMUT_MAP_PERCEPTUAL
Definition: vf_libplacebo.c:83
level
uint8_t level
Definition: svq3.c:205
AVCOL_PRI_EBU3213
@ AVCOL_PRI_EBU3213
EBU Tech. 3213-E (nothing there) / one of JEDEC P22 group phosphors.
Definition: pixfmt.h:571
mix
static int mix(int c0, int c1)
Definition: 4xm.c:716
LibplaceboContext::fps_string
char * fps_string
Definition: vf_libplacebo.c:176
libplacebo_query_format
static int libplacebo_query_format(AVFilterContext *ctx)
Definition: vf_libplacebo.c:1076
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:233
LibplaceboContext::deband
int deband
Definition: vf_libplacebo.c:214
var_name
var_name
Definition: noise.c:47
LibplaceboContext::deband_iterations
int deband_iterations
Definition: vf_libplacebo.c:215
input_init
static int input_init(AVFilterContext *avctx, AVFilterLink *link, LibplaceboInput *input, int idx)
Definition: vf_libplacebo.c:586
LibplaceboContext::deband_threshold
float deband_threshold
Definition: vf_libplacebo.c:216
LibplaceboContext::gamut_mode
int gamut_mode
Definition: vf_libplacebo.c:236
out
FILE * out
Definition: movenc.c:55
VAR_IN_H
@ VAR_IN_H
Definition: vf_libplacebo.c:120
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:947
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: internal.h:351
TONE_MAP_LINEAR
@ TONE_MAP_LINEAR
Definition: vf_libplacebo.c:77
LibplaceboContext::contrast
float contrast
Definition: vf_libplacebo.c:222
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1015
GAMUT_MAP_RELATIVE
@ GAMUT_MAP_RELATIVE
Definition: vf_libplacebo.c:84
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2965
VAR_OUT_T
@ VAR_OUT_T
Definition: vf_libplacebo.c:135
av_parse_color
int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, void *log_ctx)
Put the RGBA values that correspond to color_string in rgba_color.
Definition: parseutils.c:356
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
AVCOL_TRC_LINEAR
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition: pixfmt.h:589
av_dict_count
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition: dict.c:39
pl_options_t::sigmoid_params
struct pl_sigmoid_params sigmoid_params
Definition: vf_libplacebo.c:53
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:264
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
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:132
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:338
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
VAR_IN_IDX
@ VAR_IN_IDX
Definition: vf_libplacebo.c:118
AVFrame::opaque
void * opaque
Frame owner's private data.
Definition: frame.h:522
update_settings
static int update_settings(AVFilterContext *ctx)
Definition: vf_libplacebo.c:363
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:374
AVCOL_TRC_NB
@ AVCOL_TRC_NB
Not part of ABI.
Definition: pixfmt.h:602
pl_options_t::deband_params
struct pl_deband_params deband_params
Definition: vf_libplacebo.c:52
AVVulkanDeviceContext::get_proc_addr
PFN_vkGetInstanceProcAddr get_proc_addr
Pointer to the instance-provided vkGetInstanceProcAddr loading function.
Definition: hwcontext_vulkan.h:56
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:486
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:686
pl_av_log
static void pl_av_log(void *log_ctx, enum pl_log_level level, const char *msg)
Definition: vf_libplacebo.c:273
AVOption
AVOption.
Definition: opt.h:346
AVCOL_SPC_NB
@ AVCOL_SPC_NB
Not part of ABI.
Definition: pixfmt.h:629
b
#define b
Definition: input.c:41
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:583
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:159
LibplaceboContext
Definition: vf_libplacebo.c:153
LibplaceboInput::status
int status
Definition: vf_libplacebo.c:150
GAMUT_MAP_LINEAR
@ GAMUT_MAP_LINEAR
Definition: vf_libplacebo.c:90
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:2972
AV_FRAME_DATA_DOVI_RPU_BUFFER
@ AV_FRAME_DATA_DOVI_RPU_BUFFER
Dolby Vision RPU raw data, suitable for passing to x265 or other libraries.
Definition: frame.h:201
AVVulkanDeviceContext::inst
VkInstance inst
Vulkan instance.
Definition: hwcontext_vulkan.h:61
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:572
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
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:610
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
TONE_MAP_COUNT
@ TONE_MAP_COUNT
Definition: vf_libplacebo.c:78
AVCOL_TRC_BT2020_12
@ AVCOL_TRC_BT2020_12
ITU-R BT2020 for 12-bit system.
Definition: pixfmt.h:596
handle_input
static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
Definition: vf_libplacebo.c:943
GAMUT_MAP_DESATURATE
@ GAMUT_MAP_DESATURATE
Definition: vf_libplacebo.c:87
GAMUT_MAP_HIGHLIGHT
@ GAMUT_MAP_HIGHLIGHT
Definition: vf_libplacebo.c:89
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:469
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:2917
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:1873
LibplaceboContext::sigmoid
int sigmoid
Definition: vf_libplacebo.c:205
LibplaceboContext::crop_h_expr
char * crop_h_expr
Definition: vf_libplacebo.c:179
AVDictionary
Definition: dict.c:34
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:912
VAR_OT
@ VAR_OT
Definition: vf_libplacebo.c:135
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
LibplaceboContext::fillcolor
char * fillcolor
Definition: vf_libplacebo.c:172
pl_options_t::color_adjustment
struct pl_color_adjustment color_adjustment
Definition: vf_libplacebo.c:54
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:621
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:530
VAR_CROP_H
@ VAR_CROP_H
Definition: vf_libplacebo.c:124
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:996
TONE_MAP_REINHARD
@ TONE_MAP_REINHARD
Definition: vf_libplacebo.c:73
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
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:931
VAR_VSUB
@ VAR_VSUB
Definition: vf_libplacebo.c:131
libplacebo_config_output
static int libplacebo_config_output(AVFilterLink *outlink)
Definition: vf_libplacebo.c:1188
VAR_PH
@ VAR_PH
Definition: vf_libplacebo.c:126
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:1442
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:615
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:212
fifo.h
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
offset must point to a pointer immediately followed by an int for the length
Definition: opt.h:241
AVCOL_TRC_IEC61966_2_1
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:594
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:422
LibplaceboContext::shader_bin_len
int shader_bin_len
Definition: vf_libplacebo.c:256
fail
#define fail()
Definition: checkasm.h:179
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
TONE_MAP_HABLE
@ TONE_MAP_HABLE
Definition: vf_libplacebo.c:75
AVCOL_RANGE_NB
@ AVCOL_RANGE_NB
Not part of ABI.
Definition: pixfmt.h:687
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:586
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:177
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:1412
LibplaceboContext::lut_entries
int lut_entries
Definition: vf_libplacebo.c:203
LibplaceboContext::pos_y_expr
char * pos_y_expr
Definition: vf_libplacebo.c:180
pts
static int64_t pts
Definition: transcode_aac.c:644
AV_ROUND_UP
@ AV_ROUND_UP
Round toward +infinity.
Definition: mathematics.h:134
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:106
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:242
VAR_CROP_W
@ VAR_CROP_W
Definition: vf_libplacebo.c:123
LibplaceboInput::renderer
pl_renderer renderer
Definition: vf_libplacebo.c:143
AVCOL_TRC_GAMMA22
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:585
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
LibplaceboContext::extra_opts
AVDictionary * extra_opts
Definition: vf_libplacebo.c:196
VAR_OW
@ VAR_OW
Definition: vf_libplacebo.c:121
TONE_MAP_CLIP
@ TONE_MAP_CLIP
Definition: vf_libplacebo.c:67
LibplaceboContext::antiringing
float antiringing
Definition: vf_libplacebo.c:204
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:208
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:206
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
VAR_VARS_NB
@ VAR_VARS_NB
Definition: vf_libplacebo.c:137
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
ff_vf_libplacebo
const AVFilter ff_vf_libplacebo
Definition: vf_libplacebo.c:1449
LibplaceboContext::crop_x_expr
char * crop_x_expr
Definition: vf_libplacebo.c:178
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:62
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:189
ff_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1568
ref_frame
static const AVFrame * ref_frame(const struct pl_frame_mix *mix)
Definition: vf_libplacebo.c:733
output_frame
static int output_frame(AVFilterContext *ctx, int64_t pts)
Definition: vf_libplacebo.c:807
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVCOL_PRI_NB
@ AVCOL_PRI_NB
Not part of ABI.
Definition: pixfmt.h:573
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:593
LibplaceboContext::force_dither
int force_dither
Definition: vf_libplacebo.c:210
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:937
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:616
AVDictionaryEntry::key
char * key
Definition: dict.h:90
TONE_MAP_MOBIUS
@ TONE_MAP_MOBIUS
Definition: vf_libplacebo.c:74
LibplaceboContext::opts
pl_options opts
Definition: vf_libplacebo.c:199
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:679
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
TONE_MAP_ST2094_10
@ TONE_MAP_ST2094_10
Definition: vf_libplacebo.c:69
libplacebo_uninit
static void libplacebo_uninit(AVFilterContext *avctx)
Definition: vf_libplacebo.c:690
LibplaceboContext::frame_mixer
char * frame_mixer
Definition: vf_libplacebo.c:202
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
filters.h
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c: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:237
AVCOL_PRI_SMPTE428
@ AVCOL_PRI_SMPTE428
SMPTE ST 428-1 (CIE 1931 XYZ)
Definition: pixfmt.h:567
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:209
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
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:720
VAR_IN_T
@ VAR_IN_T
Definition: vf_libplacebo.c:134
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:564
LibplaceboInput
Definition: vf_libplacebo.c:141
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:55
LibplaceboContext::force_divisible_by
int force_divisible_by
Definition: vf_libplacebo.c:188
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:558
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:146
link
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 link
Definition: filter_design.txt:23
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:562
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:563
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:442
get_tonemapping_func
static const struct pl_tone_map_function * get_tonemapping_func(int tm)
Definition: vf_libplacebo.c:290
VAR_IW
@ VAR_IW
Definition: vf_libplacebo.c:119
AVVulkanDeviceContext
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_vulkan.h:45
opts
AVDictionary * opts
Definition: movenc.c:51
VAR_PW
@ VAR_PW
Definition: vf_libplacebo.c:125
NULL
#define NULL
Definition: coverity.c:32
LibplaceboContext::dither_temporal
int dither_temporal
Definition: vf_libplacebo.c:247
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:709
AVVulkanDeviceContext::nb_enabled_dev_extensions
int nb_enabled_dev_extensions
Definition: hwcontext_vulkan.h:100
LibplaceboContext::skip_aa
int skip_aa
Definition: vf_libplacebo.c:206
LibplaceboContext::shader_bin
void * shader_bin
Definition: vf_libplacebo.c:255
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
LibplaceboContext::cones
int cones
Definition: vf_libplacebo.c:250
GAMUT_MAP_COUNT
@ GAMUT_MAP_COUNT
Definition: vf_libplacebo.c:91
AVCOL_TRC_IEC61966_2_4
@ AVCOL_TRC_IEC61966_2_4
IEC 61966-2-4.
Definition: pixfmt.h:592
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:221
activate
filter_frame For filters that do not use the activate() callback
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:153
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Definition: opt.h:242
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:415
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:557
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:505
parseutils.h
VAR_OUT_W
@ VAR_OUT_W
Definition: vf_libplacebo.c:121
AV_FRAME_DATA_ICC_PROFILE
@ AV_FRAME_DATA_ICC_PROFILE
The data contains an ICC profile as an opaque octet buffer following the format described by ISO 1507...
Definition: frame.h:144
ff_vk_filter_config_output
int ff_vk_filter_config_output(AVFilterLink *outlink)
Definition: vulkan_filter.c:198
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA
@ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata associated with a video frame.
Definition: frame.h:120
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:196
double
double
Definition: af_crystalizer.c:131
AVCOL_TRC_BT2020_10
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:595
AVCOL_SPC_YCGCO
@ AVCOL_SPC_YCGCO
used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
Definition: pixfmt.h:618
VAR_OUT_H
@ VAR_OUT_H
Definition: vf_libplacebo.c:122
LibplaceboContext::status_pts
int64_t status_pts
tracks status of most recently used input
Definition: vf_libplacebo.c:166
FFVulkanContext
Definition: vulkan.h:228
ff_all_color_spaces
AVFilterFormats * ff_all_color_spaces(void)
Construct an AVFilterFormats representing all possible color spaces.
Definition: formats.c:631
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:1389
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:652
parse_shader
static int parse_shader(AVFilterContext *avctx, const void *shader, size_t len)
Definition: vf_libplacebo.c:480
set_gamut_mode
static void set_gamut_mode(struct pl_color_map_params *p, int gamut_mode)
Definition: vf_libplacebo.c:310
libplacebo_config_input
static int libplacebo_config_input(AVFilterLink *inlink)
Definition: vf_libplacebo.c:1169
VAR_CW
@ VAR_CW
Definition: vf_libplacebo.c:123
AVCOL_PRI_BT2020
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition: pixfmt.h:566
LibplaceboInput::status_pts
int64_t status_pts
Definition: vf_libplacebo.c:149
LibplaceboContext::cone_str
float cone_str
Definition: vf_libplacebo.c:251
TONE_MAP_AUTO
@ TONE_MAP_AUTO
Definition: vf_libplacebo.c:66
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:609
LibplaceboContext::hue
float hue
Definition: vf_libplacebo.c:224
TONE_MAP_BT2390
@ TONE_MAP_BT2390
Definition: vf_libplacebo.c:70
AVCOL_TRC_SMPTE2084
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition: pixfmt.h:597
AVCOL_PRI_SMPTE431
@ AVCOL_PRI_SMPTE431
SMPTE ST 431-2 (2011) / DCI P3.
Definition: pixfmt.h:569
eval.h
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:366
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:588
AVCOL_PRI_FILM
@ AVCOL_PRI_FILM
colour filters using Illuminant C
Definition: pixfmt.h:565
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
LibplaceboInput::link
AVFilterLink * link
Definition: vf_libplacebo.c:147
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(libplacebo)
LibplaceboContext::deband_grain
float deband_grain
Definition: vf_libplacebo.c:218
LibplaceboInput::mix
struct pl_frame_mix mix
temporary storage
Definition: vf_libplacebo.c:146
AVFILTER_FLAG_HWDEVICE
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition: avfilter.h:138
LibplaceboContext::out_format_string
char * out_format_string
Definition: vf_libplacebo.c:170
LibplaceboContext::disable_fbos
int disable_fbos
Definition: vf_libplacebo.c:211
LibplaceboContext::saturation
float saturation
Definition: vf_libplacebo.c:223
LibplaceboContext::num_hooks
int num_hooks
Definition: vf_libplacebo.c:258
TONE_MAP_SPLINE
@ TONE_MAP_SPLINE
Definition: vf_libplacebo.c:72
LibplaceboContext::status
int status
Definition: vf_libplacebo.c:167
libplacebo_options
static const AVOption libplacebo_options[]
Definition: vf_libplacebo.c:1270
scale_eval.h
sigmoid
static float sigmoid(float x)
Definition: vf_dnn_detect.c:90
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:887
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:1013
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
GAMUT_MAP_CLIP
@ GAMUT_MAP_CLIP
Definition: vf_libplacebo.c:82
pl_options_alloc
#define pl_options_alloc(log)
Definition: vf_libplacebo.c:61
ff_all_color_ranges
AVFilterFormats * ff_all_color_ranges(void)
Construct an AVFilterFormats representing all possible color ranges.
Definition: formats.c:647
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
LibplaceboContext::polar_cutoff
float polar_cutoff
Definition: vf_libplacebo.c:207
av_pix_fmt_desc_get_id
enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc)
Definition: pixdesc.c:2984
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:126
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:201
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:148
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:191
AVCOL_TRC_BT709
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition: pixfmt.h:582
internal.h
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
Definition: opt.h:238
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:617
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:261
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:718
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
AV_FRAME_DATA_CONTENT_LIGHT_LEVEL
@ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition: frame.h:137
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:200
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:620
pl_options_free
#define pl_options_free(ptr)
Definition: vf_libplacebo.c:62
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:186
LibplaceboContext::gamma
float gamma
Definition: vf_libplacebo.c:225
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
VAR_OVSUB
@ VAR_OVSUB
Definition: vf_libplacebo.c:133
LibplaceboInput::qstatus
enum pl_queue_status qstatus
Definition: vf_libplacebo.c:145
GAMUT_MAP_ABSOLUTE
@ GAMUT_MAP_ABSOLUTE
Definition: vf_libplacebo.c:86
LibplaceboContext::min_peak
float min_peak
Definition: vf_libplacebo.c:230
LibplaceboContext::tonemapping_lut_size
int tonemapping_lut_size
Definition: vf_libplacebo.c:240
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
LibplaceboContext::tonemapping_param
float tonemapping_param
Definition: vf_libplacebo.c:238
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:94
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:612
LibplaceboContext::dithering
int dithering
Definition: vf_libplacebo.c:245
LibplaceboContext::scene_high
float scene_high
Definition: vf_libplacebo.c:232
STATIC
#define STATIC
Definition: vf_libplacebo.c:1267
drain_input_pts
static void drain_input_pts(LibplaceboInput *in, int64_t until)
Definition: vf_libplacebo.c:989
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:669
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
LibplaceboInput::queue
pl_queue queue
Definition: vf_libplacebo.c:144
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
AVFilter
Filter definition.
Definition: avfilter.h:166
pl_options_t::dither_params
struct pl_dither_params dither_params
Definition: vf_libplacebo.c:57
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:115
AVCOL_PRI_BT470M
@ AVCOL_PRI_BT470M
also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:560
GAMUT_MAP_DARKEN
@ GAMUT_MAP_DARKEN
Definition: vf_libplacebo.c:88
ret
ret
Definition: filter_design.txt:187
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:174
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:72
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:231
VAR_OH
@ VAR_OH
Definition: vf_libplacebo.c:122
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:150
VAR_CH
@ VAR_CH
Definition: vf_libplacebo.c:124
unlock_queue
static void unlock_queue(AVHWDeviceContext *ctx, uint32_t queue_family, uint32_t index)
Definition: hwcontext_vulkan.c:1418
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
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)
Transform evaluated width and height obtained from ff_scale_eval_dimensions into actual target width ...
Definition: scale_eval.c:113
VAR_T
@ VAR_T
Definition: vf_libplacebo.c:134
TONE_MAP_GAMMA
@ TONE_MAP_GAMMA
Definition: vf_libplacebo.c:76
LibplaceboContext::peakdetect
int peakdetect
Definition: vf_libplacebo.c:228
av_get_pix_fmt
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:2897
LibplaceboContext::deband_radius
float deband_radius
Definition: vf_libplacebo.c:217
LibplaceboInput::idx
int idx
Definition: vf_libplacebo.c:142
GAMUT_MAP_SATURATION
@ GAMUT_MAP_SATURATION
Definition: vf_libplacebo.c:85
AVCOL_TRC_ARIB_STD_B67
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:601
status
ov_status_e status
Definition: dnn_backend_openvino.c:121
LibplaceboContext::contrast_recovery
float contrast_recovery
Definition: vf_libplacebo.c:241
VAR_IN_W
@ VAR_IN_W
Definition: vf_libplacebo.c:119
update_crops
static void update_crops(AVFilterContext *ctx, LibplaceboInput *in, struct pl_frame *target, double target_pts)
Definition: vf_libplacebo.c:742
libplacebo_outputs
static const AVFilterPad libplacebo_outputs[]
Definition: vf_libplacebo.c:1441
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
VAR_HSUB
@ VAR_HSUB
Definition: vf_libplacebo.c:130
LibplaceboContext::inverse_tonemapping
int inverse_tonemapping
Definition: vf_libplacebo.c:239
TONE_MAP_BT2446A
@ TONE_MAP_BT2446A
Definition: vf_libplacebo.c:71
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
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:587
file.h
OFFSET
#define OFFSET(x)
Definition: vf_libplacebo.c:1266
VAR_SAR
@ VAR_SAR
Definition: vf_libplacebo.c:128
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:602
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
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:99
ff_vk_filter_config_input
int ff_vk_filter_config_input(AVFilterLink *inlink)
Definition: vulkan_filter.c:166
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
VAR_IDX
@ VAR_IDX
Definition: vf_libplacebo.c:118
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:71
AVCOL_PRI_SMPTE432
@ AVCOL_PRI_SMPTE432
SMPTE ST 432-1 (2010) / P3 D65 / Display P3.
Definition: pixfmt.h:570
AVDictionaryEntry
Definition: dict.h:89
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:251
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
VAR_POS_W
@ VAR_POS_W
Definition: vf_libplacebo.c:125
max_q
static AVRational max_q(AVRational a, AVRational b)
Definition: vf_libplacebo.c:1183
LibplaceboContext::smoothing
float smoothing
Definition: vf_libplacebo.c:229
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:234
pl_options_t::color_map_params
struct pl_color_map_params color_map_params
Definition: vf_libplacebo.c:56
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
DYNAMIC
#define DYNAMIC
Definition: vf_libplacebo.c:1268
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
VAR_N
@ VAR_N
Definition: vf_libplacebo.c:136
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:254
VAR_A
@ VAR_A
Definition: vf_libplacebo.c:127
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:79
LibplaceboContext::color_range
int color_range
Definition: vf_libplacebo.c:193
AVDictionaryEntry::value
char * value
Definition: dict.h:91
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:239
LibplaceboContext::dither_lut_size
int dither_lut_size
Definition: vf_libplacebo.c:246
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:498
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:611
LibplaceboContext::h_expr
char * h_expr
Definition: vf_libplacebo.c:175
VAR_DAR
@ VAR_DAR
Definition: vf_libplacebo.c:129
pl_options_t::cone_params
struct pl_cone_params cone_params
Definition: vf_libplacebo.c:58
AVCOL_SPC_ICTCP
@ AVCOL_SPC_ICTCP
ITU-R BT.2100-0, ICtCp.
Definition: pixfmt.h:625
LibplaceboContext::hooks
const struct pl_hook * hooks[2]
Definition: vf_libplacebo.c:257
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
RET
#define RET(x)
Definition: vulkan.h:67
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
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
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:2885
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