Skip to content

Commit

Permalink
vo_gpu: desaturate after peak detection
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
haasn authored and jeeb committed May 31, 2018
1 parent cb52cfa commit 5056777
Showing 1 changed file with 12 additions and 12 deletions.
24 changes: 12 additions & 12 deletions video/out/gpu/video_shaders.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand Down

0 comments on commit 5056777

Please sign in to comment.