From 482d81378fe00e620776e096c75320210efe5fa3 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Fri, 5 May 2023 11:02:34 +0200 Subject: [PATCH] lavfi/vf_libplacebo: update render params on demand Only update this struct when it's expected to change, and cache it otherwise. Partially motivated by a desire to make `process_frames` smaller. --- libavfilter/vf_libplacebo.c | 228 ++++++++++++++++++++---------------- 1 file changed, 126 insertions(+), 102 deletions(-) diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c index 8387f4dd47..9596bed940 100644 --- a/libavfilter/vf_libplacebo.c +++ b/libavfilter/vf_libplacebo.c @@ -143,6 +143,7 @@ typedef struct LibplaceboContext { int color_trc; /* pl_render_params */ + struct pl_render_params params; char *upscaler; char *downscaler; int lut_entries; @@ -156,6 +157,7 @@ typedef struct LibplaceboContext { int disable_fbos; /* pl_deband_params */ + struct pl_deband_params deband_params; int deband; int deband_iterations; float deband_threshold; @@ -163,6 +165,7 @@ typedef struct LibplaceboContext { float deband_grain; /* pl_color_adjustment */ + struct pl_color_adjustment color_adjustment; float brightness; float contrast; float saturation; @@ -170,6 +173,7 @@ typedef struct LibplaceboContext { float gamma; /* pl_peak_detect_params */ + struct pl_peak_detect_params peak_detect_params; int peakdetect; float smoothing; float min_peak; @@ -178,6 +182,7 @@ typedef struct LibplaceboContext { float overshoot; /* pl_color_map_params */ + struct pl_color_map_params color_map_params; int intent; int gamut_mode; int tonemapping; @@ -196,12 +201,14 @@ typedef struct LibplaceboContext { int force_icc_lut; #endif - /* pl_dither_params */ + /* pl_dither_params */ + struct pl_dither_params dither_params; int dithering; int dither_lut_size; int dither_temporal; /* pl_cone_params */ + struct pl_cone_params cone_params; int cones; float cone_str; @@ -280,18 +287,112 @@ static int find_scaler(AVFilterContext *avctx, return AVERROR(EINVAL); } -static int parse_fillcolor(AVFilterContext *avctx, - struct pl_render_params *params, - const char *color_str) +static int update_settings(AVFilterContext *ctx) { int err = 0; + LibplaceboContext *s = ctx->priv; + enum pl_tone_map_mode tonemapping_mode = s->tonemapping_mode; + enum pl_gamut_mode gamut_mode = s->gamut_mode; uint8_t color_rgba[4]; - RET(av_parse_color(color_rgba, color_str, -1, avctx)); - params->background_color[0] = (float) color_rgba[0] / UINT8_MAX; - params->background_color[1] = (float) color_rgba[1] / UINT8_MAX; - params->background_color[2] = (float) color_rgba[2] / UINT8_MAX; - params->background_transparency = 1.0f - (float) color_rgba[3] / UINT8_MAX; + RET(av_parse_color(color_rgba, s->fillcolor, -1, s)); + +#if FF_API_LIBPLACEBO_OPTS + /* 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; +#endif + + s->deband_params = *pl_deband_params( + .iterations = s->deband_iterations, + .threshold = s->deband_threshold, + .radius = s->deband_radius, + .grain = s->deband_grain, + ); + + s->color_adjustment = (struct pl_color_adjustment) { + .brightness = s->brightness, + .contrast = s->contrast, + .saturation = s->saturation, + .hue = s->hue, + .gamma = s->gamma, + }; + + s->peak_detect_params = *pl_peak_detect_params( + .smoothing_period = s->smoothing, + .minimum_peak = s->min_peak, + .scene_threshold_low = s->scene_low, + .scene_threshold_high = s->scene_high, + .overshoot_margin = s->overshoot, + ); + + s->color_map_params = *pl_color_map_params( + .intent = s->intent, + .gamut_mode = gamut_mode, + .tone_mapping_function = tonemapping_funcs[s->tonemapping], + .tone_mapping_param = s->tonemapping_param, + .tone_mapping_mode = tonemapping_mode, + .inverse_tone_mapping = s->inverse_tonemapping, + .tone_mapping_crosstalk = s->crosstalk, + .lut_size = s->tonemapping_lut_size, + ); + + s->dither_params = *pl_dither_params( + .method = s->dithering, + .lut_size = s->dither_lut_size, + .temporal = s->dither_temporal, + ); + + s->cone_params = *pl_cone_params( + .cones = s->cones, + .strength = s->cone_str, + ); + + s->params = *pl_render_params( + .lut_entries = s->lut_entries, + .antiringing_strength = s->antiringing, + .background_transparency = 1.0f - (float) color_rgba[3] / UINT8_MAX, + .background_color = { + (float) color_rgba[0] / UINT8_MAX, + (float) color_rgba[1] / UINT8_MAX, + (float) color_rgba[2] / UINT8_MAX, + }, + + .deband_params = s->deband ? &s->deband_params : NULL, + .sigmoid_params = s->sigmoid ? &pl_sigmoid_default_params : NULL, + .color_adjustment = &s->color_adjustment, + .peak_detect_params = s->peakdetect ? &s->peak_detect_params : NULL, + .color_map_params = &s->color_map_params, + .dither_params = s->dithering >= 0 ? &s->dither_params : NULL, + .cone_params = s->cones ? &s->cone_params : NULL, + + .hooks = s->hooks, + .num_hooks = s->num_hooks, + + .skip_anti_aliasing = s->skip_aa, + .polar_cutoff = s->polar_cutoff, + .disable_linear_scaling = s->disable_linear, + .disable_builtin_scalers = s->disable_builtin, + .force_dither = s->force_dither, + .disable_fbos = s->disable_fbos, + ); + + RET(find_scaler(ctx, &s->params.upscaler, s->upscaler)); + RET(find_scaler(ctx, &s->params.downscaler, s->downscaler)); return 0; fail: @@ -327,6 +428,7 @@ static int libplacebo_init(AVFilterContext *avctx) s->out_format = AV_PIX_FMT_NONE; } + RET(update_settings(avctx)); RET(av_expr_parse(&s->crop_x_pexpr, s->crop_x_expr, var_names, NULL, NULL, NULL, NULL, 0, s)); RET(av_expr_parse(&s->crop_y_pexpr, s->crop_y_expr, var_names, @@ -440,14 +542,24 @@ static void libplacebo_uninit(AVFilterContext *avctx) av_expr_free(s->pos_h_pexpr); } +static int libplacebo_process_command(AVFilterContext *ctx, const char *cmd, + const char *arg, char *res, int res_len, + int flags) +{ + int err = 0; + RET(ff_filter_process_command(ctx, cmd, arg, res, res_len, flags)); + RET(update_settings(ctx)); + return 0; + +fail: + return err; +} + 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; const AVPixFmtDescriptor *outdesc = av_pix_fmt_desc_get(out->format); - 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, @@ -496,95 +608,7 @@ static int process_frames(AVFilterContext *avctx, AVFrame *out, AVFrame *in) pl_rect2df_aspect_set(&target.crop, aspect, s->pad_crop_ratio); } -#if FF_API_LIBPLACEBO_OPTS - /* 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; -#endif - - /* Update render params */ - params = (struct pl_render_params) { - PL_RENDER_DEFAULTS - .lut_entries = s->lut_entries, - .antiringing_strength = s->antiringing, - - .deband_params = !s->deband ? NULL : pl_deband_params( - .iterations = s->deband_iterations, - .threshold = s->deband_threshold, - .radius = s->deband_radius, - .grain = s->deband_grain, - ), - - .sigmoid_params = s->sigmoid ? &pl_sigmoid_default_params : NULL, - - .color_adjustment = &(struct pl_color_adjustment) { - .brightness = s->brightness, - .contrast = s->contrast, - .saturation = s->saturation, - .hue = s->hue, - .gamma = s->gamma, - }, - - .peak_detect_params = !s->peakdetect ? NULL : pl_peak_detect_params( - .smoothing_period = s->smoothing, - .minimum_peak = s->min_peak, - .scene_threshold_low = s->scene_low, - .scene_threshold_high = s->scene_high, - .overshoot_margin = s->overshoot, - ), - - .color_map_params = pl_color_map_params( - .intent = s->intent, - .gamut_mode = gamut_mode, - .tone_mapping_function = tonemapping_funcs[s->tonemapping], - .tone_mapping_param = s->tonemapping_param, - .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( - .method = s->dithering, - .lut_size = s->dither_lut_size, - .temporal = s->dither_temporal, - ), - - .cone_params = !s->cones ? NULL : pl_cone_params( - .cones = s->cones, - .strength = s->cone_str, - ), - - .hooks = s->hooks, - .num_hooks = s->num_hooks, - - .skip_anti_aliasing = s->skip_aa, - .polar_cutoff = s->polar_cutoff, - .disable_linear_scaling = s->disable_linear, - .disable_builtin_scalers = s->disable_builtin, - .force_dither = s->force_dither, - .disable_fbos = s->disable_fbos, - }; - - RET(find_scaler(avctx, ¶ms.upscaler, s->upscaler)); - RET(find_scaler(avctx, ¶ms.downscaler, s->downscaler)); - RET(parse_fillcolor(avctx, ¶ms, s->fillcolor)); - - pl_render_image(s->renderer, &image, &target, ¶ms); + pl_render_image(s->renderer, &image, &target, &s->params); pl_unmap_avframe(s->gpu, &image); if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) { @@ -1052,7 +1076,7 @@ const AVFilter ff_vf_libplacebo = { .priv_size = sizeof(LibplaceboContext), .init = &libplacebo_init, .uninit = &libplacebo_uninit, - .process_command = &ff_filter_process_command, + .process_command = &libplacebo_process_command, FILTER_INPUTS(libplacebo_inputs), FILTER_OUTPUTS(libplacebo_outputs), FILTER_QUERY_FUNC(libplacebo_query_format),