mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-10-28 10:04:37 +08:00
avcodec/vaapi_decode: destroy the buffers of a picture released without being issued
mjpegdec releases a picture left over from a failed packet before ff_get_format() tears down the VA context and the device the callback needs. Fixes: vMMlgSzb6MuU Fixes: AISLE-2026-0150-00741 Fixes: memleak Memleak Replicated through UnModified FFmpeg with ASAN Found-by: Joshua Rogers (AISLE) The report suggested a free_frame_priv callback that destroys the still tracked parameter and slice buffers.
This commit is contained in:
1 parent
838c660bb3
commit
4221a63ce8
13 files changed
+45
-17
No files matched your search
@@ -761,6 +761,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
|
||||
s->avctx->pix_fmt,
|
||||
AV_PIX_FMT_NONE,
|
||||
};
|
||||
av_refstruct_unref(&s->hwaccel_picture_private);
|
||||
s->hwaccel_pix_fmt = ff_get_format(s->avctx, pix_fmts);
|
||||
if (s->hwaccel_pix_fmt < 0)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
@@ -456,6 +456,7 @@ const FFHWAccel ff_av1_vaapi_hwaccel = {
|
||||
.end_frame = vaapi_av1_end_frame,
|
||||
.decode_slice = vaapi_av1_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePicture),
|
||||
.free_frame_priv = ff_vaapi_decode_free_frame_priv,
|
||||
.init = vaapi_av1_decode_init,
|
||||
.uninit = vaapi_av1_decode_uninit,
|
||||
.frame_params = ff_vaapi_common_frame_params,
|
||||
|
||||
+30
-17
@@ -135,34 +135,44 @@ int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ff_vaapi_decode_destroy_buffers(AVCodecContext *avctx,
|
||||
static void ff_vaapi_decode_destroy_buffers(void *logctx, VADisplay display,
|
||||
VAAPIDecodePicture *pic)
|
||||
{
|
||||
VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
|
||||
VAStatus vas;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pic->nb_param_buffers; i++) {
|
||||
vas = vaDestroyBuffer(ctx->hwctx->display,
|
||||
pic->param_buffers[i]);
|
||||
vas = vaDestroyBuffer(display, pic->param_buffers[i]);
|
||||
if (vas != VA_STATUS_SUCCESS) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
|
||||
av_log(logctx, AV_LOG_ERROR, "Failed to destroy "
|
||||
"parameter buffer %#x: %d (%s).\n",
|
||||
pic->param_buffers[i], vas, vaErrorStr(vas));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2 * pic->nb_slices; i++) {
|
||||
vas = vaDestroyBuffer(ctx->hwctx->display,
|
||||
pic->slice_buffers[i]);
|
||||
vas = vaDestroyBuffer(display, pic->slice_buffers[i]);
|
||||
if (vas != VA_STATUS_SUCCESS) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Failed to destroy slice "
|
||||
av_log(logctx, AV_LOG_ERROR, "Failed to destroy slice "
|
||||
"slice buffer %#x: %d (%s).\n",
|
||||
pic->slice_buffers[i], vas, vaErrorStr(vas));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vaapi_decode_free_buffers(void *logctx, VADisplay display,
|
||||
VAAPIDecodePicture *pic)
|
||||
{
|
||||
ff_vaapi_decode_destroy_buffers(logctx, display, pic);
|
||||
|
||||
pic->nb_param_buffers = 0;
|
||||
pic->nb_param_buffers_allocated = 0;
|
||||
av_freep(&pic->param_buffers);
|
||||
pic->nb_slices = 0;
|
||||
pic->nb_slice_buffers_allocated = 0;
|
||||
av_freep(&pic->slice_buffers);
|
||||
}
|
||||
|
||||
int ff_vaapi_decode_issue(AVCodecContext *avctx,
|
||||
VAAPIDecodePicture *pic)
|
||||
{
|
||||
@@ -219,7 +229,7 @@ int ff_vaapi_decode_issue(AVCodecContext *avctx,
|
||||
|
||||
if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
|
||||
AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS)
|
||||
ff_vaapi_decode_destroy_buffers(avctx, pic);
|
||||
ff_vaapi_decode_destroy_buffers(avctx, ctx->hwctx->display, pic);
|
||||
|
||||
err = 0;
|
||||
goto exit;
|
||||
@@ -231,7 +241,7 @@ fail_with_picture:
|
||||
"after error: %d (%s).\n", vas, vaErrorStr(vas));
|
||||
}
|
||||
fail:
|
||||
ff_vaapi_decode_destroy_buffers(avctx, pic);
|
||||
ff_vaapi_decode_destroy_buffers(avctx, ctx->hwctx->display, pic);
|
||||
fail_at_end:
|
||||
exit:
|
||||
pic->nb_param_buffers = 0;
|
||||
@@ -247,18 +257,21 @@ exit:
|
||||
int ff_vaapi_decode_cancel(AVCodecContext *avctx,
|
||||
VAAPIDecodePicture *pic)
|
||||
{
|
||||
ff_vaapi_decode_destroy_buffers(avctx, pic);
|
||||
VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
|
||||
|
||||
pic->nb_param_buffers = 0;
|
||||
pic->nb_param_buffers_allocated = 0;
|
||||
av_freep(&pic->param_buffers);
|
||||
pic->nb_slices = 0;
|
||||
pic->nb_slice_buffers_allocated = 0;
|
||||
av_freep(&pic->slice_buffers);
|
||||
vaapi_decode_free_buffers(avctx, ctx->hwctx->display, pic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_vaapi_decode_free_frame_priv(AVRefStructOpaque hwctx, void *data)
|
||||
{
|
||||
AVHWDeviceContext *device_ctx = hwctx.nc;
|
||||
AVVAAPIDeviceContext *vactx = device_ctx->hwctx;
|
||||
|
||||
vaapi_decode_free_buffers(device_ctx, vactx->display, data);
|
||||
}
|
||||
|
||||
static const struct {
|
||||
uint32_t fourcc;
|
||||
enum AVPixelFormat pix_fmt;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/hwcontext.h"
|
||||
#include "libavutil/hwcontext_vaapi.h"
|
||||
#include "libavutil/refstruct.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
@@ -79,6 +80,7 @@ int ff_vaapi_decode_issue(AVCodecContext *avctx,
|
||||
VAAPIDecodePicture *pic);
|
||||
int ff_vaapi_decode_cancel(AVCodecContext *avctx,
|
||||
VAAPIDecodePicture *pic);
|
||||
void ff_vaapi_decode_free_frame_priv(AVRefStructOpaque hwctx, void *data);
|
||||
|
||||
int ff_vaapi_decode_init(AVCodecContext *avctx);
|
||||
int ff_vaapi_decode_uninit(AVCodecContext *avctx);
|
||||
|
||||
@@ -403,6 +403,7 @@ const FFHWAccel ff_h264_vaapi_hwaccel = {
|
||||
.end_frame = &vaapi_h264_end_frame,
|
||||
.decode_slice = &vaapi_h264_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePicture),
|
||||
.free_frame_priv = &ff_vaapi_decode_free_frame_priv,
|
||||
.init = &ff_vaapi_decode_init,
|
||||
.uninit = &ff_vaapi_decode_uninit,
|
||||
.frame_params = &ff_vaapi_common_frame_params,
|
||||
|
||||
@@ -665,6 +665,7 @@ const FFHWAccel ff_hevc_vaapi_hwaccel = {
|
||||
.end_frame = vaapi_hevc_end_frame,
|
||||
.decode_slice = vaapi_hevc_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePictureHEVC),
|
||||
.free_frame_priv = ff_vaapi_decode_free_frame_priv,
|
||||
.init = ff_vaapi_decode_init,
|
||||
.uninit = ff_vaapi_decode_uninit,
|
||||
.frame_params = ff_vaapi_common_frame_params,
|
||||
|
||||
@@ -152,6 +152,7 @@ const FFHWAccel ff_mjpeg_vaapi_hwaccel = {
|
||||
.end_frame = &vaapi_mjpeg_end_frame,
|
||||
.decode_slice = &vaapi_mjpeg_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePicture),
|
||||
.free_frame_priv = &ff_vaapi_decode_free_frame_priv,
|
||||
.init = &ff_vaapi_decode_init,
|
||||
.uninit = &ff_vaapi_decode_uninit,
|
||||
.frame_params = &ff_vaapi_common_frame_params,
|
||||
|
||||
@@ -185,6 +185,7 @@ const FFHWAccel ff_mpeg2_vaapi_hwaccel = {
|
||||
.end_frame = &vaapi_mpeg2_end_frame,
|
||||
.decode_slice = &vaapi_mpeg2_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePicture),
|
||||
.free_frame_priv = &ff_vaapi_decode_free_frame_priv,
|
||||
.init = &ff_vaapi_decode_init,
|
||||
.uninit = &ff_vaapi_decode_uninit,
|
||||
.frame_params = &ff_vaapi_common_frame_params,
|
||||
|
||||
@@ -192,6 +192,7 @@ const FFHWAccel ff_mpeg4_vaapi_hwaccel = {
|
||||
.end_frame = &vaapi_mpeg4_end_frame,
|
||||
.decode_slice = &vaapi_mpeg4_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePicture),
|
||||
.free_frame_priv = &ff_vaapi_decode_free_frame_priv,
|
||||
.init = &ff_vaapi_decode_init,
|
||||
.uninit = &ff_vaapi_decode_uninit,
|
||||
.frame_params = &ff_vaapi_common_frame_params,
|
||||
@@ -210,6 +211,7 @@ const FFHWAccel ff_h263_vaapi_hwaccel = {
|
||||
.end_frame = &vaapi_mpeg4_end_frame,
|
||||
.decode_slice = &vaapi_mpeg4_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePicture),
|
||||
.free_frame_priv = &ff_vaapi_decode_free_frame_priv,
|
||||
.init = &ff_vaapi_decode_init,
|
||||
.uninit = &ff_vaapi_decode_uninit,
|
||||
.frame_params = &ff_vaapi_common_frame_params,
|
||||
|
||||
@@ -516,6 +516,7 @@ const FFHWAccel ff_wmv3_vaapi_hwaccel = {
|
||||
.end_frame = &vaapi_vc1_end_frame,
|
||||
.decode_slice = &vaapi_vc1_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePicture),
|
||||
.free_frame_priv = &ff_vaapi_decode_free_frame_priv,
|
||||
.init = &ff_vaapi_decode_init,
|
||||
.uninit = &ff_vaapi_decode_uninit,
|
||||
.frame_params = &ff_vaapi_common_frame_params,
|
||||
@@ -533,6 +534,7 @@ const FFHWAccel ff_vc1_vaapi_hwaccel = {
|
||||
.end_frame = &vaapi_vc1_end_frame,
|
||||
.decode_slice = &vaapi_vc1_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePicture),
|
||||
.free_frame_priv = &ff_vaapi_decode_free_frame_priv,
|
||||
.init = &ff_vaapi_decode_init,
|
||||
.uninit = &ff_vaapi_decode_uninit,
|
||||
.frame_params = &ff_vaapi_common_frame_params,
|
||||
|
||||
@@ -230,6 +230,7 @@ const FFHWAccel ff_vp8_vaapi_hwaccel = {
|
||||
.end_frame = &vaapi_vp8_end_frame,
|
||||
.decode_slice = &vaapi_vp8_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePicture),
|
||||
.free_frame_priv = &ff_vaapi_decode_free_frame_priv,
|
||||
.init = &ff_vaapi_decode_init,
|
||||
.uninit = &ff_vaapi_decode_uninit,
|
||||
.frame_params = &ff_vaapi_common_frame_params,
|
||||
|
||||
@@ -178,6 +178,7 @@ const FFHWAccel ff_vp9_vaapi_hwaccel = {
|
||||
.end_frame = vaapi_vp9_end_frame,
|
||||
.decode_slice = vaapi_vp9_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePicture),
|
||||
.free_frame_priv = ff_vaapi_decode_free_frame_priv,
|
||||
.init = ff_vaapi_decode_init,
|
||||
.uninit = ff_vaapi_decode_uninit,
|
||||
.frame_params = ff_vaapi_common_frame_params,
|
||||
|
||||
@@ -650,6 +650,7 @@ const FFHWAccel ff_vvc_vaapi_hwaccel = {
|
||||
.end_frame = &vaapi_vvc_end_frame,
|
||||
.decode_slice = &vaapi_vvc_decode_slice,
|
||||
.frame_priv_data_size = sizeof(VAAPIDecodePictureVVC),
|
||||
.free_frame_priv = &ff_vaapi_decode_free_frame_priv,
|
||||
.init = &ff_vaapi_decode_init,
|
||||
.uninit = &ff_vaapi_decode_uninit,
|
||||
.frame_params = &ff_vaapi_common_frame_params,
|
||||
|
||||
Reference in new issue
Block a user