On Mon, 21 May 2018 14:50:17 +0800, Ruiling Song <ruiling.s...@intel.com> wrote: > +float3 map_one_pixel_rgb(float3 rgb, float peak, float average) { > + float sig = max(max(rgb.x, max(rgb.y, rgb.z)), 1e-6f); > + // de-saturate > + if (desat_param > 0.0f) { > + float luma = get_luma_dst(rgb); > + float base = 0.18f * dst_peak; > + float coeff = max(sig - base, 1e-6f) / max(sig, 1e-6f); > + coeff = native_powr(coeff, 10.0f / desat_param); > + rgb = mix(rgb, (float3)luma, (float3)coeff); > + sig = mix(sig, luma, coeff); > + } > + > + float sig_old = sig; > + float slope = min(1.0f, sdr_avg / average); > + sig *= slope; > + peak *= slope; > + > + sig = TONE_FUNC(sig, peak); > + rgb *= (sig/sig_old); > + return rgb;
Actually a better way to do this is to swap the order of the `slope` adjustment and the desaturation step. This prevents a problematic case where very bright (badly mastered) sources ended up getting too aggressively desaturated. Some care needs to be taken when swapping the order in order to scale the multiplication in the correct way. This should work: float3 map_one_pixel_rgb(float3 rgb, float peak, float average) { float sig = max(max(rgb.x, max(rgb.y, rgb.z)), 1e-6f); float sig_old = sig; float slope = min(1.0f, sdr_avg / average); sig *= slope; peak *= slope; // de-saturate if (desat_param > 0.0f) { float luma = get_luma_dst(rgb); float base = 0.18f * dst_peak; float coeff = max(sig - base, 1e-6f) / max(sig, 1e-6f); coeff = native_powr(coeff, 10.0f / desat_param); rgb = mix(rgb, (float3)luma, (float3)coeff); sig = mix(sig, luma * slope, coeff); } sig = TONE_FUNC(sig, peak); rgb *= (sig/sig_old); return rgb; I found out about this while testing some pathological HLG sources earlier today. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel