summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2022-01-03 04:31:50 +0100
committerNiklas Haas <github-daiK1o@haasn.dev>2022-01-07 06:28:14 +0100
commitf3fccfc395ddb7a504ab2aae48452178fa92d907 (patch)
treef273e2a3e74820aeb718601bd709e84cebf123e0
parent2332445d8d78d569015cabbacb3d9cf5552e5c73 (diff)
downloadmpv-f3fccfc395ddb7a504ab2aae48452178fa92d907.tar.bz2
mpv-f3fccfc395ddb7a504ab2aae48452178fa92d907.tar.xz
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.
-rw-r--r--DOCS/interface-changes.rst1
-rw-r--r--DOCS/man/options.rst37
-rw-r--r--video/out/gpu/video.c23
-rw-r--r--video/out/gpu/video.h11
-rw-r--r--video/out/gpu/video_shaders.c6
-rw-r--r--video/out/vo_gpu_next.c14
6 files changed, 60 insertions, 32 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 2c59f0f6b5..75516627df 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -35,6 +35,7 @@ Interface changes
- add `--tone-mapping-crosstalk`
- add `--tone-mapping` options `auto`, `spline` and `bt.2446a`
- add `--inverse-tone-mapping`
+ - add `--gamut-mapping-mode`, replacing `--gamut-clipping` and `--gamut-warning`
--- mpv 0.34.0 ---
- deprecate selecting by card number with `--drm-connector`, add
`--drm-device` which can be used instead
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 6742ec1a6c..bd2b9be470 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -6385,6 +6385,24 @@ them.
it too high will make dark scenes appear unnaturally bright. (``-vo=gpu``
only)
+``--gamut-mapping-mode``
+ Specifies the algorithm used for reducing the gamut of images for the
+ target display, after any tone mapping is done.
+
+ auto
+ Choose the best mode automatically. (Default)
+ clip
+ Hard-clip to the gamut (per-channel).
+ warn
+ Simply highlight out-of-gamut pixels.
+ desaturate
+ Chromatically desaturate out-of-gamut colors towards white.
+ darken
+ Linearly darken the entire image, then clip to the color volume. Unlike
+ ``clip``, this does not destroy detail in saturated regions, but comes
+ at the cost of sometimes significantly lowering output brightness.
+ (``--vo=gpu-next`` only)
+
``--hdr-compute-peak=<auto|yes|no>``
Compute the HDR peak and frame average brightness per-frame instead of
relying on tagged metadata. These values are averaged over local regions as
@@ -6448,25 +6466,6 @@ them.
desaturated. The default of 1.5 provides a reasonable balance. Decreasing
this exponent makes the curve more aggressive.
-``--gamut-warning``
- If enabled, mpv will mark all clipped/out-of-gamut pixels that exceed a
- given threshold (currently hard-coded to 101%). The affected pixels will be
- inverted to make them stand out. Note: This option applies after the
- effects of all of mpv's color space transformation / tone mapping options,
- so it's a good idea to combine this with ``--tone-mapping=clip`` and use
- ``--target-prim`` to set the gamut to simulate. For example,
- ``--target-prim=bt.709`` would make mpv highlight all pixels that exceed the
- gamut of a standard gamut (sRGB) display. This option also does not work
- well with ICC profiles, since the 3DLUTs are always generated against the
- source color space and have chromatically-accurate clipping built in.
-
-``--gamut-clipping``
- If enabled (default: yes), mpv will colorimetrically clip out-of-gamut
- colors by desaturating them (preserving luma), rather than hard-clipping
- each component individually. This should make playback of wide gamut
- content on typical (standard gamut) monitors look much more aesthetically
- pleasing and less blown-out.
-
``--use-embedded-icc-profile``
Load the embedded ICC profile contained in media files such as PNG images.
(Default: yes). Note that this option only works when also using a display
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: