PR #24792 opened by ffmpeg-devel URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24792 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24792.patch
**Backport:** https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24698 Use the actual size in the final column. No other filter_column function uses the size parameter, so changing its value is safe. Fixes: #YWH-PGM40646-36 >From f347375d1f03c87afdb9531c66a18f886f96a04d Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler <[email protected]> Date: Fri, 25 Sep 2026 22:55:01 +0200 Subject: [PATCH] avfilter/vf_convolution: don't assume frame is multiple of 16 pixels wide Limit the 8-bit column filter to the pixels remaining in the current slice. Pass slice_end - y at all three call sites so both the 8-bit and high-bit-depth column filters receive the correct remaining width. This handles partial 16-pixel blocks at frame and thread-slice boundaries. The non-column callbacks do not use this argument. Fixes: #YWH-PGM40646-36 (cherry picked from commit 8b9e02cc17126bf42416624e0fea329aa42126b0) --- libavfilter/vf_convolution.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libavfilter/vf_convolution.c b/libavfilter/vf_convolution.c index 70cbe28475..cc55beb0be 100644 --- a/libavfilter/vf_convolution.c +++ b/libavfilter/vf_convolution.c @@ -494,16 +494,17 @@ static void filter_column(uint8_t *dst, int height, int dstride, int stride, int size) { DECLARE_ALIGNED(64, unsigned, sum)[16]; + const int width = FFMIN(16, size); for (int y = 0; y < height; y++) { memset(sum, 0, sizeof(sum)); for (int i = 0; i < 2 * radius + 1; i++) { - for (int off16 = 0; off16 < 16; off16++) + for (int off16 = 0; off16 < width; off16++) sum[off16] += (unsigned)c[i][0 + y * stride + off16] * matrix[i]; } - for (int off16 = 0; off16 < 16; off16++) { + for (int off16 = 0; off16 < width; off16++) { dst[off16] = av_clip_uint8((int)sum[off16] * rdiv + bias + 0.5f); } dst += dstride; @@ -612,12 +613,12 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) s->setup[plane](radius, c, src, stride, x, width, y, height, bpc); s->filter[plane](dst + yoff + xoff, 1, rdiv, bias, matrix, c, s->max, radius, - dstride, stride, slice_end - step); + dstride, stride, slice_end - y); } s->setup[plane](radius, c, src, stride, left, width, y, height, bpc); s->filter[plane](dst + yoff + xoff, right - left, rdiv, bias, matrix, c, s->max, radius, - dstride, stride, slice_end - step); + dstride, stride, slice_end - y); for (x = right; x < sizew; x++) { const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc; const int yoff = mode == MATRIX_COLUMN ? x * dstride : 0; @@ -625,7 +626,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) s->setup[plane](radius, c, src, stride, x, width, y, height, bpc); s->filter[plane](dst + yoff + xoff, 1, rdiv, bias, matrix, c, s->max, radius, - dstride, stride, slice_end - step); + dstride, stride, slice_end - y); } if (mode != MATRIX_COLUMN) dst += dstride; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
