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:
Niklas Haas 2022-01-03 03:56:36 +01:00 committed by Niklas Haas
parent 57bc5ba6d6
commit a9cb2e2821
7 changed files with 90 additions and 34 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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: