diff options
author | Niklas Haas <git@nand.wakku.to> | 2016-05-16 02:44:30 +0200 |
---|---|---|
committer | Niklas Haas <git@nand.wakku.to> | 2016-05-16 02:49:49 +0200 |
commit | e047cc0931a22d277d7ccd14588f905d7852f7e0 (patch) | |
tree | 6ad6d88295bf3b7ab045ce6befadd063bec84c81 /video/out/opengl/video.c | |
parent | 3cfe98c6848d888e06e5d402f9100d55ab09d755 (diff) | |
download | mpv-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.c | 17 |
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 |