From d09c73c7b2b0135cb24ab2173b3c4ee1c55840b0 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Tue, 4 Jan 2022 01:50:00 +0100 Subject: vo_gpu: add --tone-mapping-mode This merges the old desaturation control options into a single enumeration, with the goal of both simplifying how these options work and also making this list more extensible (including, notably, new options only supported by vo_gpu_next). For the hybrid option, I decided to port the (slightly tweaked) values from libplacebo's pre-refactor defaults, rather than the old values we had in mpv, to more visually match the look of the vo_gpu_next hybrid. --- video/out/gpu/video.c | 25 ++++++++++++++++++++----- video/out/gpu/video.h | 11 +++++++++-- video/out/gpu/video_shaders.c | 30 ++++++++++++++++++------------ video/out/vo_gpu_next.c | 9 +++++++++ 4 files changed, 56 insertions(+), 19 deletions(-) (limited to 'video/out') diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index 8236a7b43f..d0d0509792 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -329,8 +329,6 @@ static const struct gl_video_opts gl_video_opts_def = { .decay_rate = 100.0, .scene_threshold_low = 5.5, .scene_threshold_high = 10.0, - .desat = 0.75, - .desat_exp = 1.5, }, .early_flush = -1, .hwdec_interop = "auto", @@ -394,9 +392,12 @@ const struct m_sub_options gl_video_conf = { M_RANGE(0.0, 0.3)}, {"tone-mapping-max-boost", OPT_FLOAT(tone_map.max_boost), M_RANGE(1.0, 10.0)}, - {"tone-mapping-desaturate", OPT_FLOAT(tone_map.desat)}, - {"tone-mapping-desaturate-exponent", OPT_FLOAT(tone_map.desat_exp), - M_RANGE(0.0, 20.0)}, + {"tone-mapping-mode", OPT_CHOICE(tone_map.mode, + {"auto", TONE_MAP_MODE_AUTO}, + {"rgb", TONE_MAP_MODE_RGB}, + {"max", TONE_MAP_MODE_MAX}, + {"hybrid", TONE_MAP_MODE_HYBRID}, + {"luma", TONE_MAP_MODE_LUMA})}, {"gamut-mapping-mode", OPT_CHOICE(tone_map.gamut_mode, {"auto", GAMUT_AUTO}, {"clip", GAMUT_CLIP}, @@ -479,6 +480,8 @@ const struct m_sub_options gl_video_conf = { "--linear-downscaling")}, {"gamut-warning", OPT_REMOVED("Replaced by --gamut-mapping-mode=warn")}, {"gamut-clipping", OPT_REMOVED("Replaced by --gamut-mapping-mode=desaturate")}, + {"tone-mapping-desaturate", OPT_REMOVED("Replaced by --tone-mapping-mode")}, + {"tone-mapping-desaturate-exponent", OPT_REMOVED("Replaced by --tone-mapping-mode")}, {0} }, .size = sizeof(struct gl_video_opts), @@ -2644,6 +2647,18 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, break; } + switch (p->opts.tone_map.mode) { + case TONE_MAP_MODE_AUTO: + case TONE_MAP_MODE_RGB: + case TONE_MAP_MODE_MAX: + case TONE_MAP_MODE_HYBRID: + break; + default: + MP_WARN(p, "Tone mapping mode unsupported by vo_gpu, falling back.\n"); + p->opts.tone_map.mode = TONE_MAP_MODE_AUTO; + break; + } + switch (p->opts.tone_map.gamut_mode) { case GAMUT_AUTO: case GAMUT_WARN: diff --git a/video/out/gpu/video.h b/video/out/gpu/video.h index adeadaba65..0bb180e514 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 tone_mapping_mode { + TONE_MAP_MODE_AUTO, + TONE_MAP_MODE_RGB, + TONE_MAP_MODE_MAX, + TONE_MAP_MODE_HYBRID, + TONE_MAP_MODE_LUMA, +}; + enum gamut_mode { GAMUT_AUTO, GAMUT_CLIP, @@ -114,12 +122,11 @@ struct gl_tone_map_opts { float max_boost; int inverse; float crosstalk; + int mode; int compute_peak; float decay_rate; float scene_threshold_low; float scene_threshold_high; - float desat; - float desat_exp; int gamut_mode; }; diff --git a/video/out/gpu/video_shaders.c b/video/out/gpu/video_shaders.c index 6dcef77fa0..9628274b19 100644 --- a/video/out/gpu/video_shaders.c +++ b/video/out/gpu/video_shaders.c @@ -809,18 +809,24 @@ static void pass_tone_map(struct gl_shader_cache *sc, abort(); } - GLSL(vec3 sig_lin = color.rgb * (sig[sig_idx] / sig_orig);) - - // Mix between the per-channel tone mapped and the linear tone mapped - // signal based on the desaturation strength - if (opts->desat > 0) { - float base = 0.18 * dst_scale; - GLSLF("float coeff = max(sig[sig_idx] - %f, 1e-6) / " - " max(sig[sig_idx], 1.0);\n", base); - GLSLF("coeff = %f * pow(coeff, %f);\n", opts->desat, opts->desat_exp); - GLSLF("color.rgb = mix(sig_lin, %f * sig, coeff);\n", dst_scale); - } else { - GLSL(color.rgb = sig_lin;) + switch (opts->mode) { + case TONE_MAP_MODE_RGB: + GLSL(color.rgb = sig;) + break; + case TONE_MAP_MODE_MAX: + GLSL(color.rgb *= sig[sig_idx] / sig_orig;) + break; + case TONE_MAP_MODE_AUTO: + case TONE_MAP_MODE_HYBRID: + GLSLF("float coeff = max(sig[sig_idx] - %f, 1e-6) / \n" + " max(sig[sig_idx], 1.0); \n" + "coeff = %f * pow(coeff / %f, %f); \n" + "color.rgb *= sig[sig_idx] / sig_orig; \n" + "color.rgb = mix(color.rgb, %f * sig, coeff); \n", + 0.18 / dst_scale, 0.90, dst_scale, 0.20, dst_scale); + break; + default: + abort(); } } diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 390852ff71..9bbb58101f 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -1406,12 +1406,21 @@ static void update_render_options(struct priv *p) [GAMUT_DARKEN] = PL_GAMUT_DARKEN, }; + static const enum pl_tone_map_mode tone_map_modes[] = { + [TONE_MAP_MODE_AUTO] = PL_TONE_MAP_AUTO, + [TONE_MAP_MODE_RGB] = PL_TONE_MAP_RGB, + [TONE_MAP_MODE_MAX] = PL_TONE_MAP_MAX, + [TONE_MAP_MODE_HYBRID] = PL_TONE_MAP_HYBRID, + [TONE_MAP_MODE_LUMA] = PL_TONE_MAP_LUMA, + }; + 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]; p->color_map.tone_mapping_param = opts->tone_map.curve_param; p->color_map.inverse_tone_mapping = opts->tone_map.inverse; p->color_map.tone_mapping_crosstalk = opts->tone_map.crosstalk; + p->color_map.tone_mapping_mode = tone_map_modes[opts->tone_map.mode]; if (isnan(p->color_map.tone_mapping_param)) // vo_gpu compatibility p->color_map.tone_mapping_param = 0.0; if (opts->tone_map.gamut_mode != GAMUT_AUTO) -- cgit v1.2.3