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]

Reply via email to