summaryrefslogtreecommitdiffstats
path: root/video/out/gpu
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.xyz>2018-05-23 16:52:40 +0200
committerJan Ekström <jeebjp@gmail.com>2018-05-31 03:13:50 +0300
commit5056777b861230abb45c66b50bd2198846915f29 (patch)
tree3643729629aa2c4fc988efd9d0b73bb4c35278b3 /video/out/gpu
parentcb52cfae1aa7e29de08c69780a773548f708f972 (diff)
downloadmpv-5056777b861230abb45c66b50bd2198846915f29.tar.bz2
mpv-5056777b861230abb45c66b50bd2198846915f29.tar.xz
vo_gpu: desaturate after peak detection
This sacrifices some dynamic range for well-behaved sources, but prevents catastrophic desaturation on badly mastered / too bright sources. I think that's the better trade-off. This makes the desaturation algorithm much "safer" to deploy by default, as well. One could even argue going up to strength 1.0, which works better for some sources but worse for others. But I think the current strength is the best trade-off even after this change.
Diffstat (limited to 'video/out/gpu')
-rw-r--r--video/out/gpu/video_shaders.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/video/out/gpu/video_shaders.c b/video/out/gpu/video_shaders.c
index 19fb0ccde8..2b18d172db 100644
--- a/video/out/gpu/video_shaders.c
+++ b/video/out/gpu/video_shaders.c
@@ -655,18 +655,6 @@ static void pass_tone_map(struct gl_shader_cache *sc, bool detect_peak,
GLSLF("float sig_peak = %f;\n", src_peak);
GLSLF("float sig_avg = %f;\n", sdr_avg);
- // Desaturate the color using a coefficient dependent on the signal
- // Do this before peak detection in order to try and reclaim as much
- // dynamic range as possible.
- if (desat > 0) {
- float base = 0.18 * dst_peak;
- GLSL(float luma = dot(dst_luma, color.rgb);)
- GLSLF("float coeff = max(sig - %f, 1e-6) / max(sig, 1e-6);\n", base);
- GLSLF("coeff = pow(coeff, %f);\n", 10.0 / desat);
- GLSL(color.rgb = mix(color.rgb, vec3(luma), coeff);)
- GLSL(sig = mix(sig, luma, coeff);) // also make sure to update `sig`
- }
-
if (detect_peak)
hdr_update_peak(sc);
@@ -683,6 +671,18 @@ static void pass_tone_map(struct gl_shader_cache *sc, bool detect_peak,
GLSL(sig *= slope;)
GLSL(sig_peak *= slope;)
+ // Desaturate the color using a coefficient dependent on the signal.
+ // Do this after peak detection in order to prevent over-desaturating
+ // overly bright souces
+ if (desat > 0) {
+ float base = 0.18 * dst_peak;
+ GLSL(float luma = dot(dst_luma, color.rgb);)
+ GLSLF("float coeff = max(sig - %f, 1e-6) / max(sig, 1e-6);\n", base);
+ GLSLF("coeff = pow(coeff, %f);\n", 10.0 / desat);
+ GLSL(color.rgb = mix(color.rgb, vec3(luma), coeff);)
+ GLSL(sig = mix(sig, luma * slope, coeff);) // also make sure to update `sig`
+ }
+
switch (algo) {
case TONE_MAPPING_CLIP:
GLSLF("sig = %f * sig;\n", isnan(param) ? 1.0 : param);