summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2022-01-03 03:56:36 +0100
committerNiklas Haas <github-daiK1o@haasn.dev>2022-01-07 06:28:14 +0100
commita9cb2e2821adb40e7548e8233390e79706104041 (patch)
tree382cee5ce44b9c6cf3ae196e23e908c4718ebbea
parent57bc5ba6d6579d5f1e6897f6915a3a940b84bb73 (diff)
downloadmpv-a9cb2e2821adb40e7548e8233390e79706104041.tar.bz2
mpv-a9cb2e2821adb40e7548e8233390e79706104041.tar.xz
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
-rw-r--r--DOCS/interface-changes.rst3
-rw-r--r--DOCS/man/options.rst28
-rw-r--r--meson.build6
-rw-r--r--video/out/gpu/video.c44
-rw-r--r--video/out/gpu/video.h5
-rw-r--r--video/out/gpu/video_shaders.c5
-rw-r--r--video/out/vo_gpu_next.c33
7 files changed, 90 insertions, 34 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index e8ad97cd55..2c59f0f6b5 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -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
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 000e9185e5..6742ec1a6c 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -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
diff --git a/meson.build b/meson.build
index 407fd1ddea..a04fda3172 100644
--- a/meson.build
+++ b/meson.build
@@ -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
diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c
index 841cf36db4..32049f584c 100644
--- a/video/out/gpu/video.c
+++ b/video/out/gpu/video.c
@@ -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;
diff --git a/video/out/gpu/video.h b/video/out/gpu/video.h
index dd16744778..13285bfce1 100644
--- a/video/out/gpu/video.h
+++ b/video/out/gpu/video.h
@@ -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;
diff --git a/video/out/gpu/video_shaders.c b/video/out/gpu/video_shaders.c
index df379778fc..d7774a61e5 100644
--- a/video/out/gpu/video_shaders.c
+++ b/video/out/gpu/video_shaders.c
@@ -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;
diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c
index fd4fd82b58..16ce51279a 100644
--- a/video/out/vo_gpu_next.c
+++ b/video/out/vo_gpu_next.c
@@ -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: