From f3fccfc395ddb7a504ab2aae48452178fa92d907 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Mon, 3 Jan 2022 04:31:50 +0100 Subject: vo_gpu: add --gamut-mapping-mode Merge --gamut-clipping and --gamut-warning into a single option, --gamut-mapping-mode, better corresponding to the new vo_gpu_next APIs and allowing us to easily extend this option as new modes are added in the future. --- video/out/gpu/video.c | 23 ++++++++++++++++++++--- video/out/gpu/video.h | 11 +++++++++-- video/out/gpu/video_shaders.c | 6 +++--- video/out/vo_gpu_next.c | 14 +++++++++----- 4 files changed, 41 insertions(+), 13 deletions(-) (limited to 'video/out') diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index 32049f584c..8236a7b43f 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -331,7 +331,6 @@ static const struct gl_video_opts gl_video_opts_def = { .scene_threshold_high = 10.0, .desat = 0.75, .desat_exp = 1.5, - .gamut_clipping = 1, }, .early_flush = -1, .hwdec_interop = "auto", @@ -398,8 +397,12 @@ const struct m_sub_options gl_video_conf = { {"tone-mapping-desaturate", OPT_FLOAT(tone_map.desat)}, {"tone-mapping-desaturate-exponent", OPT_FLOAT(tone_map.desat_exp), M_RANGE(0.0, 20.0)}, - {"gamut-warning", OPT_FLAG(tone_map.gamut_warning)}, - {"gamut-clipping", OPT_FLAG(tone_map.gamut_clipping)}, + {"gamut-mapping-mode", OPT_CHOICE(tone_map.gamut_mode, + {"auto", GAMUT_AUTO}, + {"clip", GAMUT_CLIP}, + {"warn", GAMUT_WARN}, + {"desaturate", GAMUT_DESATURATE}, + {"darken", GAMUT_DARKEN})}, {"hdr-compute-peak", OPT_CHOICE(tone_map.compute_peak, {"auto", 0}, {"yes", 1}, @@ -474,6 +477,8 @@ const struct m_sub_options gl_video_conf = { {"opengl-gamma", OPT_REPLACED("gamma-factor")}, {"linear-scaling", OPT_REMOVED("Split into --linear-upscaling and " "--linear-downscaling")}, + {"gamut-warning", OPT_REMOVED("Replaced by --gamut-mapping-mode=warn")}, + {"gamut-clipping", OPT_REMOVED("Replaced by --gamut-mapping-mode=desaturate")}, {0} }, .size = sizeof(struct gl_video_opts), @@ -2639,6 +2644,18 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, break; } + switch (p->opts.tone_map.gamut_mode) { + case GAMUT_AUTO: + case GAMUT_WARN: + case GAMUT_CLIP: + case GAMUT_DESATURATE: + break; + default: + MP_WARN(p, "Gamut mapping mode unsupported by vo_gpu, falling back.\n"); + p->opts.tone_map.gamut_mode = GAMUT_AUTO; + break; + } + struct gl_tone_map_opts tone_map = p->opts.tone_map; bool detect_peak = tone_map.compute_peak >= 0 && mp_trc_is_hdr(src.gamma) && src.sig_peak > dst.sig_peak; diff --git a/video/out/gpu/video.h b/video/out/gpu/video.h index 13285bfce1..adeadaba65 100644 --- a/video/out/gpu/video.h +++ b/video/out/gpu/video.h @@ -100,6 +100,14 @@ enum tone_mapping { TONE_MAPPING_BT_2446A, }; +enum gamut_mode { + GAMUT_AUTO, + GAMUT_CLIP, + GAMUT_WARN, + GAMUT_DESATURATE, + GAMUT_DARKEN, +}; + struct gl_tone_map_opts { int curve; float curve_param; @@ -112,8 +120,7 @@ struct gl_tone_map_opts { float scene_threshold_high; float desat; float desat_exp; - int gamut_warning; // bool - int gamut_clipping; // bool + int gamut_mode; }; struct gl_video_opts { diff --git a/video/out/gpu/video_shaders.c b/video/out/gpu/video_shaders.c index d7774a61e5..6dcef77fa0 100644 --- a/video/out/gpu/video_shaders.c +++ b/video/out/gpu/video_shaders.c @@ -882,7 +882,7 @@ void pass_color_map(struct gl_shader_cache *sc, bool is_linear, gl_sc_uniform_mat3(sc, "cms_matrix", true, &m[0][0]); GLSL(color.rgb = cms_matrix * color.rgb;) - if (opts->gamut_clipping) { + if (!opts->gamut_mode || opts->gamut_mode == GAMUT_DESATURATE) { GLSL(float cmin = min(min(color.r, color.g), color.b);) GLSL(if (cmin < 0.0) { float luma = dot(dst_luma, color.rgb); @@ -907,8 +907,8 @@ void pass_color_map(struct gl_shader_cache *sc, bool is_linear, GLSLF("color.rgb *= vec3(%f);\n", 1.0 / dst_range); - // Warn for remaining out-of-gamut colors is enabled - if (opts->gamut_warning) { + // Warn for remaining out-of-gamut colors if enabled + if (opts->gamut_mode == GAMUT_WARN) { GLSL(if (any(greaterThan(color.rgb, vec3(1.005))) || any(lessThan(color.rgb, vec3(-0.005))))) GLSL(color.rgb = vec3(1.0) - color.rgb;) // invert diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 14e2fdeadc..390852ff71 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -1399,6 +1399,13 @@ static void update_render_options(struct priv *p) [TONE_MAPPING_BT_2446A] = &pl_tone_map_bt2446a, }; + static const enum pl_gamut_mode gamut_modes[] = { + [GAMUT_CLIP] = PL_GAMUT_CLIP, + [GAMUT_WARN] = PL_GAMUT_WARN, + [GAMUT_DESATURATE] = PL_GAMUT_DESATURATE, + [GAMUT_DARKEN] = PL_GAMUT_DARKEN, + }; + p->color_map = pl_color_map_default_params; p->color_map.intent = opts->icc_opts->intent; p->color_map.tone_mapping_function = tone_map_funs[opts->tone_map.curve]; @@ -1407,11 +1414,8 @@ static void update_render_options(struct priv *p) p->color_map.tone_mapping_crosstalk = opts->tone_map.crosstalk; if (isnan(p->color_map.tone_mapping_param)) // vo_gpu compatibility p->color_map.tone_mapping_param = 0.0; - if (opts->tone_map.gamut_clipping) { - p->color_map.gamut_mode = PL_GAMUT_DESATURATE; - } else if (opts->tone_map.gamut_warning) { - p->color_map.gamut_mode = PL_GAMUT_WARN; - } + if (opts->tone_map.gamut_mode != GAMUT_AUTO) + p->color_map.gamut_mode = gamut_modes[opts->tone_map.gamut_mode]; switch (opts->dither_algo) { case DITHER_ERROR_DIFFUSION: -- cgit v1.2.3