History

lavfi/vf_libplacebo: update for new tone mapping API

This algorithm has once again been refactored, this time leading to a dropping of the old `tone_mapping_mode` field, to be replaced by a single tunable hybrid mode with configurable strength. We can approximately map the old modes onto the new API for backwards compatibility. Replace deprecated enums by their integer equivalents to safely preserve this API until the next bump.

Niklas Haas committed 3 years ago

Commit 643cf2e1 parent d637f202 files · +33 −50Browse files

Unified · Split

2 files
  1. doc/filters.texi +6 −28
  2. libavfilter/vf_libplacebo.c +27 −22
doc/filters.texi+6−28
@@ -16461,42 +16461,20 @@ For tunable tone mapping functions, this parameter can be used to fine-tune the · 16460 unmodified lines
1646116461 curve behavior. Refer to the documentation of @code{tonemapping}. The default
1646216462 value of @code{0.0} is replaced by the curve's preferred default setting.
1646316463
16464−@item tonemapping_mode
16465−This option determines how the tone mapping function specified by
16466−@code{tonemapping} is applied to the colors in a scene. Possible values are:
16467−@table @samp
16468−@item auto
16469−Automatic selection based on internal heuristics. This is the default.
16470−@item rgb
16471−Apply the function per-channel in the RGB colorspace.
16472−Per-channel tone-mapping in RGB. Guarantees no clipping and heavily desaturates
16473−the output, but distorts the colors quite significantly. Very similar to the
16474−"Hollywood" look and feel.
16475−@item max
16476−Tone-mapping is performed on the brightest component found in the signal. Good
16477−at preserving details in highlights, but has a tendency to crush blacks.
16478−@item hybrid
16479−Tone-map per-channel for highlights and linearly (luma-based) for
16480−midtones/shadows, based on a fixed gamma @code{2.4} coefficient curve.
16481−@item luma
16482−Tone-map linearly on the luma component (CIE Y), and adjust (desaturate) the
16483−chromaticities to compensate using a simple constant factor. This is
16484−essentially the mode used in ITU-R BT.2446 method A.
16485−@end table
16486−
1648716464 @item inverse_tonemapping
1648816465 If enabled, this filter will also attempt stretching SDR signals to fill HDR
1648916466 output color volumes. Disabled by default.
1649016467
16491−@item tonemapping_crosstalk
16492−Extra tone-mapping crosstalk factor, between @code{0.0} and @code{0.3}. This
16493−can help reduce issues tone-mapping certain bright spectral colors. Defaults to
16494−@code{0.04}.
16495−
1649616468 @item tonemapping_lut_size
1649716469 Size of the tone-mapping LUT, between @code{2} and @code{1024}. Defaults to
1649816470 @code{256}. Note that this figure is squared when combined with
1649916471 @code{peak_detect}.
16472+
16473+@item hybrid_mix
16474+If nonzero, this much of the upper range of the tone-mapped result is smoothly
16475+mixed with a per-channel (LMS) tone-mapped version. Helps avoid unnatural
16476+blown-out highlights when tone-mapping very bright, strongly saturated colors.
16477+Defaults to @code{0.2}.
1650016478 @end table
1650116479
1650216480 @subsubsection Dithering
libavfilter/vf_libplacebo.c+27−22
@@ -204,10 +204,9 @@ typedef struct LibplaceboContext { · 203 unmodified lines
204204 int gamut_mode;
205205 int tonemapping;
206206 float tonemapping_param;
207− int tonemapping_mode;
208207 int inverse_tonemapping;
209− float crosstalk;
210208 int tonemapping_lut_size;
209+ float hybrid_mix;
211210
212211 #if FF_API_LIBPLACEBO_OPTS
213212 /* for backwards compatibility */
@@ -217,6 +216,8 @@ typedef struct LibplaceboContext { · 3 unmodified lines
217216 int gamut_clipping;
218217 int force_icc_lut;
219218 int intent;
219+ int tonemapping_mode;
220+ float crosstalk;
220221 #endif
221222
222223 /* pl_dither_params */
@@ -359,24 +360,23 @@ static int update_settings(AVFilterContext *ctx) · 136 unmodified lines
359360 {
360361 int err = 0;
361362 LibplaceboContext *s = ctx->priv;
362− enum pl_tone_map_mode tonemapping_mode = s->tonemapping_mode;
363363 int gamut_mode = s->gamut_mode;
364+ float hybrid_mix = s->hybrid_mix;
364365 uint8_t color_rgba[4];
365366
366367 RET(av_parse_color(color_rgba, s->fillcolor, -1, s));
367368
368369 #if FF_API_LIBPLACEBO_OPTS
369370 /* backwards compatibility with older API */
370− if (!tonemapping_mode && (s->desat_str >= 0.0f || s->desat_exp >= 0.0f)) {
371− float str = s->desat_str < 0.0f ? 0.9f : s->desat_str;
372− float exp = s->desat_exp < 0.0f ? 0.2f : s->desat_exp;
373− if (str >= 0.9f && exp <= 0.1f) {
374− tonemapping_mode = PL_TONE_MAP_RGB;
375− } else if (str > 0.1f) {
376− tonemapping_mode = PL_TONE_MAP_HYBRID;
377− } else {
378− tonemapping_mode = PL_TONE_MAP_LUMA;
379− }
371+ switch (s->tonemapping_mode) {
372+ case 0: /*PL_TONE_MAP_AUTO*/
373+ if (s->desat_str >= 0.0f)
374+ hybrid_mix = s->desat_str;
375+ break;
376+ case 1: /*PL_TONE_MAP_RGB*/ hybrid_mix = 1.0f; break;
377+ case 2: /*PL_TONE_MAP_HYBRID*/ hybrid_mix = 0.2f; break;
378+ case 3: /*PL_TONE_MAP_LUMA*/ hybrid_mix = 0.0f; break;
379+ case 4: /*PL_TONE_MAP_MAX*/ hybrid_mix = 0.0f; break;
380380 }
381381
382382 switch (s->intent) {
@@ -415,11 +415,15 @@ static int update_settings(AVFilterContext *ctx) · 32 unmodified lines
415415 );
416416
417417 s->color_map_params = *pl_color_map_params(
418+#if PL_API_VER >= 269
419+ .hybrid_mix = hybrid_mix,
420+#elif FF_API_LIBPLACEBO_OPTS
421+ .tone_mapping_mode = s->tonemapping_mode,
422+ .tone_mapping_crosstalk = s->crosstalk,
423+#endif
418424 .tone_mapping_function = pl_get_tonemapping_func(s->tonemapping),
419425 .tone_mapping_param = s->tonemapping_param,
420− .tone_mapping_mode = tonemapping_mode,
421426 .inverse_tone_mapping = s->inverse_tonemapping,
422− .tone_mapping_crosstalk = s->crosstalk,
423427 .lut_size = s->tonemapping_lut_size,
424428 );
425429
@@ -1228,15 +1232,9 @@ static const AVOption libplacebo_options[] = { · 802 unmodified lines
12281232 { "gamma", "Gamma function with knee", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_GAMMA}, 0, 0, STATIC, "tonemap" },
12291233 { "linear", "Perceptually linear stretch", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_LINEAR}, 0, 0, STATIC, "tonemap" },
12301234 { "tonemapping_param", "Tunable parameter for some tone-mapping functions", OFFSET(tonemapping_param), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 100.0, .flags = DYNAMIC },
1231− { "tonemapping_mode", "Tone-mapping mode", OFFSET(tonemapping_mode), AV_OPT_TYPE_INT, {.i64 = PL_TONE_MAP_AUTO}, 0, PL_TONE_MAP_MODE_COUNT - 1, DYNAMIC, "tonemap_mode" },
1232− { "auto", "Automatic selection", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_AUTO}, 0, 0, STATIC, "tonemap_mode" },
1233− { "rgb", "Per-channel (RGB)", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_RGB}, 0, 0, STATIC, "tonemap_mode" },
1234− { "max", "Maximum component", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_MAX}, 0, 0, STATIC, "tonemap_mode" },
1235− { "hybrid", "Hybrid of Luma/RGB", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_HYBRID}, 0, 0, STATIC, "tonemap_mode" },
1236− { "luma", "Luminance", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_LUMA}, 0, 0, STATIC, "tonemap_mode" },
12371235 { "inverse_tonemapping", "Inverse tone mapping (range expansion)", OFFSET(inverse_tonemapping), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
1238− { "tonemapping_crosstalk", "Crosstalk factor for tone-mapping", OFFSET(crosstalk), AV_OPT_TYPE_FLOAT, {.dbl = 0.04}, 0.0, 0.30, DYNAMIC },
12391236 { "tonemapping_lut_size", "Tone-mapping LUT size", OFFSET(tonemapping_lut_size), AV_OPT_TYPE_INT, {.i64 = 256}, 2, 1024, DYNAMIC },
1237+ { "hybrid_mix", "Tone-mapping hybrid LMS mixing coefficient", OFFSET(hybrid_mix), AV_OPT_TYPE_FLOAT, {.dbl = 0.20}, 0.0, 1.00, DYNAMIC },
12401238
12411239 #if FF_API_LIBPLACEBO_OPTS
12421240 /* deprecated options for backwards compatibility, defaulting to -1 to not override the new defaults */
@@ -1249,6 +1247,13 @@ static const AVOption libplacebo_options[] = { · 6 unmodified lines
12491247 { "relative", "Relative colorimetric", 0, AV_OPT_TYPE_CONST, {.i64 = PL_INTENT_RELATIVE_COLORIMETRIC}, 0, 0, STATIC, "intent" },
12501248 { "absolute", "Absolute colorimetric", 0, AV_OPT_TYPE_CONST, {.i64 = PL_INTENT_ABSOLUTE_COLORIMETRIC}, 0, 0, STATIC, "intent" },
12511249 { "saturation", "Saturation mapping", 0, AV_OPT_TYPE_CONST, {.i64 = PL_INTENT_SATURATION}, 0, 0, STATIC, "intent" },
1250+ { "tonemapping_mode", "Tone-mapping mode", OFFSET(tonemapping_mode), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 4, DYNAMIC | AV_OPT_FLAG_DEPRECATED, "tonemap_mode" },
1251+ { "auto", "Automatic selection", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, STATIC, "tonemap_mode" },
1252+ { "rgb", "Per-channel (RGB)", 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, STATIC, "tonemap_mode" },
1253+ { "max", "Maximum component", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, STATIC, "tonemap_mode" },
1254+ { "hybrid", "Hybrid of Luma/RGB", 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, STATIC, "tonemap_mode" },
1255+ { "luma", "Luminance", 0, AV_OPT_TYPE_CONST, {.i64 = 4}, 0, 0, STATIC, "tonemap_mode" },
1256+ { "tonemapping_crosstalk", "Crosstalk factor for tone-mapping", OFFSET(crosstalk), AV_OPT_TYPE_FLOAT, {.dbl = 0.04}, 0.0, 0.30, DYNAMIC | AV_OPT_FLAG_DEPRECATED },
12521257 #endif
12531258
12541259 { "dithering", "Dither method to use", OFFSET(dithering), AV_OPT_TYPE_INT, {.i64 = PL_DITHER_BLUE_NOISE}, -1, PL_DITHER_METHOD_COUNT - 1, DYNAMIC, "dither" },

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t