Commit 26ebd5a180 for ffmpeg
commit 26ebd5a180f5bed3063c8ddbb64d8bb3ae289299
Author: Niklas Haas <git@haasn.dev>
Date: Sun Nov 8 02:54:37 2026 +0100
swscale/filters: calculate true filter size
Instead of estimating based on a worst-case scenario, calculate the
number of taps each row needs (which depends on the phase), and take
the maximum of these values as the overall filter size.
Signed-off-by: Niklas Haas <git@haasn.dev>
diff --git a/libswscale/filters.c b/libswscale/filters.c
index 006cad5f83..5544116961 100644
--- a/libswscale/filters.c
+++ b/libswscale/filters.c
@@ -267,11 +267,22 @@ int ff_sws_filter_generate(void *log, const SwsFilterParams *params,
}
radius *= stretch;
- int filter_size = ceil(radius * 2.0);
- filter_size = FFMIN(filter_size, params->src_size);
- av_assert0(filter_size >= 1);
- if (filter_size > SWS_FILTER_SIZE_MAX)
- return AVERROR(ENOTSUP);
+ /* Compute filter size by checking the number of taps in each row */
+ int filter_size = 0;
+ for (int i = 0; i < params->dst_size; i++) {
+ /* Matches the indexing in compute_row() */
+ const double src_pos = get_src_pos(i, ratio_inv, params->offset);
+ const int start = floor(src_pos - radius) + 1;
+ const int stop = ceil (src_pos + radius) - 1;
+ const int taps = av_clip(stop - start + 1, 1, params->src_size);
+ if (taps > SWS_FILTER_SIZE_MAX) {
+ return AVERROR(ENOTSUP);
+ } else if (taps > filter_size) {
+ filter_size = taps;
+ if (taps == params->src_size)
+ break; /* can't get any bigger */
+ }
+ }
SwsFilterWeights *filter;
filter = av_refstruct_alloc_ext(sizeof(*filter), 0, NULL, sws_filter_free);