summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeungha Yang <seungha.yang@navercorp.com>2019-10-29 11:43:05 +0900
committerSeungha Yang <seungha.yang@navercorp.com>2019-10-29 16:29:46 +0900
commit07f33470b34c6677b614e543a6d8f8cf0a7ce7e3 (patch)
tree955de22ed74b1e95b82715213241c322d69b5171
parent30d0674e7dea5e5af0a39193b960ce0aa59b3f37 (diff)
downloadgst-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.c16
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);