summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/video.c
diff options
context:
space:
mode:
authorNiklas Haas <git@nand.wakku.to>2016-05-16 02:44:30 +0200
committerNiklas Haas <git@nand.wakku.to>2016-05-16 02:49:49 +0200
commite047cc0931a22d277d7ccd14588f905d7852f7e0 (patch)
tree6ad6d88295bf3b7ab045ce6befadd063bec84c81 /video/out/opengl/video.c
parent3cfe98c6848d888e06e5d402f9100d55ab09d755 (diff)
downloadmpv-e047cc0931a22d277d7ccd14588f905d7852f7e0.tar.bz2
mpv-e047cc0931a22d277d7ccd14588f905d7852f7e0.tar.xz
vo_opengl: implement more HDR tonemapping algorithms
This is now a configurable option, with tunable parameters. I got inspiration for these algorithms off wikipedia. "simple" seems to work pretty well, but not well enough to make it a reasonable default. Some other notable candidates: - Local functions (e.g. based on local contrast or gradient) - Clamp with soft knee (linear up to a point) - Mapping in CIE L*Ch. Map L smoothly, clamp C and h. - Color appearance models These will have to be implemented some other time. Note that the parameter "peak_src" to pass_tone_map should, in principle, be auto-detected from the SEI information of the source file where available. This will also have to be implemented in a later commit.
Diffstat (limited to 'video/out/opengl/video.c')
-rw-r--r--video/out/opengl/video.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index 7470f9668d..7224e1af22 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -321,6 +321,7 @@ const struct gl_video_opts gl_video_opts_def = {
.prescale_passes = 1,
.prescale_downscaling_threshold = 2.0f,
.target_brightness = 250,
+ .tone_mapping_param = NAN,
};
const struct gl_video_opts gl_video_opts_hq_def = {
@@ -350,6 +351,7 @@ const struct gl_video_opts gl_video_opts_hq_def = {
.prescale_passes = 1,
.prescale_downscaling_threshold = 2.0f,
.target_brightness = 250,
+ .tone_mapping_param = NAN,
};
static int validate_scaler_opt(struct mp_log *log, const m_option_t *opt,
@@ -379,6 +381,12 @@ const struct m_sub_options gl_video_conf = {
OPT_CHOICE_C("target-prim", target_prim, 0, mp_csp_prim_names),
OPT_CHOICE_C("target-trc", target_trc, 0, mp_csp_trc_names),
OPT_INTRANGE("target-brightness", target_brightness, 0, 1, 100000),
+ OPT_CHOICE("hdr-tone-mapping", hdr_tone_mapping, 0,
+ ({"clip", TONE_MAPPING_CLIP},
+ {"simple", TONE_MAPPING_SIMPLE},
+ {"gamma", TONE_MAPPING_GAMMA},
+ {"linear", TONE_MAPPING_LINEAR})),
+ OPT_FLOAT("tone-mapping-param", tone_mapping_param, 0),
OPT_FLAG("pbo", pbo, 0),
SCALER_OPTS("scale", SCALER_SCALE),
SCALER_OPTS("dscale", SCALER_DSCALE),
@@ -2249,12 +2257,13 @@ static void pass_colormanage(struct gl_video *p, bool display_scaled,
pass_linearize(p->sc, trc_src);
// For HDR, the assumption of reference brightness = display brightness
- // is discontinued. Instead, we have to rescale the brightness to match
- // the display (and clip out-of-range values)
+ // is discontinued. Instead, we have to tone map the brightness to
+ // the display using some algorithm.
if (p->image_params.gamma == MP_CSP_TRC_SMPTE_ST2084 && !display_scaled) {
+ GLSLF("// HDR tone mapping\n");
int reference_brightness = 10000; // As per SMPTE ST.2084
- GLSLF("color.rgb = clamp(%f * color.rgb, 0.0, 1.0);\n",
- (float)reference_brightness / p->opts.target_brightness);
+ pass_tone_map(p->sc, reference_brightness, p->opts.target_brightness,
+ p->opts.hdr_tone_mapping, p->opts.tone_mapping_param);
}
// Adapt to the right colorspace if necessary