From ca1b5d85765be8df27d0a87a45426c7925ce1f29 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Wed, 15 Jan 2014 09:02:33 +0000 Subject: [PATCH] gst-libav: fix context leaks A AVCodecContext needs cleaning up before being freed. Go through all of the allocations/setups to ensure none of them can leak a context or its contents. --- ext/libav/gstavauddec.c | 7 +++++-- ext/libav/gstavaudenc.c | 2 ++ ext/libav/gstavcfg.c | 4 +++- ext/libav/gstavdeinterlace.c | 1 + ext/libav/gstavviddec.c | 2 ++ ext/libav/gstavvidenc.c | 2 ++ 6 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ext/libav/gstavauddec.c b/ext/libav/gstavauddec.c index 3941a56..ecff389 100644 --- a/ext/libav/gstavauddec.c +++ b/ext/libav/gstavauddec.c @@ -150,9 +150,11 @@ gst_ffmpegauddec_finalize (GObject * object) { GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) object; - if (ffmpegdec->context != NULL) + if (ffmpegdec->context != NULL) { + gst_ffmpeg_avcodec_close (ffmpegdec->context); av_free (ffmpegdec->context); - ffmpegdec->context = NULL; + ffmpegdec->context = NULL; + } G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -199,6 +201,7 @@ gst_ffmpegauddec_start (GstAudioDecoder * decoder) oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec)); GST_OBJECT_LOCK (ffmpegdec); + gst_ffmpeg_avcodec_close (ffmpegdec->context); if (avcodec_get_context_defaults3 (ffmpegdec->context, oclass->in_plugin) < 0) { GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults"); GST_OBJECT_UNLOCK (ffmpegdec); diff --git a/ext/libav/gstavaudenc.c b/ext/libav/gstavaudenc.c index ec78999..39d9f38 100644 --- a/ext/libav/gstavaudenc.c +++ b/ext/libav/gstavaudenc.c @@ -191,6 +191,7 @@ gst_ffmpegaudenc_finalize (GObject * object) GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) object; /* clean up remaining allocated data */ + gst_ffmpeg_avcodec_close (ffmpegaudenc->context); av_free (ffmpegaudenc->context); G_OBJECT_CLASS (parent_class)->finalize (object); @@ -203,6 +204,7 @@ gst_ffmpegaudenc_start (GstAudioEncoder * encoder) GstFFMpegAudEncClass *oclass = (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc); + gst_ffmpeg_avcodec_close (ffmpegaudenc->context); if (avcodec_get_context_defaults3 (ffmpegaudenc->context, oclass->in_plugin) < 0) { GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults"); diff --git a/ext/libav/gstavcfg.c b/ext/libav/gstavcfg.c index b971314..a635fd4 100644 --- a/ext/libav/gstavcfg.c +++ b/ext/libav/gstavcfg.c @@ -827,8 +827,10 @@ gst_ffmpeg_cfg_install_property (GstFFMpegVidEncClass * klass, guint base) } } - if (ctx) + if (ctx) { + gst_ffmpeg_avcodec_close (ctx); av_free (ctx); + } } /* returns TRUE if it is a known property for this config system, diff --git a/ext/libav/gstavdeinterlace.c b/ext/libav/gstavdeinterlace.c index 7dd37d0..596477c 100644 --- a/ext/libav/gstavdeinterlace.c +++ b/ext/libav/gstavdeinterlace.c @@ -209,6 +209,7 @@ gst_ffmpegdeinterlace_sink_setcaps (GstPad * pad, GstCaps * caps) ctx->pix_fmt = PIX_FMT_NB; gst_ffmpeg_caps_with_codectype (AVMEDIA_TYPE_VIDEO, caps, ctx); if (ctx->pix_fmt == PIX_FMT_NB) { + gst_ffmpeg_avcodec_close (ctx); av_free (ctx); return FALSE; } diff --git a/ext/libav/gstavviddec.c b/ext/libav/gstavviddec.c index fe9c54a..d968ebf 100644 --- a/ext/libav/gstavviddec.c +++ b/ext/libav/gstavviddec.c @@ -268,6 +268,7 @@ gst_ffmpegviddec_finalize (GObject * object) GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) object; if (ffmpegdec->context != NULL) { + gst_ffmpeg_avcodec_close (ffmpegdec->context); av_free (ffmpegdec->context); ffmpegdec->context = NULL; } @@ -1591,6 +1592,7 @@ gst_ffmpegviddec_start (GstVideoDecoder * decoder) oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec)); GST_OBJECT_LOCK (ffmpegdec); + gst_ffmpeg_avcodec_close (ffmpegdec->context); if (avcodec_get_context_defaults3 (ffmpegdec->context, oclass->in_plugin) < 0) { GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults"); GST_OBJECT_UNLOCK (ffmpegdec); diff --git a/ext/libav/gstavvidenc.c b/ext/libav/gstavvidenc.c index 45c752c..d1d6d7e 100644 --- a/ext/libav/gstavvidenc.c +++ b/ext/libav/gstavvidenc.c @@ -263,6 +263,7 @@ gst_ffmpegvidenc_finalize (GObject * object) gst_ffmpeg_cfg_finalize (ffmpegenc); /* clean up remaining allocated data */ + gst_ffmpeg_avcodec_close (ffmpegenc->context); av_free (ffmpegenc->context); avcodec_free_frame (&ffmpegenc->picture); @@ -794,6 +795,7 @@ gst_ffmpegvidenc_start (GstVideoEncoder * encoder) (GstFFMpegVidEncClass *) G_OBJECT_GET_CLASS (ffmpegenc); /* close old session */ + gst_ffmpeg_avcodec_close (ffmpegenc->context); if (avcodec_get_context_defaults3 (ffmpegenc->context, oclass->in_plugin) < 0) { GST_DEBUG_OBJECT (ffmpegenc, "Failed to set context defaults"); return FALSE; -- 2.7.4