PR #25180 opened by Marti2203
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25180
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25180.patch

`horizontal_frame_pack()` (non-interleaved, i.e. `sbs`) and 
`vertical_frame_pack()` (`tab`, `lines`) fill only the first three entries of 
the destination pointer array (and, for the vertical case, the linesize array) 
passed to `av_image_copy2()`, which copies every plane of the format. framepack 
accepts formats with alpha (`yuva*`, `gbrap*`), and for those the alpha plane 
is written through an uninitialized pointer:

```
ffmpeg -f lavfi -i "testsrc2=s=320x240:d=0.2,format=yuva420p" \
       -f lavfi -i "testsrc2=s=320x240:d=0.2,format=yuva420p" \
       -filter_complex "[0][1]framepack" -f null -
```

crashes with a segmentation fault, as does `framepack=tab`.

With the patch, the alpha plane pointer (and linesize) are set like luma's when 
the output has an alpha plane. For `yuva420p`, `yuva444p10le` and `gbrap`, with 
a non-trivial alpha plane in one input, every mode (`sbs`, `tab`, `lines`, 
`columns`, `frameseq`) runs, and `sbs` / `tab` output is identical to `hstack` 
/ `vstack` of the same inputs, alpha included; valgrind reports no errors. 
Output for formats without alpha is byte-identical to before, and the 
`fate-filter-framepack-*` tests pass.

This issue was found by an LLM-Enhanced Static Analysis Engine and verified 
manually.

🤖 Generated with [Claude Code](https://claude.com/claude-code)



From f96c180daf39bc667bdbd9ec685a893d83ed650f Mon Sep 17 00:00:00 2001
From: Martin Mirchev <[email protected]>
Date: Sun, 18 Oct 2026 17:40:47 +0800
Subject: [PATCH] avfilter/vf_framepack: set the alpha plane pointer for sbs
 and tab

horizontal_frame_pack() (non-interleaved) and vertical_frame_pack()
filled only the first three entries of the destination arrays passed to
av_image_copy2(), which copies all planes of the format. For formats
with alpha (yuva*, gbrap*), which framepack supports, the alpha plane was
written through an uninitialized pointer (and, for tab/lines, with an
uninitialized linesize), crashing e.g.

  ffmpeg -f lavfi -i testsrc2,format=yuva420p -f lavfi -i 
testsrc2,format=yuva420p \
         -filter_complex "[0][1]framepack" -f null -

Set the alpha plane pointer and linesize as for luma.

Signed-off-by: Martin Mirchev <[email protected]>
---
 libavfilter/vf_framepack.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/libavfilter/vf_framepack.c b/libavfilter/vf_framepack.c
index 5480ef0fc1..c9cdab66aa 100644
--- a/libavfilter/vf_framepack.c
+++ b/libavfilter/vf_framepack.c
@@ -238,12 +238,14 @@ static void horizontal_frame_pack(AVFilterLink *outlink,
         for (i = 0; i < 2; i++) {
             const AVFrame *const input_view = s->input_views[i];
             const int psize = 1 + (s->depth > 8);
-            uint8_t *dst[4];
+            uint8_t *dst[4] = { NULL };
             int sub_w = psize * input_view->width >> 
s->pix_desc->log2_chroma_w;
 
             dst[0] = out->data[0] + i * input_view->width * psize;
             dst[1] = out->data[1] + i * sub_w;
             dst[2] = out->data[2] + i * sub_w;
+            if (out->data[3])
+                dst[3] = out->data[3] + i * input_view->width * psize;
 
             av_image_copy2(dst, out->linesize,
                            input_view->data, input_view->linesize,
@@ -264,8 +266,8 @@ static void vertical_frame_pack(AVFilterLink *outlink,
 
     for (i = 0; i < 2; i++) {
         const AVFrame *const input_view = s->input_views[i];
-        uint8_t *dst[4];
-        int linesizes[4];
+        uint8_t *dst[4] = { NULL };
+        int linesizes[4] = { 0 };
         int sub_h = input_view->height >> s->pix_desc->log2_chroma_h;
 
         dst[0] = out->data[0] + i * out->linesize[0] *
@@ -281,6 +283,12 @@ static void vertical_frame_pack(AVFilterLink *outlink,
                        interleaved * out->linesize[1];
         linesizes[2] = out->linesize[2] +
                        interleaved * out->linesize[2];
+        if (out->data[3]) {
+            dst[3] = out->data[3] + i * out->linesize[3] *
+                     (interleaved + input_view->height * (1 - interleaved));
+            linesizes[3] = out->linesize[3] +
+                           interleaved * out->linesize[3];
+        }
 
         av_image_copy2(dst, linesizes,
                        input_view->data, input_view->linesize,
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to