summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2023-06-30 05:46:51 +0200
committerNiklas Haas <github-daiK1o@haasn.dev>2023-07-17 18:50:34 +0200
commit347fbd6fa357e854cfb0bc6d3c9b3d12994d5c0c (patch)
tree8fbd9e2477fae72b333a91d4712936dbe8354aa3 /video
parentfbd392bcbb2d8b17ccefa79446d275caa25762d8 (diff)
downloadmpv-347fbd6fa357e854cfb0bc6d3c9b3d12994d5c0c.tar.bz2
mpv-347fbd6fa357e854cfb0bc6d3c9b3d12994d5c0c.tar.xz
vo_gpu_next: add --target-contrast option
For better control over target display levels.
Diffstat (limited to 'video')
-rw-r--r--video/out/gpu/video.c2
-rw-r--r--video/out/gpu/video.h1
-rw-r--r--video/out/vo_gpu_next.c30
3 files changed, 33 insertions, 0 deletions
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 <pthread.h>
+#include <libplacebo/colorspace.h>
#include <libplacebo/renderer.h>
#include <libplacebo/shaders/lut.h>
#include <libplacebo/utils/libav.h>
@@ -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);