0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 12:02:23 +02:00

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.
This commit is contained in:
Niklas Haas 2018-05-23 16:52:40 +02:00 committed by Jan Ekström
parent cb52cfae1a
commit 5056777b86

View File

@ -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);