diff --git a/media-plugins/gst-plugins-libav/files/gst-plugins-libav-1.2.4-fix-memory-leak.patch b/media-plugins/gst-plugins-libav/files/gst-plugins-libav-1.2.4-fix-memory-leak.patch new file mode 100644 index 00000000..6745e800 --- /dev/null +++ b/media-plugins/gst-plugins-libav/files/gst-plugins-libav-1.2.4-fix-memory-leak.patch @@ -0,0 +1,96 @@ +--- ext/libav/gstavviddec.c ++++ ext/libav/gstavviddec.c +@@ -523,6 +523,7 @@ open_failed: + + typedef struct + { ++ GstFFMpegVidDec *ffmpegdec; + GstVideoCodecFrame *frame; + gboolean mapped; + GstVideoFrame vframe; +@@ -530,13 +531,17 @@ typedef struct + } GstFFMpegVidDecVideoFrame; + + static GstFFMpegVidDecVideoFrame * +-gst_ffmpegviddec_video_frame_new (GstVideoCodecFrame * frame) ++gst_ffmpegviddec_video_frame_new (GstFFMpegVidDec * ffmpegdec, ++ GstVideoCodecFrame * frame) + { + GstFFMpegVidDecVideoFrame *dframe; + + dframe = g_slice_new0 (GstFFMpegVidDecVideoFrame); ++ dframe->ffmpegdec = ffmpegdec; + dframe->frame = frame; + ++ GST_DEBUG_OBJECT (ffmpegdec, "new video frame %p", dframe); ++ + return dframe; + } + +@@ -544,6 +549,8 @@ static void + gst_ffmpegviddec_video_frame_free (GstFFMpegVidDec * ffmpegdec, + GstFFMpegVidDecVideoFrame * frame) + { ++ GST_DEBUG_OBJECT (ffmpegdec, "free video frame %p", frame); ++ + if (frame->mapped) + gst_video_frame_unmap (&frame->vframe); + gst_video_decoder_release_frame (GST_VIDEO_DECODER (ffmpegdec), frame->frame); +@@ -551,6 +558,14 @@ gst_ffmpegviddec_video_frame_free (GstFFMpegVidDec * ffmpegdec, + g_slice_free (GstFFMpegVidDecVideoFrame, frame); + } + ++static void ++dummy_free_buffer (void *opaque, uint8_t * data) ++{ ++ GstFFMpegVidDecVideoFrame *frame = opaque; ++ ++ gst_ffmpegviddec_video_frame_free (frame->ffmpegdec, frame); ++} ++ + /* 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 +@@ -589,7 +604,8 @@ gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture) + goto duplicate_frame; + + /* GstFFMpegVidDecVideoFrame receives the frame ref */ +- picture->opaque = dframe = gst_ffmpegviddec_video_frame_new (frame); ++ picture->opaque = dframe = ++ gst_ffmpegviddec_video_frame_new (ffmpegdec, frame); + + GST_DEBUG_OBJECT (ffmpegdec, "storing opaque %p", dframe); + +@@ -695,12 +711,20 @@ invalid_frame: + fallback: + { + int c; ++ gboolean first = TRUE; + int ret = avcodec_default_get_buffer (context, picture); + + GST_LOG_OBJECT (ffmpegdec, "performing fallback alloc"); +- for (c = 0; c < AV_NUM_DATA_POINTERS; c++) ++ for (c = 0; c < AV_NUM_DATA_POINTERS; c++) { + ffmpegdec->stride[c] = picture->linesize[c]; + ++ if (picture->buf[c] == NULL && first) { ++ picture->buf[c] = ++ av_buffer_create (NULL, 0, dummy_free_buffer, dframe, 0); ++ first = FALSE; ++ } ++ } ++ + return ret; + } + duplicate_frame: +@@ -1684,8 +1718,8 @@ gst_ffmpegviddec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query) + avcodec_align_dimensions2 (ffmpegdec->context, &width, &height, + linesize_align); + edge = +- ffmpegdec->context-> +- flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width (); ++ ffmpegdec-> ++ context->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width (); + /* increase the size for the padding */ + width += edge << 1; + height += edge << 1; diff --git a/media-plugins/gst-plugins-libav/gst-plugins-libav-1.2.4.ebuild b/media-plugins/gst-plugins-libav/gst-plugins-libav-1.2.4.ebuild index b9d19f44..8ebe512c 100644 --- a/media-plugins/gst-plugins-libav/gst-plugins-libav-1.2.4.ebuild +++ b/media-plugins/gst-plugins-libav/gst-plugins-libav-1.2.4.ebuild @@ -40,6 +40,7 @@ src_prepare() { -e 's/ CodecID/ AVCodecID/g' \ ext/libav/*.{c,h} || die epatch "${FILESDIR}/${P}-ffmpeg2.patch" + epatch "${FILESDIR}/${P}-fix-memory-leak.patch" fi }