diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index d8c11bd995bcd..92a625afa4eb9 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -7499,7 +7499,7 @@ them. In such a configuration, we highly recommend setting ``--tone-mapping`` to ``mobius`` or even ``clip``. -``--target-contrast=`` +``--target-contrast=`` Specifies the measured contrast of the output display. ``--target-contrast`` in conjunction with ``--target-peak`` value is used to calculate display black point. Used in black point compensation during HDR tone-mapping. @@ -7509,6 +7509,21 @@ them. ``inf`` contrast specifies display with perfect black level, in practice OLED. (Only for ``--vo=gpu-next``) +``--target-contrast-hdr=`` + Same as ``--target-contrast``, but only applies when ``--target-trc`` is set to + a HDR transfer function and would override the settings of ``--target-contrast``. + This allows to specify a different contrast for HDR content. + + This might be useful when user is running a host OS that supports global color + management and monitor has large contrast ratio. In this case, under some OS + implementation, mpv can't correctly get the actual contrast ratio info of the + monitor when ``--target-trc`` is a SDR transfer function, and only use + ``--target-contrast=auto`` might cause washed out colors. + + ``no`` is the default value and means the contrast is only controlled by + ``--target-contrast``. + (Only for ``--vo=gpu-next``) + ``--target-gamut=`` Constrains the gamut of the display. You can use this option to output e.g. DCIP3-in-BT.2020. Set ``--target-prim`` to the primaries of the containing diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index 603f35ef0a2c0..68c62edc89ae2 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -453,6 +453,8 @@ const struct m_sub_options gl_video_conf = { {"no", 0}, {"input", 1}, {"output", 2}, {"both", 1|2}, {"auto", 1|2|4})}, {"target-contrast", OPT_CHOICE(target_contrast, {"auto", 0}, {"inf", -1}), M_RANGE(10, 10 / PL_COLOR_HDR_BLACK)}, + {"target-contrast-hdr", OPT_CHOICE(target_contrast_hdr, {"no", 0}, {"auto", -1}, {"inf", -2}), + M_RANGE(10, 10 / PL_COLOR_HDR_BLACK)}, {"target-gamut", OPT_STRING_VALIDATE(target_gamut, validate_target_gamut)}, {"tone-mapping", OPT_CHOICE(tone_map.curve, {"auto", TONE_MAPPING_AUTO}, diff --git a/video/out/gpu/video.h b/video/out/gpu/video.h index a5b03adfbf7bc..589f912631a5a 100644 --- a/video/out/gpu/video.h +++ b/video/out/gpu/video.h @@ -142,6 +142,7 @@ struct gl_video_opts { int sdr_adjust_gamma; int treat_srgb_as_power22; int target_contrast; + int target_contrast_hdr; char *target_gamut; struct gl_tone_map_opts tone_map; bool correct_downscaling; diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 308a9fb02f5b6..d224bc4240bc6 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -915,6 +915,20 @@ static void update_options(struct vo *vo) static void apply_target_contrast(struct priv *p, struct pl_color_space *color, float min_luma) { const struct gl_video_opts *opts = p->opts_cache->opts; + const bool is_hdr = pl_color_space_is_hdr(color); + + if (is_hdr && opts->target_contrast_hdr) + switch (opts->target_contrast_hdr) { + case -1: + color->hdr.min_luma = min_luma; + return; + case -2: + color->hdr.min_luma = 1e-7; + mp_assert(color->hdr.min_luma > 0); + return; + default: + goto apply_user_value; + } // Auto mode, use target value if available if (!opts->target_contrast) { @@ -929,6 +943,7 @@ static void apply_target_contrast(struct priv *p, struct pl_color_space *color, return; } +apply_user_value: // Infer max_luma for current pl_color_space pl_color_space_nominal_luma_ex(pl_nominal_luma_params( .color = color, @@ -938,7 +953,10 @@ static void apply_target_contrast(struct priv *p, struct pl_color_space *color, .out_max = &color->hdr.max_luma )); - color->hdr.min_luma = color->hdr.max_luma / opts->target_contrast; + if (is_hdr && opts->target_contrast_hdr) + color->hdr.min_luma = color->hdr.max_luma / opts->target_contrast_hdr; + else + color->hdr.min_luma = color->hdr.max_luma / opts->target_contrast; } static void apply_target_options(struct priv *p, struct pl_frame *target,