25 #include <libplacebo/renderer.h>
26 #include <libplacebo/utils/libav.h>
27 #include <libplacebo/vulkan.h>
177 av_log(log_ctx, av_lev,
"%s\n", msg);
183 const struct pl_hook *hook;
185 hook = pl_mpv_user_shader_parse(
s->gpu, shader,
len);
191 s->hooks[
s->num_hooks++] = hook;
196 const struct pl_filter_config **opt,
199 const struct pl_filter_preset *
preset;
200 if (!strcmp(
name,
"help")) {
223 s->log = pl_log_create(PL_API_VER, pl_log_params(
245 s->vulkan = pl_vulkan_import(
s->log, pl_vulkan_import_params(
246 .instance = hwctx->
inst,
254 .index = hwctx->queue_family_index,
255 .count = hwctx->nb_graphics_queues,
258 .index = hwctx->queue_family_comp_index,
259 .count = hwctx->nb_comp_queues,
262 .index = hwctx->queue_family_tx_index,
263 .count = hwctx->nb_tx_queues,
266 .max_api_version = VK_API_VERSION_1_2,
276 s->gpu =
s->vulkan->gpu;
277 s->renderer = pl_renderer_create(
s->log,
s->gpu);
280 if (
s->shader_bin_len)
283 if (
s->shader_path &&
s->shader_path[0]) {
300 for (
int i = 0;
i <
s->num_hooks;
i++)
301 pl_mpv_user_shader_destroy(&
s->hooks[
i]);
302 pl_renderer_destroy(&
s->renderer);
303 pl_vulkan_destroy(&
s->vulkan);
304 pl_log_destroy(&
s->log);
314 struct pl_render_params params;
315 enum pl_tone_map_mode tonemapping_mode =
s->tonemapping_mode;
316 enum pl_gamut_mode gamut_mode =
s->gamut_mode;
317 struct pl_frame image, target;
318 ok = pl_map_avframe_ex(
s->gpu, &image, pl_avframe_params(
320 .map_dovi =
s->apply_dovi,
323 ok &= pl_map_avframe_ex(
s->gpu, &target, pl_avframe_params(
333 if (!
s->apply_filmgrain)
334 image.film_grain.type = PL_FILM_GRAIN_NONE;
336 if (
s->target_sar.num) {
337 float aspect = pl_rect2df_aspect(&target.crop) *
av_q2d(
s->target_sar);
338 pl_rect2df_aspect_set(&target.crop, aspect,
s->pad_crop_ratio);
342 if (!tonemapping_mode && (
s->desat_str >= 0.0f ||
s->desat_exp >= 0.0f)) {
343 float str =
s->desat_str < 0.0f ? 0.9f :
s->desat_str;
344 float exp =
s->desat_exp < 0.0f ? 0.2f :
s->desat_exp;
346 tonemapping_mode = PL_TONE_MAP_RGB;
347 }
else if (
str > 0.1
f) {
348 tonemapping_mode = PL_TONE_MAP_HYBRID;
350 tonemapping_mode = PL_TONE_MAP_LUMA;
354 if (
s->gamut_warning)
355 gamut_mode = PL_GAMUT_WARN;
356 if (
s->gamut_clipping)
357 gamut_mode = PL_GAMUT_DESATURATE;
360 params = (
struct pl_render_params) {
362 .lut_entries =
s->lut_entries,
363 .antiringing_strength =
s->antiringing,
365 .deband_params = !
s->deband ?
NULL : pl_deband_params(
366 .iterations =
s->deband_iterations,
367 .threshold =
s->deband_threshold,
368 .radius =
s->deband_radius,
369 .grain =
s->deband_grain,
372 .sigmoid_params =
s->sigmoid ? &pl_sigmoid_default_params :
NULL,
374 .color_adjustment = &(
struct pl_color_adjustment) {
375 .brightness =
s->brightness,
376 .contrast =
s->contrast,
377 .saturation =
s->saturation,
382 .peak_detect_params = !
s->peakdetect ?
NULL : pl_peak_detect_params(
383 .smoothing_period =
s->smoothing,
384 .minimum_peak =
s->min_peak,
385 .scene_threshold_low =
s->scene_low,
386 .scene_threshold_high =
s->scene_high,
387 .overshoot_margin =
s->overshoot,
390 .color_map_params = pl_color_map_params(
392 .gamut_mode = gamut_mode,
394 .tone_mapping_param =
s->tonemapping_param,
395 .tone_mapping_mode = tonemapping_mode,
396 .inverse_tone_mapping =
s->inverse_tonemapping,
397 .tone_mapping_crosstalk =
s->crosstalk,
398 .lut_size =
s->tonemapping_lut_size,
401 .dither_params =
s->dithering < 0 ?
NULL : pl_dither_params(
402 .method =
s->dithering,
403 .lut_size =
s->dither_lut_size,
404 .temporal =
s->dither_temporal,
407 .cone_params = !
s->cones ?
NULL : pl_cone_params(
409 .strength =
s->cone_str,
413 .num_hooks =
s->num_hooks,
415 .skip_anti_aliasing =
s->skip_aa,
416 .polar_cutoff =
s->polar_cutoff,
417 .disable_linear_scaling =
s->disable_linear,
418 .disable_builtin_scalers =
s->disable_builtin,
419 .force_icc_lut =
s->force_icc_lut,
420 .force_dither =
s->force_dither,
421 .disable_fbos =
s->disable_fbos,
427 pl_render_image(
s->renderer, &image, &target, ¶ms);
428 pl_unmap_avframe(
s->gpu, &image);
429 pl_unmap_avframe(
s->gpu, &target);
432 pl_gpu_flush(
s->gpu);
436 pl_unmap_avframe(
s->gpu, &image);
437 pl_unmap_avframe(
s->gpu, &target);
443 int err, changed_csp;
459 out->width = outlink->
w;
460 out->height = outlink->
h;
470 if (
s->colorspace >= 0)
471 out->colorspace =
s->colorspace;
472 if (
s->color_range >= 0)
473 out->color_range =
s->color_range;
474 if (
s->color_trc >= 0)
475 out->color_trc =
s->color_trc;
476 if (
s->color_primaries >= 0)
477 out->color_primaries =
s->color_primaries;
489 if (
s->apply_dovi || changed_csp) {
493 if (
s->apply_filmgrain)
517 int *out_w = &
s->vkctx.output_width;
518 int *out_h = &
s->vkctx.output_height;
524 s->force_original_aspect_ratio,
525 s->force_divisible_by);
528 if (
inlink->sample_aspect_ratio.num)
531 if (
s->normalize_sar) {
533 s->target_sar = scale_sar;
538 if (
inlink->sample_aspect_ratio.num)
542 if (
s->out_format_string) {
550 s->vkctx.output_format =
s->vkctx.input_format;
556 vkfc->
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
564 #define OFFSET(x) offsetof(LibplaceboContext, x)
565 #define STATIC (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
566 #define DYNAMIC (STATIC | AV_OPT_FLAG_RUNTIME_PARAM)
572 {
"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,
"force_oar" },
576 {
"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 },
578 {
"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 },
605 {
"auto",
"keep the same color primaries", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX,
STATIC,
"color_primaries"},
621 {
"auto",
"keep the same color transfer", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX,
STATIC,
"color_trc"},
666 {
"relative",
"Relative colorimetric", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_INTENT_RELATIVE_COLORIMETRIC}, 0, 0,
STATIC,
"intent" },
667 {
"absolute",
"Absolute colorimetric", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_INTENT_ABSOLUTE_COLORIMETRIC}, 0, 0,
STATIC,
"intent" },
668 {
"saturation",
"Saturation mapping", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_INTENT_SATURATION}, 0, 0,
STATIC,
"intent" },
669 {
"gamut_mode",
"Gamut-mapping mode",
OFFSET(gamut_mode),
AV_OPT_TYPE_INT, {.i64 = PL_GAMUT_CLIP}, 0, PL_GAMUT_MODE_COUNT - 1,
DYNAMIC,
"gamut_mode" },
670 {
"clip",
"Hard-clip gamut boundary", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_GAMUT_CLIP}, 0, 0,
STATIC,
"gamut_mode" },
671 {
"warn",
"Highlight out-of-gamut colors", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_GAMUT_WARN}, 0, 0,
STATIC,
"gamut_mode" },
672 {
"darken",
"Darken image to fit gamut", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_GAMUT_DARKEN}, 0, 0,
STATIC,
"gamut_mode" },
673 {
"desaturate",
"Colorimetrically desaturate colors", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_GAMUT_DESATURATE}, 0, 0,
STATIC,
"gamut_mode" },
685 {
"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 },
686 {
"tonemapping_mode",
"Tone-mapping mode",
OFFSET(tonemapping_mode),
AV_OPT_TYPE_INT, {.i64 = PL_TONE_MAP_AUTO}, 0, PL_TONE_MAP_MODE_COUNT - 1,
DYNAMIC,
"tonemap_mode" },
687 {
"auto",
"Automatic selection", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_AUTO}, 0, 0,
STATIC,
"tonemap_mode" },
690 {
"hybrid",
"Hybrid of Luma/RGB", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_HYBRID}, 0, 0,
STATIC,
"tonemap_mode" },
692 {
"inverse_tonemapping",
"Inverse tone mapping (range expansion)",
OFFSET(inverse_tonemapping),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
DYNAMIC },
701 {
"dithering",
"Dither method to use",
OFFSET(dithering),
AV_OPT_TYPE_INT, {.i64 = PL_DITHER_BLUE_NOISE}, -1, PL_DITHER_METHOD_COUNT - 1,
DYNAMIC,
"dither" },
705 {
"ordered_fixed",
"Fixed function ordered", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_ORDERED_FIXED}, 0, 0,
STATIC,
"dither" },
724 {
"force_icc_lut",
"Force the use of a full ICC 3DLUT for color mapping",
OFFSET(force_icc_lut),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
DYNAMIC },
750 .
name =
"libplacebo",
759 .priv_class = &libplacebo_class,