summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/out/opengl/video.c9
-rw-r--r--video/out/opengl/video.h2
-rw-r--r--video/out/opengl/video_shaders.c29
3 files changed, 23 insertions, 17 deletions
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index 5ecf80b450..0cd7ef3688 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -326,7 +326,7 @@ static const struct gl_video_opts gl_video_opts_def = {
.alpha_mode = ALPHA_BLEND_TILES,
.background = {0, 0, 0, 255},
.gamma = 1.0f,
- .hdr_tone_mapping = TONE_MAPPING_MOBIUS,
+ .tone_mapping = TONE_MAPPING_MOBIUS,
.tone_mapping_param = NAN,
.tone_mapping_desat = 2.0,
.early_flush = -1,
@@ -363,7 +363,7 @@ const struct m_sub_options gl_video_conf = {
OPT_FLAG("gamma-auto", gamma_auto, 0),
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_CHOICE("hdr-tone-mapping", hdr_tone_mapping, 0,
+ OPT_CHOICE("tone-mapping", tone_mapping, 0,
({"clip", TONE_MAPPING_CLIP},
{"mobius", TONE_MAPPING_MOBIUS},
{"reinhard", TONE_MAPPING_REINHARD},
@@ -431,6 +431,7 @@ const struct m_sub_options gl_video_conf = {
OPT_CHOICE("opengl-early-flush", early_flush, 0,
({"no", 0}, {"yes", 1}, {"auto", -1})),
OPT_STRING("opengl-shader-cache-dir", shader_cache_dir, 0),
+ OPT_REPLACED("hdr-tone-mapping", "tone-mapping"),
{0}
},
.size = sizeof(struct gl_video_opts),
@@ -2537,7 +2538,7 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool
}
// Adapt from src to dst as necessary
- pass_color_map(p->sc, src, dst, p->opts.hdr_tone_mapping,
+ pass_color_map(p->sc, src, dst, p->opts.tone_mapping,
p->opts.tone_mapping_param, p->opts.tone_mapping_desat,
detect_peak, p->use_linear && !osd);
@@ -3499,7 +3500,7 @@ static void check_gl_features(struct gl_video *p)
.temporal_dither_period = p->opts.temporal_dither_period,
.tex_pad_x = p->opts.tex_pad_x,
.tex_pad_y = p->opts.tex_pad_y,
- .hdr_tone_mapping = p->opts.hdr_tone_mapping,
+ .tone_mapping = p->opts.tone_mapping,
.tone_mapping_param = p->opts.tone_mapping_param,
.tone_mapping_desat = p->opts.tone_mapping_desat,
.early_flush = p->opts.early_flush,
diff --git a/video/out/opengl/video.h b/video/out/opengl/video.h
index 5b50cdd3f2..d74f3cf576 100644
--- a/video/out/opengl/video.h
+++ b/video/out/opengl/video.h
@@ -110,7 +110,7 @@ struct gl_video_opts {
int target_prim;
int target_trc;
int target_brightness;
- int hdr_tone_mapping;
+ int tone_mapping;
int compute_hdr_peak;
float tone_mapping_param;
float tone_mapping_desat;
diff --git a/video/out/opengl/video_shaders.c b/video/out/opengl/video_shaders.c
index 4708187580..a8170c10d1 100644
--- a/video/out/opengl/video_shaders.c
+++ b/video/out/opengl/video_shaders.c
@@ -577,7 +577,7 @@ static void pass_tone_map(struct gl_shader_cache *sc, float ref_peak,
GLSLF("// HDR tone mapping\n");
// Desaturate the color using a coefficient dependent on the luminance
- GLSL(float luma = dot(src_luma, color.rgb);)
+ GLSL(float luma = dot(dst_luma, color.rgb);)
if (desat > 0) {
GLSLF("float overbright = max(luma - %f, 1e-6) / max(luma, 1e-6);\n", desat);
GLSL(color.rgb = mix(color.rgb, vec3(luma), overbright);)
@@ -699,13 +699,15 @@ void pass_color_map(struct gl_shader_cache *sc,
// Compute the highest encodable level
float src_range = mp_trc_nom_peak(src.gamma),
dst_range = mp_trc_nom_peak(dst.gamma);
+ float ref_peak = src.sig_peak / dst_range;
- // Some operations need access to the video's luma coefficients (src
- // colorspace), so make it available
- struct mp_csp_primaries prim = mp_get_csp_primaries(src.primaries);
+ // Some operations need access to the video's luma coefficients, so make
+ // them available
float rgb2xyz[3][3];
- mp_get_rgb2xyz_matrix(prim, rgb2xyz);
+ mp_get_rgb2xyz_matrix(mp_get_csp_primaries(src.primaries), rgb2xyz);
gl_sc_uniform_vec3(sc, "src_luma", rgb2xyz[1]);
+ mp_get_rgb2xyz_matrix(mp_get_csp_primaries(dst.primaries), rgb2xyz);
+ gl_sc_uniform_vec3(sc, "dst_luma", rgb2xyz[1]);
// All operations from here on require linear light as a starting point,
// so we linearize even if src.gamma == dst.gamma when one of the other
@@ -732,13 +734,6 @@ void pass_color_map(struct gl_shader_cache *sc,
GLSLF("color.rgb *= vec3(%f);\n", src_range / dst_range);
}
- // Tone map to prevent clipping when the source signal peak exceeds the
- // encodable range
- if (src.sig_peak > dst_range) {
- float ref_peak = detect_peak ? 0 : src.sig_peak / dst_range;
- pass_tone_map(sc, ref_peak, algo, tone_mapping_param, tone_mapping_desat);
- }
-
// Adapt to the right colorspace if necessary
if (src.primaries != dst.primaries) {
struct mp_csp_primaries csp_src = mp_get_csp_primaries(src.primaries),
@@ -747,6 +742,16 @@ void pass_color_map(struct gl_shader_cache *sc,
mp_get_cms_matrix(csp_src, csp_dst, MP_INTENT_RELATIVE_COLORIMETRIC, m);
gl_sc_uniform_mat3(sc, "cms_matrix", true, &m[0][0]);
GLSL(color.rgb = cms_matrix * color.rgb;)
+ // Since this can reduce the gamut, figure out by how much
+ for (int c = 0; c < 3; c++)
+ ref_peak = MPMAX(ref_peak, m[c][c]);
+ }
+
+ // Tone map to prevent clipping when the source signal peak exceeds the
+ // encodable range or we've reduced the gamut
+ if (ref_peak > 1) {
+ pass_tone_map(sc, detect_peak ? 0 : ref_peak, algo,
+ tone_mapping_param, tone_mapping_desat);
}
if (src.light != dst.light)