From 347fbd6fa357e854cfb0bc6d3c9b3d12994d5c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Fri, 30 Jun 2023 05:46:51 +0200 Subject: vo_gpu_next: add --target-contrast option For better control over target display levels. --- video/out/gpu/video.c | 2 ++ video/out/gpu/video.h | 1 + video/out/vo_gpu_next.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) (limited to 'video/out') diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index d961002e7b..b38c88d054 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -374,6 +374,8 @@ const struct m_sub_options gl_video_conf = { {"target-trc", OPT_CHOICE_C(target_trc, mp_csp_trc_names)}, {"target-peak", OPT_CHOICE(target_peak, {"auto", 0}), M_RANGE(10, 10000)}, + {"target-contrast", OPT_CHOICE(target_contrast, {"auto", 0}, {"inf", -1}), + M_RANGE(10, 1000000)}, {"tone-mapping", OPT_CHOICE(tone_map.curve, {"auto", TONE_MAPPING_AUTO}, {"clip", TONE_MAPPING_CLIP}, diff --git a/video/out/gpu/video.h b/video/out/gpu/video.h index de70a8f801..307f7ea2ca 100644 --- a/video/out/gpu/video.h +++ b/video/out/gpu/video.h @@ -146,6 +146,7 @@ struct gl_video_opts { int target_prim; int target_trc; int target_peak; + int target_contrast; struct gl_tone_map_opts tone_map; bool correct_downscaling; bool linear_downscaling; diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 93cf4f54d6..42164ecd98 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -788,6 +789,32 @@ static void update_options(struct vo *vo) p->output_levels = cparams.levels_out; } +static void apply_target_contrast(struct priv *p, struct pl_color_space *color) +{ + const struct gl_video_opts *opts = p->opts_cache->opts; + + // Auto mode, leave as is + if (!opts->target_contrast) + return; + + // Infinite contrast + if (opts->target_contrast == -1) { + color->hdr.max_luma = 1e-7; + return; + } + + // Infer max_luma for current pl_color_space + pl_color_space_nominal_luma_ex(pl_nominal_luma_params( + .color = color, + // with HDR10 meta to respect value if already set + .metadata = PL_HDR_METADATA_HDR10, + .scaling = PL_HDR_NITS, + .out_max = &color->hdr.max_luma + )); + + color->hdr.min_luma = color->hdr.max_luma / opts->target_contrast; +} + static void apply_target_options(struct priv *p, struct pl_frame *target) { @@ -806,6 +833,8 @@ static void apply_target_options(struct priv *p, struct pl_frame *target) // If swapchain returned a value use this, override is used in hint if (opts->target_peak && !target->color.hdr.max_luma) target->color.hdr.max_luma = opts->target_peak; + if (!target->color.hdr.min_luma) + apply_target_contrast(p, &target->color); if (opts->dither_depth > 0) { struct pl_bit_encoding *tbits = &target->repr.bits; tbits->color_depth += opts->dither_depth - tbits->sample_depth; @@ -897,6 +926,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) hint.transfer = mp_trc_to_pl(opts->target_trc); if (opts->target_peak) hint.hdr.max_luma = opts->target_peak; + apply_target_contrast(p, &hint); pl_swapchain_colorspace_hint(p->sw, &hint); } else if (!p->target_hint) { pl_swapchain_colorspace_hint(p->sw, NULL); -- cgit v1.2.3