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

decode_init() allocates the decompression buffer with av_mallocz(), so the 
whole (width + 255) * 4 * (height + 64) byte buffer is written and becomes 
resident.
The decoder only reads the bytes it just wrote for the current packet (up to 
decomp_len), so zeroing the buffer is unnecessary and wastes RAM. Use 
av_malloc() instead.

The output is byte-identical to the unpatched decoder on 1536 valid streams 
(pal8 with palette changes, rgb555, rgb565, bgr0, 1x1 to 1920x1080, zlib and 
uncompressed packets), on 1272 damaged streams and on 22000 randomly mutated 
ones, with clang 21, GCC 16.2, a --enable-memory-poisoning build, 
MallocScribble and ASan+UBSan; an instrumented build saw no read of decomp_buf 
outside [0, decomp_len), and fate-zmbv passes.

| size | bpp | RSS before | RSS after | RAM saved |
|---|---|---|---|---|
| 640x400 | 8 | 11.4 MiB | 9.9 MiB | 1.4 MiB (12.7%) |
| 640x400 | 32 | 16.9 MiB | 16.2 MiB | 0.7 MiB (4.2%) |
| 1920x1080 | 8 | 33.4 MiB | 24.2 MiB | 7.7 MiB (23.0%) |
| 1920x1080 | 32 | 69.3 MiB | 67.0 MiB | 1.6 MiB (2.4%) |
| 3840x2160 | 8 | 91.6 MiB | 64.8 MiB | 26.9 MiB (29.3%) |
| 3840x2160 | 32 | 246.9 MiB | 243.8 MiB | 3.2 MiB (1.3%) |

Noticed during a review sweep of ffmpeg using an LLM. Testing was heavily 
assisted by an LLM.

Signed-off-by: romainhedouin <[email protected]>

# Summary of changes

Briefly describe what this PR does and why.

<!--
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 4926fcc9df97f9768ce7f414c1f34a2dc803808f Mon Sep 17 00:00:00 2001
From: romainhedouin <[email protected]>
Date: Mon, 2 Nov 2026 02:12:46 +0100
Subject: [PATCH] avcodec/zmbv: don't zero the decompression buffer

decomp_buf is only read up to decomp_len, the number of bytes that
inflate (or the uncompressed copy) wrote for the current packet, so it
does not need to be cleared. Allocate it without clearing it, so that
only the part used by the stream gets touched. The output is unchanged.

Noticed during a review sweep of ffmpeg using an LLM.

Signed-off-by: romainhedouin <[email protected]>
---
 libavcodec/zmbv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c
index 3e2e7fa98a9..208e9410f1d 100644
--- a/libavcodec/zmbv.c
+++ b/libavcodec/zmbv.c
@@ -634,7 +634,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     c->decomp_size = (avctx->width + 255) * 4 * (avctx->height + 64);
 
     /* Allocate decompression buffer */
-    c->decomp_buf = av_mallocz(c->decomp_size);
+    c->decomp_buf = av_malloc(c->decomp_size);
     if (!c->decomp_buf) {
         av_log(avctx, AV_LOG_ERROR,
                 "Can't allocate decompression buffer.\n");
-- 
2.54.0

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

Reply via email to