Skip to content

Commit

Permalink
vo_gpu: add better gamut clipping option
Browse files Browse the repository at this point in the history
See https://code.videolan.org/videolan/libplacebo/-/commit/d63eeb1ecc204

Enabled by default because I think it looks better. YMMV.
  • Loading branch information
haasn committed Jun 19, 2020
1 parent ae5ac7e commit dc24a43
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 0 deletions.
7 changes: 7 additions & 0 deletions DOCS/man/options.rst
Expand Up @@ -6167,6 +6167,13 @@ The following video options are currently all specific to ``--vo=gpu`` and
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
Expand Down
2 changes: 2 additions & 0 deletions video/out/gpu/video.c
Expand Up @@ -330,6 +330,7 @@ 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",
Expand Down Expand Up @@ -401,6 +402,7 @@ const struct m_sub_options gl_video_conf = {
{"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)},
{"opengl-pbo", OPT_FLAG(pbo)},
SCALER_OPTS("scale", SCALER_SCALE),
SCALER_OPTS("dscale", SCALER_DSCALE),
Expand Down
1 change: 1 addition & 0 deletions video/out/gpu/video.h
Expand Up @@ -108,6 +108,7 @@ struct gl_tone_map_opts {
float desat;
float desat_exp;
int gamut_warning; // bool
int gamut_clipping; // bool
};

struct gl_video_opts {
Expand Down
11 changes: 11 additions & 0 deletions video/out/gpu/video_shaders.c
Expand Up @@ -870,6 +870,17 @@ void pass_color_map(struct gl_shader_cache *sc, bool is_linear,
mp_get_cms_matrix(csp_src, csp_dst, MP_INTENT_RELATIVE_COLORIMETRIC, m);
gl_sc_uniform_mat3(sc, "cms_matrix", true, &m[0][0]);
GLSL(color.rgb = cms_matrix * color.rgb;)

if (opts->gamut_clipping) {
GLSL(float cmin = min(min(color.r, color.g), color.b);)
GLSL(if (cmin < 0.0) {
float luma = dot(dst_luma, color.rgb);
float coeff = cmin / (cmin - luma);
color.rgb = mix(color.rgb, vec3(luma), coeff);
})
GLSL(float cmax = max(max(color.r, color.g), color.b);)
GLSL(if (cmax > 1.0) color.rgb /= cmax;)
}
}

if (need_ootf)
Expand Down

3 comments on commit dc24a43

@Doofussy2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is on by default, does that mean it will always clip? Or will it automatically see how wide the gamut is and act accordingly? More concisely, do I need to set --gamut-clipping=no when applying --target-prim=bt.2020?

@haasn
Copy link
Member Author

@haasn haasn commented on dc24a43 Jun 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is on by default, does that mean it will always clip?

This option never introduces clipping. It's about clipping in a smarter way, in cases that would previously clip badly.

Or will it automatically see how wide the gamut is and act accordingly?

Right now it always runs when gamut mapping is performed. In theory we could make it only run when the gamut is being reduced, that's what the libplacebo commit mentioned does. But the performance impact from a non-divergent branch is negligible so I don't think it's a big deal.

More concisely, do I need to set --gamut-clipping=no when applying --target-prim=bt.2020?

Only if you want to save a few nanoseconds.

@Doofussy2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So left enabled, it won't affect the color in an HDR wide gamut environment?

Please sign in to comment.