mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
2332445d8d
commit
f3fccfc395
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue