diff --git a/libswscale/filters.c b/libswscale/filters.c index a57d81fef3..7e8865659e 100644 --- a/libswscale/filters.c +++ b/libswscale/filters.c @@ -154,7 +154,11 @@ static bool validate_params(const SwsFilterFunction *fun, SwsScaler scaler) } } -static double filter_radius(const SwsFilterFunction *fun) +/** + * Numerically estimate the last intersection between the function value + * and the cutoff domain [-SWS_MAX_REDUCE_CUTOFF, SWS_MAX_REDUCE_CUTOFF]. + */ +static double est_filter_radius(const SwsFilterFunction *fun) { const double bound = fun->radius; const double step = 1e-2; @@ -225,7 +229,21 @@ int ff_sws_filter_generate(void *log, const SwsFilterParams *params, if (fun.radius < 0.0) /* tunable width kernels like lanczos */ fun.radius = fun.params[0]; - const double radius = filter_radius(&fun) * stretch; + double radius; + switch (scaler) { + case SWS_SCALE_POINT: + radius = 0.5; + break; + case SWS_SCALE_BILINEAR: + radius = 1.0 - SWS_MAX_REDUCE_CUTOFF; + break; + default: + /* Numerically estimate radius of nontrivial or parametric kernels */ + radius = est_filter_radius(&fun); + break; + } + radius *= stretch; + int filter_size = ceil(radius * 2.0); filter_size = FFMIN(filter_size, params->src_size); av_assert0(filter_size >= 1);