PR #25678 opened by romainhedouin URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25678 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25678.patch
The sum buffer was allocated with sizeof(*s->sum), the size of a pointer, instead of the size of an element. That made it eight times larger than what the fast tmix path uses (a row stride of two times the line size). Allocate only what is used. The smaller buffer can be allocated for larger frames when max_alloc is raised, so also compute the offset of the first sum row of a slice with size_t. Without the cast, that offset overflows int for planes larger than about 1 GiB. The output is byte-identical: 52618 framemd5 outputs per compiler (149 pixel formats, tmix fast and non-fast path, mix) match before and after with clang and GCC 16. | tmix=frames=3, 8 threads | RSS MiB, clang | RSS MiB, GCC | CPU s, clang | CPU s, GCC | |---|---|---|---|---| | yuv420p 1920x1080 | 99.9 -> 58.4 | 96.6 -> 55.1 | 3.32 -> 3.32 | 3.97 -> 3.90 | | yuv420p 3840x2160 | 367.9 -> 201.9 | 355.8 -> 201.6 | 3.46 -> 3.44 | 4.27 -> 4.35 | | yuv420p10le 1920x1080 | 164.1 -> 87.1 | 169.9 -> 86.8 | 2.59 -> 2.57 | 2.94 -> 2.95 | | gbrpf32le 1920x1080 | 601.5 -> 269.3 | 601.2 -> 269.0 | 3.08 -> 3.05 | 3.35 -> 3.33 | Apple M4, clang 21 / GCC 16.2, median of 5 runs. CPU differences are within noise. Noticed during a review sweep of ffmpeg using an LLM. Signed-off-by: romainhedouin <[email protected]> <!-- If this PR requires new FATE test samples, attach them to the PR and list their target paths below (relative to the fate-suite root). Attached filenames must match the sample's filename: ```fate-samples # e.g. vorbis/new-sample.ogg ``` --> >From fac2a9157f343cae96292d5dbfdd85797a2ba660 Mon Sep 17 00:00:00 2001 From: romainhedouin <[email protected]> Date: Mon, 2 Nov 2026 10:38:24 +0100 Subject: [PATCH] avfilter/vf_mix: fix the size of the sum buffer The size of the sum buffer was computed with sizeof(*s->sum), which is the size of a pointer, not of an element. This made it eight times larger than what the fast tmix path indexes, which uses a row stride of two times the line size. Allocate the size that is used. The output is unchanged. The smaller buffer can be allocated for larger frames when max_alloc is raised, so also compute the offset of the first sum row of a slice with size_t. In int it overflows for planes larger than about 1 GiB. Noticed during a review sweep of ffmpeg using an LLM. Signed-off-by: romainhedouin <[email protected]> --- libavfilter/vf_mix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_mix.c b/libavfilter/vf_mix.c index 3143f6e9c84..f76217fbeb3 100644 --- a/libavfilter/vf_mix.c +++ b/libavfilter/vf_mix.c @@ -162,7 +162,7 @@ typedef struct ThreadData { const int slice_start = ff_slice_pos(s->height[p], jobnr, nb_jobs); \ const int slice_end = ff_slice_pos(s->height[p], jobnr + 1, nb_jobs); \ const int width = s->linesizes[p] / sizeof(type); \ - stype *sum = (stype *)(s->sum[p] + slice_start * s->linesizes[p] * 2); \ + stype *sum = (stype *)(s->sum[p] + (size_t)slice_start * s->linesizes[p] * 2); \ type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ const ptrdiff_t sum_linesize = (s->linesizes[p] * 2) / sizeof(stype); \ const ptrdiff_t dst_linesize = out->linesize[p] / sizeof(type); \ @@ -361,7 +361,7 @@ static int config_output(AVFilterLink *outlink) if (s->tmix) { for (int p = 0; p < s->nb_planes; p++) { - s->sum[p] = av_calloc(s->linesizes[p], s->height[p] * sizeof(*s->sum) * 2); + s->sum[p] = av_calloc(s->height[p], 2 * (size_t)s->linesizes[p]); if (!s->sum[p]) return AVERROR(ENOMEM); } -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
