mirror of https://github.com/mpv-player/mpv
vo_gpu_next: update for new tone mapping options
This was significantly refactored upstream. Switch to new APIs and add new tone mapping curves and options. cf. https://code.videolan.org/videolan/libplacebo/-/merge_requests/212
This commit is contained in:
parent
57bc5ba6d6
commit
a9cb2e2821
|
@ -32,6 +32,9 @@ Interface changes
|
|||
`--interpolation-preserve` `--lut`, `--lut-type`, `--image-lut`,
|
||||
`--image-lut-type` and `--target-lut` along with it.
|
||||
- add `--target-colorspace-hint`
|
||||
- add `--tone-mapping-crosstalk`
|
||||
- add `--tone-mapping` options `auto`, `spline` and `bt.2446a`
|
||||
- add `--inverse-tone-mapping`
|
||||
--- mpv 0.34.0 ---
|
||||
- deprecate selecting by card number with `--drm-connector`, add
|
||||
`--drm-device` which can be used instead
|
||||
|
|
|
@ -6302,6 +6302,8 @@ them.
|
|||
reduction (e.g. playing back BT.2020 content on a standard gamut display).
|
||||
Valid values are:
|
||||
|
||||
auto
|
||||
Choose the best curve according to internal heuristics. (Default)
|
||||
clip
|
||||
Hard-clip any out-of-range values. Use this when you care about
|
||||
perfect color accuracy for in-range values at the cost of completely
|
||||
|
@ -6327,13 +6329,17 @@ them.
|
|||
you should also enable ``--hdr-compute-peak`` for the best results.
|
||||
bt.2390
|
||||
Perceptual tone mapping curve (EETF) specified in ITU-R Report BT.2390.
|
||||
This is the recommended curve to use for typical HDR-mastered content.
|
||||
(Default)
|
||||
gamma
|
||||
Fits a logarithmic transfer between the tone curves.
|
||||
linear
|
||||
Linearly stretches the entire reference gamut to (a linear multiple of)
|
||||
the display.
|
||||
spline
|
||||
Perceptually linear single-pivot polynomial. (``--vo=gpu-next`` only)
|
||||
bt.2446a
|
||||
HDR<->SDR mapping specified in ITU-R Report BT.2446, method A. This is
|
||||
the recommended curve for well-mastered content. (``--vo=gpu-next``
|
||||
only)
|
||||
|
||||
``--tone-mapping-param=<value>``
|
||||
Set tone mapping parameters. By default, this is set to the special string
|
||||
|
@ -6358,6 +6364,17 @@ them.
|
|||
Specifies the exponent of the function. Defaults to 1.8.
|
||||
linear
|
||||
Specifies the scale factor to use while stretching. Defaults to 1.0.
|
||||
spline
|
||||
Specifies the knee point (in PQ space). Defaults to 0.30.
|
||||
|
||||
``--inverse-tone-mapping``
|
||||
If set, allows inverse tone mapping (expanding SDR to HDR). Not supported
|
||||
by all tone mapping curves. Use with caution. (``--vo=gpu-next`` only)
|
||||
|
||||
``--tone-mapping-crosstalk=<0.0..0.30>``
|
||||
If nonzero, apply an extra crosstalk matrix before tone mapping. Can help
|
||||
improve the appearance of strongly saturated monochromatic highlights.
|
||||
(Default: 0.04, only affects ``--vo=gpu-next``)
|
||||
|
||||
``--tone-mapping-max-boost=<1.0..10.0>``
|
||||
Upper limit for how much the tone mapping algorithm is allowed to boost
|
||||
|
@ -6365,7 +6382,8 @@ them.
|
|||
allows no additional brightness boost. A value of 2.0 would allow
|
||||
over-exposing by a factor of 2, and so on. Raising this setting can help
|
||||
reveal details that would otherwise be hidden in dark scenes, but raising
|
||||
it too high will make dark scenes appear unnaturally bright.
|
||||
it too high will make dark scenes appear unnaturally bright. (``-vo=gpu``
|
||||
only)
|
||||
|
||||
``--hdr-compute-peak=<auto|yes|no>``
|
||||
Compute the HDR peak and frame average brightness per-frame instead of
|
||||
|
@ -6413,8 +6431,8 @@ them.
|
|||
Apply desaturation for highlights (default: 0.75). The parameter controls
|
||||
the strength of the desaturation curve. A value of 0.0 completely disables
|
||||
it, while a value of 1.0 means that overly bright colors will tend towards
|
||||
white. (This is not always the case, especially not for highlights that are
|
||||
near primary colors)
|
||||
white. This is not always the case, especially not for highlights that are
|
||||
near primary colors. (``--vo=gpu`` only)
|
||||
|
||||
Values in between apply progressively more/less aggressive desaturation.
|
||||
This setting helps prevent unnaturally oversaturated colors for
|
||||
|
|
|
@ -977,14 +977,14 @@ if libplacebo.found()
|
|||
sources += files('video/out/placebo/ra_pl.c',
|
||||
'video/out/placebo/utils.c')
|
||||
pl_api_ver = libplacebo.version().split('.')[1]
|
||||
if pl_api_ver.version_compare('>=170')
|
||||
if pl_api_ver.version_compare('>=190')
|
||||
features += 'libplacebo-v4'
|
||||
libplacebo_v4 = true
|
||||
message('libplacebo v4.170+ found! Enabling vo_gpu_next.')
|
||||
message('libplacebo v4.190+ found! Enabling vo_gpu_next.')
|
||||
sources += files('video/out/vo_gpu_next.c',
|
||||
'video/out/gpu_next/context.c')
|
||||
else
|
||||
message('libplacebo v4.170+ not found! Disabling vo_gpu_next.')
|
||||
message('libplacebo v4.190+ not found! Disabling vo_gpu_next.')
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -322,9 +322,10 @@ static const struct gl_video_opts gl_video_opts_def = {
|
|||
.background = {0, 0, 0, 255},
|
||||
.gamma = 1.0f,
|
||||
.tone_map = {
|
||||
.curve = TONE_MAPPING_BT_2390,
|
||||
.curve = TONE_MAPPING_AUTO,
|
||||
.curve_param = NAN,
|
||||
.max_boost = 1.0,
|
||||
.crosstalk = 0.04,
|
||||
.decay_rate = 100.0,
|
||||
.scene_threshold_low = 5.5,
|
||||
.scene_threshold_high = 10.0,
|
||||
|
@ -378,13 +379,27 @@ const struct m_sub_options gl_video_conf = {
|
|||
{"target-peak", OPT_CHOICE(target_peak, {"auto", 0}),
|
||||
M_RANGE(10, 10000)},
|
||||
{"tone-mapping", OPT_CHOICE(tone_map.curve,
|
||||
{"auto", TONE_MAPPING_AUTO},
|
||||
{"clip", TONE_MAPPING_CLIP},
|
||||
{"mobius", TONE_MAPPING_MOBIUS},
|
||||
{"reinhard", TONE_MAPPING_REINHARD},
|
||||
{"hable", TONE_MAPPING_HABLE},
|
||||
{"gamma", TONE_MAPPING_GAMMA},
|
||||
{"linear", TONE_MAPPING_LINEAR},
|
||||
{"bt.2390", TONE_MAPPING_BT_2390})},
|
||||
{"spline", TONE_MAPPING_SPLINE},
|
||||
{"bt.2390", TONE_MAPPING_BT_2390},
|
||||
{"bt.2446a", TONE_MAPPING_BT_2446A})},
|
||||
{"tone-mapping-param", OPT_FLOATDEF(tone_map.curve_param)},
|
||||
{"inverse-tone-mapping", OPT_FLAG(tone_map.inverse)},
|
||||
{"tone-mapping-crosstalk", OPT_FLOAT(tone_map.crosstalk),
|
||||
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)},
|
||||
{"gamut-warning", OPT_FLAG(tone_map.gamut_warning)},
|
||||
{"gamut-clipping", OPT_FLAG(tone_map.gamut_clipping)},
|
||||
{"hdr-compute-peak", OPT_CHOICE(tone_map.compute_peak,
|
||||
{"auto", 0},
|
||||
{"yes", 1},
|
||||
|
@ -395,14 +410,6 @@ const struct m_sub_options gl_video_conf = {
|
|||
M_RANGE(0, 20.0)},
|
||||
{"hdr-scene-threshold-high", OPT_FLOAT(tone_map.scene_threshold_high),
|
||||
M_RANGE(0, 20.0)},
|
||||
{"tone-mapping-param", OPT_FLOATDEF(tone_map.curve_param)},
|
||||
{"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)},
|
||||
{"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),
|
||||
|
@ -2615,6 +2622,23 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src,
|
|||
if (!src.sig_peak)
|
||||
src.sig_peak = mp_trc_nom_peak(src.gamma);
|
||||
|
||||
// Whitelist supported modes
|
||||
switch (p->opts.tone_map.curve) {
|
||||
case TONE_MAPPING_AUTO:
|
||||
case TONE_MAPPING_CLIP:
|
||||
case TONE_MAPPING_MOBIUS:
|
||||
case TONE_MAPPING_REINHARD:
|
||||
case TONE_MAPPING_HABLE:
|
||||
case TONE_MAPPING_GAMMA:
|
||||
case TONE_MAPPING_LINEAR:
|
||||
case TONE_MAPPING_BT_2390:
|
||||
break;
|
||||
default:
|
||||
MP_WARN(p, "Tone mapping curve unsupported by vo_gpu, falling back.\n");
|
||||
p->opts.tone_map.curve = TONE_MAPPING_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;
|
||||
|
|
|
@ -88,19 +88,24 @@ enum blend_subs_mode {
|
|||
};
|
||||
|
||||
enum tone_mapping {
|
||||
TONE_MAPPING_AUTO,
|
||||
TONE_MAPPING_CLIP,
|
||||
TONE_MAPPING_MOBIUS,
|
||||
TONE_MAPPING_REINHARD,
|
||||
TONE_MAPPING_HABLE,
|
||||
TONE_MAPPING_GAMMA,
|
||||
TONE_MAPPING_LINEAR,
|
||||
TONE_MAPPING_SPLINE,
|
||||
TONE_MAPPING_BT_2390,
|
||||
TONE_MAPPING_BT_2446A,
|
||||
};
|
||||
|
||||
struct gl_tone_map_opts {
|
||||
int curve;
|
||||
float curve_param;
|
||||
float max_boost;
|
||||
int inverse;
|
||||
float crosstalk;
|
||||
int compute_peak;
|
||||
float decay_rate;
|
||||
float scene_threshold_low;
|
||||
|
|
|
@ -692,7 +692,8 @@ static void pass_tone_map(struct gl_shader_cache *sc,
|
|||
// This function always operates on an absolute scale, so ignore the
|
||||
// dst_peak normalization for it
|
||||
float dst_scale = dst_peak;
|
||||
if (opts->curve == TONE_MAPPING_BT_2390)
|
||||
enum tone_mapping curve = opts->curve ? opts->curve : TONE_MAPPING_BT_2390;
|
||||
if (curve == TONE_MAPPING_BT_2390)
|
||||
dst_scale = 1.0;
|
||||
|
||||
// Rescale the variables in order to bring it into a representation where
|
||||
|
@ -709,7 +710,7 @@ static void pass_tone_map(struct gl_shader_cache *sc,
|
|||
GLSL(sig_peak *= slope;)
|
||||
|
||||
float param = opts->curve_param;
|
||||
switch (opts->curve) {
|
||||
switch (curve) {
|
||||
case TONE_MAPPING_CLIP:
|
||||
GLSLF("sig = min(%f * sig, 1.0);\n", isnan(param) ? 1.0 : param);
|
||||
break;
|
||||
|
|
|
@ -1396,27 +1396,32 @@ static void update_render_options(struct priv *p)
|
|||
p->peak_detect.scene_threshold_low = opts->tone_map.scene_threshold_low;
|
||||
p->peak_detect.scene_threshold_high = opts->tone_map.scene_threshold_high;
|
||||
|
||||
static const enum pl_tone_mapping_algorithm tone_map_algos[] = {
|
||||
[TONE_MAPPING_CLIP] = PL_TONE_MAPPING_CLIP,
|
||||
[TONE_MAPPING_MOBIUS] = PL_TONE_MAPPING_MOBIUS,
|
||||
[TONE_MAPPING_REINHARD] = PL_TONE_MAPPING_REINHARD,
|
||||
[TONE_MAPPING_HABLE] = PL_TONE_MAPPING_HABLE,
|
||||
[TONE_MAPPING_GAMMA] = PL_TONE_MAPPING_GAMMA,
|
||||
[TONE_MAPPING_LINEAR] = PL_TONE_MAPPING_LINEAR,
|
||||
[TONE_MAPPING_BT_2390] = PL_TONE_MAPPING_BT_2390,
|
||||
static const struct pl_tone_map_function * const tone_map_funs[] = {
|
||||
[TONE_MAPPING_AUTO] = &pl_tone_map_auto,
|
||||
[TONE_MAPPING_CLIP] = &pl_tone_map_clip,
|
||||
[TONE_MAPPING_MOBIUS] = &pl_tone_map_mobius,
|
||||
[TONE_MAPPING_REINHARD] = &pl_tone_map_reinhard,
|
||||
[TONE_MAPPING_HABLE] = &pl_tone_map_hable,
|
||||
[TONE_MAPPING_GAMMA] = &pl_tone_map_gamma,
|
||||
[TONE_MAPPING_LINEAR] = &pl_tone_map_linear,
|
||||
[TONE_MAPPING_SPLINE] = &pl_tone_map_spline,
|
||||
[TONE_MAPPING_BT_2390] = &pl_tone_map_bt2390,
|
||||
[TONE_MAPPING_BT_2446A] = &pl_tone_map_bt2446a,
|
||||
};
|
||||
|
||||
p->color_map = pl_color_map_default_params;
|
||||
p->color_map.intent = opts->icc_opts->intent;
|
||||
p->color_map.tone_mapping_algo = tone_map_algos[opts->tone_map.curve];
|
||||
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;
|
||||
if (isnan(p->color_map.tone_mapping_param)) // vo_gpu compatibility
|
||||
p->color_map.tone_mapping_param = 0.0;
|
||||
p->color_map.desaturation_strength = opts->tone_map.desat;
|
||||
p->color_map.desaturation_exponent = opts->tone_map.desat_exp;
|
||||
p->color_map.max_boost = opts->tone_map.max_boost;
|
||||
p->color_map.gamut_warning = opts->tone_map.gamut_warning;
|
||||
p->color_map.gamut_clipping = opts->tone_map.gamut_clipping;
|
||||
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;
|
||||
}
|
||||
|
||||
switch (opts->dither_algo) {
|
||||
case DITHER_ERROR_DIFFUSION:
|
||||
|
|
Loading…
Reference in New Issue