From: Niklas Haas <ffmpeg@haasn.xyz>
To: ffmpeg-devel@ffmpeg.org
Cc: Niklas Haas <git@haasn.dev>
Subject: Re: [FFmpeg-devel] [PATCH v2] avfilter/vf_libplacebo: update for new tone mapping API
Date: Thu, 31 Mar 2022 13:25:15 +0200
Message-ID: <20220331132515.GB113776@haasn.xyz> (raw)
In-Reply-To: <20220325151118.42130-1-ffmpeg@haasn.xyz>
Applied as e301a24fa191ad19574289b765ff1946b23c03f3
On Fri, 25 Mar 2022 16:11:19 +0100 Niklas Haas <ffmpeg@haasn.xyz> wrote:
> From: Niklas Haas <git@haasn.dev>
>
> Upstream gained a new tone-mapping API, which we never switched to. We
> don't need a version bump for this because it was included as part of
> the v4.192 release we currently already depend on.
>
> Some of the old options can be moderately approximated with the new API,
> but specifically "desaturation_base" and "max_boost" cannot. Remove
> these entirely, rather than deprecating them. They have actually been
> non-functional for a while as a result of the upstream deprecation.
>
> Signed-off-by: Niklas Haas <git@haasn.dev>
> ---
> Changes in v2:
> - Avoid use of strings in favor of replicating the enum values
> - Fix two wrong enum option value ranges
> - Simplify the option setting code again slightly
> ---
> libavfilter/vf_libplacebo.c | 112 ++++++++++++++++++++++++++++--------
> 1 file changed, 89 insertions(+), 23 deletions(-)
>
> diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
> index 31ae28ac38..8ce6462c66 100644
> --- a/libavfilter/vf_libplacebo.c
> +++ b/libavfilter/vf_libplacebo.c
> @@ -26,6 +26,33 @@
> #include <libplacebo/utils/libav.h>
> #include <libplacebo/vulkan.h>
>
> +enum {
> + TONE_MAP_AUTO,
> + TONE_MAP_CLIP,
> + TONE_MAP_BT2390,
> + TONE_MAP_BT2446A,
> + TONE_MAP_SPLINE,
> + TONE_MAP_REINHARD,
> + TONE_MAP_MOBIUS,
> + TONE_MAP_HABLE,
> + TONE_MAP_GAMMA,
> + TONE_MAP_LINEAR,
> + TONE_MAP_COUNT,
> +};
> +
> +static const struct pl_tone_map_function * const tonemapping_funcs[TONE_MAP_COUNT] = {
> + [TONE_MAP_AUTO] = &pl_tone_map_auto,
> + [TONE_MAP_CLIP] = &pl_tone_map_clip,
> + [TONE_MAP_BT2390] = &pl_tone_map_bt2390,
> + [TONE_MAP_BT2446A] = &pl_tone_map_bt2446a,
> + [TONE_MAP_SPLINE] = &pl_tone_map_spline,
> + [TONE_MAP_REINHARD] = &pl_tone_map_reinhard,
> + [TONE_MAP_MOBIUS] = &pl_tone_map_mobius,
> + [TONE_MAP_HABLE] = &pl_tone_map_hable,
> + [TONE_MAP_GAMMA] = &pl_tone_map_gamma,
> + [TONE_MAP_LINEAR] = &pl_tone_map_linear,
> +};
> +
> typedef struct LibplaceboContext {
> /* lavfi vulkan*/
> FFVulkanContext vkctx;
> @@ -91,12 +118,16 @@ typedef struct LibplaceboContext {
>
> /* pl_color_map_params */
> int intent;
> + int gamut_mode;
> int tonemapping;
> float tonemapping_param;
> + int tonemapping_mode;
> + int inverse_tonemapping;
> + float crosstalk;
> + int tonemapping_lut_size;
> + /* for backwards compatibility */
> float desat_str;
> float desat_exp;
> - float desat_base;
> - float max_boost;
> int gamut_warning;
> int gamut_clipping;
>
> @@ -281,6 +312,8 @@ static int process_frames(AVFilterContext *avctx, AVFrame *out, AVFrame *in)
> int err = 0, ok;
> LibplaceboContext *s = avctx->priv;
> struct pl_render_params params;
> + enum pl_tone_map_mode tonemapping_mode = s->tonemapping_mode;
> + enum pl_gamut_mode gamut_mode = s->gamut_mode;
> struct pl_frame image, target;
> ok = pl_map_avframe_ex(s->gpu, &image, pl_avframe_params(
> .frame = in,
> @@ -305,6 +338,24 @@ static int process_frames(AVFilterContext *avctx, AVFrame *out, AVFrame *in)
> pl_rect2df_aspect_set(&target.crop, aspect, s->pad_crop_ratio);
> }
>
> + /* backwards compatibility with older API */
> + if (!tonemapping_mode && (s->desat_str >= 0.0f || s->desat_exp >= 0.0f)) {
> + float str = s->desat_str < 0.0f ? 0.9f : s->desat_str;
> + float exp = s->desat_exp < 0.0f ? 0.2f : s->desat_exp;
> + if (str >= 0.9f && exp <= 0.1f) {
> + tonemapping_mode = PL_TONE_MAP_RGB;
> + } else if (str > 0.1f) {
> + tonemapping_mode = PL_TONE_MAP_HYBRID;
> + } else {
> + tonemapping_mode = PL_TONE_MAP_LUMA;
> + }
> + }
> +
> + if (s->gamut_warning)
> + gamut_mode = PL_GAMUT_WARN;
> + if (s->gamut_clipping)
> + gamut_mode = PL_GAMUT_DESATURATE;
> +
> /* Update render params */
> params = (struct pl_render_params) {
> PL_RENDER_DEFAULTS
> @@ -338,14 +389,13 @@ static int process_frames(AVFilterContext *avctx, AVFrame *out, AVFrame *in)
>
> .color_map_params = pl_color_map_params(
> .intent = s->intent,
> - .tone_mapping_algo = s->tonemapping,
> + .gamut_mode = gamut_mode,
> + .tone_mapping_function = tonemapping_funcs[s->tonemapping],
> .tone_mapping_param = s->tonemapping_param,
> - .desaturation_strength = s->desat_str,
> - .desaturation_exponent = s->desat_exp,
> - .desaturation_base = s->desat_base,
> - .max_boost = s->max_boost,
> - .gamut_warning = s->gamut_warning,
> - .gamut_clipping = s->gamut_clipping,
> + .tone_mapping_mode = tonemapping_mode,
> + .inverse_tone_mapping = s->inverse_tonemapping,
> + .tone_mapping_crosstalk = s->crosstalk,
> + .lut_size = s->tonemapping_lut_size,
> ),
>
> .dither_params = s->dithering < 0 ? NULL : pl_dither_params(
> @@ -616,21 +666,37 @@ static const AVOption libplacebo_options[] = {
> { "relative", "Relative colorimetric", 0, AV_OPT_TYPE_CONST, {.i64 = PL_INTENT_RELATIVE_COLORIMETRIC}, 0, 0, STATIC, "intent" },
> { "absolute", "Absolute colorimetric", 0, AV_OPT_TYPE_CONST, {.i64 = PL_INTENT_ABSOLUTE_COLORIMETRIC}, 0, 0, STATIC, "intent" },
> { "saturation", "Saturation mapping", 0, AV_OPT_TYPE_CONST, {.i64 = PL_INTENT_SATURATION}, 0, 0, STATIC, "intent" },
> - { "tonemapping", "Tone-mapping algorithm", OFFSET(tonemapping), AV_OPT_TYPE_INT, {.i64 = PL_TONE_MAPPING_BT_2390}, 0, PL_TONE_MAPPING_ALGORITHM_COUNT - 1, DYNAMIC, "tonemap" },
> - { "clip", "Hard-clipping", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAPPING_CLIP}, 0, 0, STATIC, "tonemap" },
> - { "mobius", "Mobius tone-mapping", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAPPING_MOBIUS}, 0, 0, STATIC, "tonemap" },
> - { "reinhard", "Reinhard tone-mapping", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAPPING_REINHARD}, 0, 0, STATIC, "tonemap" },
> - { "hable", "Hable/Filmic tone-mapping", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAPPING_HABLE}, 0, 0, STATIC, "tonemap" },
> - { "gamma", "Gamma tone-mapping", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAPPING_GAMMA}, 0, 0, STATIC, "tonemap" },
> - { "linear", "Linear tone-mapping", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAPPING_LINEAR}, 0, 0, STATIC, "tonemap" },
> - { "bt.2390", "ITU-R BT.2390 tone-mapping", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAPPING_BT_2390}, 0, 0, STATIC, "tonemap" },
> + { "gamut_mode", "Gamut-mapping mode", OFFSET(gamut_mode), AV_OPT_TYPE_INT, {.i64 = PL_GAMUT_CLIP}, 0, PL_GAMUT_MODE_COUNT - 1, DYNAMIC, "gamut_mode" },
> + { "clip", "Hard-clip gamut boundary", 0, AV_OPT_TYPE_CONST, {.i64 = PL_GAMUT_CLIP}, 0, 0, STATIC, "gamut_mode" },
> + { "warn", "Highlight out-of-gamut colors", 0, AV_OPT_TYPE_CONST, {.i64 = PL_GAMUT_WARN}, 0, 0, STATIC, "gamut_mode" },
> + { "darken", "Darken image to fit gamut", 0, AV_OPT_TYPE_CONST, {.i64 = PL_GAMUT_DARKEN}, 0, 0, STATIC, "gamut_mode" },
> + { "desaturate", "Colorimetrically desaturate colors", 0, AV_OPT_TYPE_CONST, {.i64 = PL_GAMUT_DESATURATE}, 0, 0, STATIC, "gamut_mode" },
> + { "tonemapping", "Tone-mapping algorithm", OFFSET(tonemapping), AV_OPT_TYPE_INT, {.i64 = TONE_MAP_AUTO}, 0, TONE_MAP_COUNT - 1, DYNAMIC, "tonemap" },
> + { "auto", "Automatic selection", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_AUTO}, 0, 0, STATIC, "tonemap" },
> + { "clip", "No tone mapping (clip", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_CLIP}, 0, 0, STATIC, "tonemap" },
> + { "bt.2390", "ITU-R BT.2390 EETF", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_BT2390}, 0, 0, STATIC, "tonemap" },
> + { "bt.2446a", "ITU-R BT.2446 Method A", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_BT2446A}, 0, 0, STATIC, "tonemap" },
> + { "spline", "Single-pivot polynomial spline", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_SPLINE}, 0, 0, STATIC, "tonemap" },
> + { "reinhard", "Reinhard", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_REINHARD}, 0, 0, STATIC, "tonemap" },
> + { "mobius", "Mobius", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_MOBIUS}, 0, 0, STATIC, "tonemap" },
> + { "hable", "Filmic tone-mapping (Hable)", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_HABLE}, 0, 0, STATIC, "tonemap" },
> + { "gamma", "Gamma function with knee", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_GAMMA}, 0, 0, STATIC, "tonemap" },
> + { "linear", "Perceptually linear stretch", 0, AV_OPT_TYPE_CONST, {.i64 = TONE_MAP_LINEAR}, 0, 0, STATIC, "tonemap" },
> { "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 },
> - { "desaturation_strength", "Desaturation strength", OFFSET(desat_str), AV_OPT_TYPE_FLOAT, {.dbl = 0.90}, 0.0, 1.0, DYNAMIC },
> - { "desaturation_exponent", "Desaturation exponent", OFFSET(desat_exp), AV_OPT_TYPE_FLOAT, {.dbl = 0.2}, 0.0, 10.0, DYNAMIC },
> - { "desaturation_base", "Desaturation base", OFFSET(desat_base), AV_OPT_TYPE_FLOAT, {.dbl = 0.18}, 0.0, 10.0, DYNAMIC },
> - { "max_boost", "Tone-mapping maximum boost", OFFSET(max_boost), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 1.0, 10.0, DYNAMIC },
> - { "gamut_warning", "Highlight out-of-gamut colors", OFFSET(gamut_warning), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
> - { "gamut_clipping", "Enable colorimetric gamut clipping", OFFSET(gamut_clipping), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
> + { "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" },
> + { "auto", "Automatic selection", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_AUTO}, 0, 0, STATIC, "tonemap_mode" },
> + { "rgb", "Per-channel (RGB)", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_RGB}, 0, 0, STATIC, "tonemap_mode" },
> + { "max", "Maximum component", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_MAX}, 0, 0, STATIC, "tonemap_mode" },
> + { "hybrid", "Hybrid of Luma/RGB", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_HYBRID}, 0, 0, STATIC, "tonemap_mode" },
> + { "luma", "Luminance", 0, AV_OPT_TYPE_CONST, {.i64 = PL_TONE_MAP_LUMA}, 0, 0, STATIC, "tonemap_mode" },
> + { "inverse_tonemapping", "Inverse tone mapping (range expansion)", OFFSET(inverse_tonemapping), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
> + { "tonemapping_crosstalk", "Crosstalk factor for tone-mapping", OFFSET(crosstalk), AV_OPT_TYPE_FLOAT, {.dbl = 0.04}, 0.0, 0.30, DYNAMIC },
> + { "tonemapping_lut_size", "Tone-mapping LUT size", OFFSET(tonemapping_lut_size), AV_OPT_TYPE_INT, {.i64 = 256}, 2, 1024, DYNAMIC },
> + /* deprecated options for backwards compatibility, defaulting to -1 to not override the new defaults */
> + { "desaturation_strength", "Desaturation strength", OFFSET(desat_str), AV_OPT_TYPE_FLOAT, {.dbl = -1.0}, -1.0, 1.0, DYNAMIC | AV_OPT_FLAG_DEPRECATED },
> + { "desaturation_exponent", "Desaturation exponent", OFFSET(desat_exp), AV_OPT_TYPE_FLOAT, {.dbl = -1.0}, -1.0, 10.0, DYNAMIC | AV_OPT_FLAG_DEPRECATED },
> + { "gamut_warning", "Highlight out-of-gamut colors", OFFSET(gamut_warning), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC | AV_OPT_FLAG_DEPRECATED },
> + { "gamut_clipping", "Enable colorimetric gamut clipping", OFFSET(gamut_clipping), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC | AV_OPT_FLAG_DEPRECATED },
>
> { "dithering", "Dither method to use", OFFSET(dithering), AV_OPT_TYPE_INT, {.i64 = PL_DITHER_BLUE_NOISE}, -1, PL_DITHER_METHOD_COUNT - 1, DYNAMIC, "dither" },
> { "none", "Disable dithering", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, STATIC, "dither" },
> --
> 2.35.1
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
prev parent reply other threads:[~2022-03-31 11:25 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-25 12:27 [FFmpeg-devel] [PATCH] " Niklas Haas
2022-03-25 12:50 ` Lynne
2022-03-25 15:11 ` [FFmpeg-devel] [PATCH v2] " Niklas Haas
2022-03-31 11:25 ` Niklas Haas [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220331132515.GB113776@haasn.xyz \
--to=ffmpeg@haasn.xyz \
--cc=ffmpeg-devel@ffmpeg.org \
--cc=git@haasn.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git