From: mirs <fangpengch...@bilibili.com> Signed-off-by: mirs <fangpengch...@bilibili.com>
add tonemapping hermite,this looks close real hdr display format patch email --- libavfilter/vf_tonemap.c | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/libavfilter/vf_tonemap.c b/libavfilter/vf_tonemap.c index d1087e6bd9..3fb2bdfa2c 100644 --- a/libavfilter/vf_tonemap.c +++ b/libavfilter/vf_tonemap.c @@ -48,6 +48,7 @@ enum TonemapAlgorithm { TONEMAP_REINHARD, TONEMAP_HABLE, TONEMAP_MOBIUS, + TONEMAP_HERMITE, TONEMAP_MAX, }; @@ -106,6 +107,66 @@ static float mobius(float in, float j, double peak) return (b * b + 2.0f * b * j + j * j) / (b - a) * (in + a) / (in + b); } +static float hermite(float in) { + /* + * in theory, max mastering lumi 、max content lumi frome packet side data, + * display max lumi from Display system value,current value is R-REP-BT.2390 max value + */ + float max_mastering_lumi = 1000.0f; + float max_content_lumi = 1000.0f; + float display_max_lumi = 400.0f; // Terminal domain 400NITS is the maximum lumen of a normal screen + + float max_in_lumi = FFMAX(max_mastering_lumi,max_content_lumi); + float max_out_lumi = display_max_lumi; + float nits = in * (display_max_lumi / max_mastering_lumi); + + // clamp + if (nits < 0) { + nits = 0.0; + } else if (nits > max_in_lumi) { + nits = max_in_lumi; + } + + if (max_in_lumi <= max_out_lumi) { + nits *= max_out_lumi / max_in_lumi; + } else { + // three control points + const float x0 = 10.0f; + const float y0 = 17.0; + float x1 = max_out_lumi * 0.75; + float y1 = x1; + float x2 = x1 + (max_in_lumi - x1) / 2.0; + float y2 = y1 + (max_out_lumi - y1) * 0.75; + // horizontal distances between the last three control points + float h12 = x2 - x1; + float h23 = max_in_lumi - x2; + // tangents at the last three control points + float m1 = (y2 - y1) / h12; + float m3 = (max_out_lumi - y2) / h23; + float m2 = (m1 + m3) / 2.0; + + if (nits < x0) { + // scale [0.0, x0] to [0.0, y0] linearly + float slope = y0 / x0; + nits *= slope; + } else if (nits < x1) { + // scale [x0, x1] to [y0, y1] linearly + float slope = (y1 - y0) / (x1 - x0); + nits = y0 + (nits - x0) * slope; + } else if (nits < x2) { + // scale [x1, x2] to [y1, y2] using Hermite interp + float t = (nits - x1) / h12; + nits = (y1 * (1.0 + 2.0 * t) + h12 * m1 * t) * (1.0 - t) * (1.0 - t) +(y2 * (3.0 - 2.0 * t) + h12 * m2 * (t - 1.0)) * t * t; + } else { + // scale [x2, maxInLumi] to [y2, maxOutLumi] using Hermite interp + float t = (nits - x2) / h23; + nits = (y2 * (1.0 + 2.0 * t) + h23 * m2 * t) * (1.0 - t) * (1.0 - t) +(max_out_lumi * (3.0 - 2.0 * t) + h23 * m3 * (t - 1.0)) * t * t; + } + } + + return nits; +} + #define MIX(x,y,a) (x) * (1 - (a)) + (y) * (a) static void tonemap(TonemapContext *s, AVFrame *out, const AVFrame *in, const AVPixFmtDescriptor *desc, int x, int y, double peak) @@ -163,6 +224,9 @@ static void tonemap(TonemapContext *s, AVFrame *out, const AVFrame *in, case TONEMAP_MOBIUS: sig = mobius(sig, s->param, peak); break; + case TONEMAP_HERMITE: + sig = hermite(sig); + break; } /* apply the computed scale factor to the color, @@ -291,6 +355,7 @@ static const AVOption tonemap_options[] = { { "reinhard", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_REINHARD}, 0, 0, FLAGS, "tonemap" }, { "hable", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_HABLE}, 0, 0, FLAGS, "tonemap" }, { "mobius", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_MOBIUS}, 0, 0, FLAGS, "tonemap" }, + { "hermite", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_HERMITE}, 0, 0, FLAGS, "tonemap" }, { "param", "tonemap parameter", OFFSET(param), AV_OPT_TYPE_DOUBLE, {.dbl = NAN}, DBL_MIN, DBL_MAX, FLAGS }, { "desat", "desaturation strength", OFFSET(desat), AV_OPT_TYPE_DOUBLE, {.dbl = 2}, 0, DBL_MAX, FLAGS }, { "peak", "signal peak override", OFFSET(peak), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, 0, DBL_MAX, FLAGS }, -- 2.32.1 (Apple Git-133) _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".