Commit 2c6cd80988 for ffmpeg
commit 2c6cd8098844f2367f8ba0a3a483e405c8f76449
Author: Michael Niedermayer <michael@niedermayer.cc>
Date: Sat Oct 17 03:22:33 2026 +0200
avcodec/vdpau: free the bitstream buffer table when the picture is released
Fixes: pzezUDNFoag5
Fixes: AISLE-2026-0150-00646
Fixes: memleak
Memleak Replicated through UnModified FFmpeg with ASAN
Found-by: Joshua Rogers (AISLE)
The report suggested a free_frame_priv callback that frees
bitstream_buffers.
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index e99ac5338d..2c13113551 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -349,6 +349,13 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
return vdpau_error(status);
}
+void ff_vdpau_free_frame_priv(AVRefStructOpaque hwctx, void *data)
+{
+ struct vdpau_picture_context *pic_ctx = data;
+
+ av_freep(&pic_ctx->bitstream_buffers);
+}
+
#if CONFIG_MPEG1_VDPAU_HWACCEL || \
CONFIG_MPEG2_VDPAU_HWACCEL || CONFIG_MPEG4_VDPAU_HWACCEL || \
CONFIG_VC1_VDPAU_HWACCEL || CONFIG_WMV3_VDPAU_HWACCEL
diff --git a/libavcodec/vdpau_av1.c b/libavcodec/vdpau_av1.c
index b7e7fa8b0c..aaf8cd57c0 100644
--- a/libavcodec/vdpau_av1.c
+++ b/libavcodec/vdpau_av1.c
@@ -362,6 +362,7 @@ const FFHWAccel ff_av1_vdpau_hwaccel = {
.end_frame = vdpau_av1_end_frame,
.decode_slice = vdpau_av1_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .free_frame_priv = ff_vdpau_free_frame_priv,
.init = vdpau_av1_init,
.uninit = ff_vdpau_common_uninit,
.frame_params = ff_vdpau_common_frame_params,
diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c
index 51c7e99900..df0ae7d5c8 100644
--- a/libavcodec/vdpau_h264.c
+++ b/libavcodec/vdpau_h264.c
@@ -271,6 +271,7 @@ const FFHWAccel ff_h264_vdpau_hwaccel = {
.end_frame = vdpau_h264_end_frame,
.decode_slice = vdpau_h264_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .free_frame_priv = ff_vdpau_free_frame_priv,
.init = vdpau_h264_init,
.uninit = ff_vdpau_common_uninit,
.frame_params = ff_vdpau_common_frame_params,
diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c
index 1a92c32b27..1a8429475e 100644
--- a/libavcodec/vdpau_hevc.c
+++ b/libavcodec/vdpau_hevc.c
@@ -551,6 +551,7 @@ const FFHWAccel ff_hevc_vdpau_hwaccel = {
.end_frame = vdpau_hevc_end_frame,
.decode_slice = vdpau_hevc_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .free_frame_priv = ff_vdpau_free_frame_priv,
.init = vdpau_hevc_init,
.uninit = ff_vdpau_common_uninit,
.frame_params = ff_vdpau_common_frame_params,
diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h
index 347576e0c3..8a4ed13d1a 100644
--- a/libavcodec/vdpau_internal.h
+++ b/libavcodec/vdpau_internal.h
@@ -30,6 +30,7 @@
#include "libavutil/frame.h"
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_vdpau.h"
+#include "libavutil/refstruct.h"
#include "avcodec.h"
#include "vdpau.h"
@@ -125,6 +126,7 @@ int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic,
const uint8_t *buffer, uint32_t size);
int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
struct vdpau_picture_context *pic);
+void ff_vdpau_free_frame_priv(AVRefStructOpaque hwctx, void *data);
int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx);
int ff_vdpau_add_buffer(struct vdpau_picture_context *pic, const uint8_t *buf,
uint32_t buf_size);
diff --git a/libavcodec/vdpau_mpeg12.c b/libavcodec/vdpau_mpeg12.c
index b3ac94f217..59047d699c 100644
--- a/libavcodec/vdpau_mpeg12.c
+++ b/libavcodec/vdpau_mpeg12.c
@@ -116,6 +116,7 @@ const FFHWAccel ff_mpeg1_vdpau_hwaccel = {
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_mpeg_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .free_frame_priv = ff_vdpau_free_frame_priv,
.init = vdpau_mpeg1_init,
.uninit = ff_vdpau_common_uninit,
.priv_data_size = sizeof(VDPAUContext),
@@ -151,6 +152,7 @@ const FFHWAccel ff_mpeg2_vdpau_hwaccel = {
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_mpeg_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .free_frame_priv = ff_vdpau_free_frame_priv,
.init = vdpau_mpeg2_init,
.uninit = ff_vdpau_common_uninit,
.frame_params = ff_vdpau_common_frame_params,
diff --git a/libavcodec/vdpau_mpeg4.c b/libavcodec/vdpau_mpeg4.c
index 58c8a6d769..10f8980567 100644
--- a/libavcodec/vdpau_mpeg4.c
+++ b/libavcodec/vdpau_mpeg4.c
@@ -122,6 +122,7 @@ const FFHWAccel ff_mpeg4_vdpau_hwaccel = {
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_mpeg4_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .free_frame_priv = ff_vdpau_free_frame_priv,
.init = vdpau_mpeg4_init,
.uninit = ff_vdpau_common_uninit,
.frame_params = ff_vdpau_common_frame_params,
diff --git a/libavcodec/vdpau_vc1.c b/libavcodec/vdpau_vc1.c
index 323ac4127a..90ce5ace9f 100644
--- a/libavcodec/vdpau_vc1.c
+++ b/libavcodec/vdpau_vc1.c
@@ -149,6 +149,7 @@ const FFHWAccel ff_wmv3_vdpau_hwaccel = {
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_vc1_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .free_frame_priv = ff_vdpau_free_frame_priv,
.init = vdpau_vc1_init,
.uninit = ff_vdpau_common_uninit,
.frame_params = ff_vdpau_common_frame_params,
@@ -166,6 +167,7 @@ const FFHWAccel ff_vc1_vdpau_hwaccel = {
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_vc1_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .free_frame_priv = ff_vdpau_free_frame_priv,
.init = vdpau_vc1_init,
.uninit = ff_vdpau_common_uninit,
.frame_params = ff_vdpau_common_frame_params,
diff --git a/libavcodec/vdpau_vp9.c b/libavcodec/vdpau_vp9.c
index 7b3c1ff4d7..83a17ed74d 100644
--- a/libavcodec/vdpau_vp9.c
+++ b/libavcodec/vdpau_vp9.c
@@ -232,6 +232,7 @@ const FFHWAccel ff_vp9_vdpau_hwaccel = {
.end_frame = vdpau_vp9_end_frame,
.decode_slice = vdpau_vp9_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .free_frame_priv = ff_vdpau_free_frame_priv,
.init = vdpau_vp9_init,
.uninit = ff_vdpau_common_uninit,
.frame_params = ff_vdpau_common_frame_params,