hermite hava more light and more details for others [image: 41662642193_.pic.jpg] 于2022年9月8日周四 20:42写道: > From: mirs > > Signed-off-by: mirs > > add tonemapping hermite,this looks close real hdr display > > --- > 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) > >