diff options
author | Seungha Yang <seungha.yang@navercorp.com> | 2019-10-29 11:43:05 +0900 |
---|---|---|
committer | Seungha Yang <seungha.yang@navercorp.com> | 2019-10-29 16:29:46 +0900 |
commit | 07f33470b34c6677b614e543a6d8f8cf0a7ce7e3 (patch) | |
tree | 955de22ed74b1e95b82715213241c322d69b5171 | |
parent | 30d0674e7dea5e5af0a39193b960ce0aa59b3f37 (diff) | |
download | gst-libav-07f33470b34c6677b614e543a6d8f8cf0a7ce7e3.tar.gz |
avviddec: Fix huge leak caused by circular reference
AVBufferRef -> GstFFMpegVideoDecVideoFrame -> GstVideoCodecFrame -> AVBufferRef
Instead of holding additional ref there, set read-only which would not be
reused by ff_reget_buffer()
Fixes: https://gitlab.freedesktop.org/gstreamer/gst-libav/issues/63
-rw-r--r-- | ext/libav/gstavviddec.c | 16 |
1 files changed, 5 insertions, 11 deletions
diff --git a/ext/libav/gstavviddec.c b/ext/libav/gstavviddec.c index ab911af..650de2d 100644 --- a/ext/libav/gstavviddec.c +++ b/ext/libav/gstavviddec.c @@ -773,12 +773,6 @@ gst_ffmpegviddec_can_direct_render (GstFFMpegVidDec * ffmpegdec) AV_CODEC_CAP_DR1); } -static void -gst_ffmpegviddec_avbuffer_unref (AVBufferRef * avbuffer) -{ - av_buffer_unref (&avbuffer); -} - /* called when ffmpeg wants us to allocate a buffer to write the decoded frame * into. We try to give it memory from our pool */ static int @@ -790,6 +784,7 @@ gst_ffmpegviddec_get_buffer2 (AVCodecContext * context, AVFrame * picture, GstFFMpegVidDec *ffmpegdec; guint c; GstFlowReturn ret; + int create_buffer_flags = 0; ffmpegdec = (GstFFMpegVidDec *) context->opaque; @@ -871,17 +866,16 @@ gst_ffmpegviddec_get_buffer2 (AVCodecContext * context, AVFrame * picture, picture->data[c]); } - picture->buf[0] = av_buffer_create (NULL, 0, dummy_free_buffer, dframe, 0); if ((flags & AV_GET_BUFFER_FLAG_REF) == AV_GET_BUFFER_FLAG_REF) { /* decoder might reuse this AVFrame and it would result to no more * get_buffer() call if the AVFrame's AVBuffer is writable * (meaning that the refcount of AVBuffer == 1). - * To enforce get_buffer() for the every output frame, hold another ref here + * To enforce get_buffer() for the every output frame, set read-only flag here */ - gst_video_codec_frame_set_user_data (frame, - av_buffer_ref (picture->buf[0]), - (GDestroyNotify) gst_ffmpegviddec_avbuffer_unref); + create_buffer_flags = AV_BUFFER_FLAG_READONLY; } + picture->buf[0] = av_buffer_create (NULL, + 0, dummy_free_buffer, dframe, create_buffer_flags); GST_LOG_OBJECT (ffmpegdec, "returned frame %p", dframe->buffer); |