summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.xyz>2017-09-10 18:18:31 +0200
committerNiklas Haas <git@haasn.xyz>2017-09-10 18:19:46 +0200
commitd0c87dd57918cab1afc4d5968355b6253377c0b1 (patch)
treebe74d142ba356485b0f9e58bddff37495229dab4
parentb19b0869d68121f4e9a973b53d9abbd370d0a160 (diff)
downloadmpv-d0c87dd57918cab1afc4d5968355b6253377c0b1.tar.bz2
mpv-d0c87dd57918cab1afc4d5968355b6253377c0b1.tar.xz
vo_opengl: add a gamut warning feature
This clearly highlights all out-of-gamut/clipped pixels. (Either too bright or too saturated) Has some (documented) caveats. Also make TONE_MAPPING_CLIP stop actually clamping the value range (it's unnecessary and breaks this feature).
-rw-r--r--DOCS/man/options.rst12
-rw-r--r--video/out/opengl/video.c3
-rw-r--r--video/out/opengl/video.h1
-rw-r--r--video/out/opengl/video_shaders.c10
-rw-r--r--video/out/opengl/video_shaders.h2
5 files changed, 24 insertions, 4 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index dd9a51e807..ce14d3e92a 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -4865,6 +4865,18 @@ The following video options are currently all specific to ``--vo=opengl`` and
The default of 2.0 is somewhat conservative and will mostly just apply to
skies or directly sunlit surfaces. A setting of 0.0 disables this option.
+``--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-gamut`` to set the gamut to simulate. For example,
+ ``--target-gamut=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.
+
``--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/opengl/video.c b/video/out/opengl/video.c
index 8d90c2bcaa..3362381eff 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -363,6 +363,7 @@ const struct m_sub_options gl_video_conf = {
OPT_FLAG("hdr-compute-peak", compute_hdr_peak, 0),
OPT_FLOAT("tone-mapping-param", tone_mapping_param, 0),
OPT_FLOAT("tone-mapping-desaturate", tone_mapping_desat, 0),
+ OPT_FLAG("gamut-warning", gamut_warning, 0),
OPT_FLAG("opengl-pbo", pbo, 0),
SCALER_OPTS("scale", SCALER_SCALE),
SCALER_OPTS("dscale", SCALER_DSCALE),
@@ -2460,7 +2461,7 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool
// Adapt from src to dst as necessary
pass_color_map(p->sc, src, dst, p->opts.tone_mapping,
p->opts.tone_mapping_param, p->opts.tone_mapping_desat,
- detect_peak, p->use_linear && !osd);
+ detect_peak, p->opts.gamut_warning, p->use_linear && !osd);
if (p->use_lut_3d) {
gl_sc_uniform_texture(p->sc, "lut_3d", p->lut_3d_texture);
diff --git a/video/out/opengl/video.h b/video/out/opengl/video.h
index e5e7ae70ec..e20af90643 100644
--- a/video/out/opengl/video.h
+++ b/video/out/opengl/video.h
@@ -115,6 +115,7 @@ struct gl_video_opts {
int compute_hdr_peak;
float tone_mapping_param;
float tone_mapping_desat;
+ int gamut_warning;
int linear_scaling;
int correct_downscaling;
int sigmoid_upscaling;
diff --git a/video/out/opengl/video_shaders.c b/video/out/opengl/video_shaders.c
index 10edc0563d..60c5ce82ac 100644
--- a/video/out/opengl/video_shaders.c
+++ b/video/out/opengl/video_shaders.c
@@ -616,7 +616,7 @@ static void pass_tone_map(struct gl_shader_cache *sc, float ref_peak,
switch (algo) {
case TONE_MAPPING_CLIP:
- GLSLF("sig = clamp(%f * sig, 0.0, 1.0);\n", isnan(param) ? 1.0 : param);
+ GLSLF("sig = %f * sig;\n", isnan(param) ? 1.0 : param);
break;
case TONE_MAPPING_MOBIUS:
@@ -683,7 +683,7 @@ void pass_color_map(struct gl_shader_cache *sc,
struct mp_colorspace src, struct mp_colorspace dst,
enum tone_mapping algo, float tone_mapping_param,
float tone_mapping_desat, bool detect_peak,
- bool is_linear)
+ bool gamut_warning, bool is_linear)
{
GLSLF("// color mapping\n");
@@ -748,6 +748,12 @@ void pass_color_map(struct gl_shader_cache *sc,
if (src.light != dst.light)
pass_inverse_ootf(sc, dst.light, mp_trc_nom_peak(dst.gamma));
+ // Warn for remaining out-of-gamut colors is enabled
+ if (gamut_warning) {
+ GLSL(if (any(greaterThan(color.rgb, vec3(1.01)))))
+ GLSL(color.rgb = vec3(1.0) - color.rgb;) // invert
+ }
+
if (is_linear)
pass_delinearize(sc, dst.gamma);
}
diff --git a/video/out/opengl/video_shaders.h b/video/out/opengl/video_shaders.h
index 1fae830720..8345e4c598 100644
--- a/video/out/opengl/video_shaders.h
+++ b/video/out/opengl/video_shaders.h
@@ -46,7 +46,7 @@ void pass_color_map(struct gl_shader_cache *sc,
struct mp_colorspace src, struct mp_colorspace dst,
enum tone_mapping algo, float tone_mapping_param,
float tone_mapping_desat, bool use_detected_peak,
- bool is_linear);
+ bool gamut_warning, bool is_linear);
void pass_sample_deband(struct gl_shader_cache *sc, struct deband_opts *opts,
AVLFG *lfg, enum mp_csp_trc trc);