mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-02-14 22:22:59 +02:00
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.
This commit is contained in:
parent
e700d87b20
commit
482d81378f
@ -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),
|
||||
|
Loading…
x
Reference in New Issue
Block a user