From 023c6ebcb9d990042f0e9a750fd6238d22001022 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 20 Mar 2014 19:20:24 +0100 Subject: GStreamer: fix memory leaks. Many GStreamer objects were not properly managed or never released. Change-Id: I38b3854e8b9e2264b5b647f331d3bb16b886e2d6 Reviewed-by: Andrew den Exter --- .../mediacapture/qgstreameraudioencode.cpp | 2 ++ .../qgstreamercaptureserviceplugin.cpp | 1 + .../mediacapture/qgstreamercapturesession.cpp | 39 ++++++++++++++++++---- .../mediacapture/qgstreamervideoencode.cpp | 2 ++ 4 files changed, 38 insertions(+), 6 deletions(-) (limited to 'src/plugins/gstreamer/mediacapture') diff --git a/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp b/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp index 88c86b3b5..e735566dd 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp @@ -196,6 +196,8 @@ GstElement *QGstreamerAudioEncode::createEncoder() //qDebug() << "set caps filter:" << gst_caps_to_string(caps); g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL); + + gst_caps_unref(caps); } if (encoderElement) { diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp index de07d2707..657b9806f 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp @@ -261,6 +261,7 @@ void QGstreamerCaptureServicePlugin::updateSupportedMimeTypes() const } } } + gst_caps_unref(caps); } } gst_object_unref (factory); diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp index d7473327f..518a66bc0 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -64,9 +65,6 @@ QT_BEGIN_NAMESPACE -#define gstRef(element) { gst_object_ref(GST_OBJECT(element)); gst_object_sink(GST_OBJECT(element)); } -#define gstUnref(element) { if (element) { gst_object_unref(GST_OBJECT(element)); element = 0; } } - QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::CaptureMode captureMode, QObject *parent) :QObject(parent), m_state(StoppedState), @@ -97,7 +95,7 @@ QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::Cap m_passPrerollImage(false) { m_pipeline = gst_pipeline_new("media-capture-pipeline"); - gstRef(m_pipeline); + qt_gst_object_ref_sink(m_pipeline); m_bus = gst_element_get_bus(m_pipeline); m_busHelper = new QGstreamerBusHelper(m_bus, this); @@ -116,6 +114,7 @@ QGstreamerCaptureSession::~QGstreamerCaptureSession() { setState(StoppedState); gst_element_set_state(m_pipeline, GST_STATE_NULL); + gst_object_unref(GST_OBJECT(m_bus)); gst_object_unref(GST_OBJECT(m_pipeline)); } @@ -160,6 +159,7 @@ GstElement *QGstreamerCaptureSession::buildEncodeBin() gst_bin_add(GST_BIN(encodeBin), audioEncoder); if (!gst_element_link_many(audioConvert, audioQueue, m_audioVolume, audioEncoder, muxer, NULL)) { + m_audioVolume = 0; gst_object_unref(encodeBin); return 0; } @@ -333,6 +333,7 @@ GstElement *QGstreamerCaptureSession::buildVideoPreview() g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL); + gst_caps_unref(caps); } // add ghostpads @@ -501,6 +502,7 @@ GstElement *QGstreamerCaptureSession::buildImageCapture() GstPad *pad = gst_element_get_static_pad(queue, "src"); Q_ASSERT(pad); gst_pad_add_buffer_probe(pad, G_CALLBACK(passImageFilter), this); + gst_object_unref(GST_OBJECT(pad)); g_object_set(G_OBJECT(sink), "signal-handoffs", TRUE, NULL); g_signal_connect(G_OBJECT(sink), "handoff", @@ -531,6 +533,7 @@ void QGstreamerCaptureSession::captureImage(int requestId, const QString &fileNa #define REMOVE_ELEMENT(element) { if (element) {gst_bin_remove(GST_BIN(m_pipeline), element); element = 0;} } +#define UNREF_ELEMENT(element) { if (element) { gst_object_unref(GST_OBJECT(element)); element = 0; } } bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMode newMode) { @@ -562,6 +565,9 @@ bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMo if (ok) { gst_bin_add_many(GST_BIN(m_pipeline), m_audioSrc, m_audioPreview, NULL); ok &= gst_element_link(m_audioSrc, m_audioPreview); + } else { + UNREF_ELEMENT(m_audioSrc); + UNREF_ELEMENT(m_audioPreview); } } if (m_captureMode & Video || m_captureMode & Image) { @@ -582,6 +588,12 @@ bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMo ok &= gst_element_link(m_videoTee, m_videoPreviewQueue); ok &= gst_element_link(m_videoPreviewQueue, m_videoPreview); ok &= gst_element_link(m_videoTee, m_imageCaptureBin); + } else { + UNREF_ELEMENT(m_videoSrc); + UNREF_ELEMENT(m_videoTee); + UNREF_ELEMENT(m_videoPreviewQueue); + UNREF_ELEMENT(m_videoPreview); + UNREF_ELEMENT(m_imageCaptureBin); } } break; @@ -631,6 +643,11 @@ bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMo ok &= gst_element_link(m_audioTee, m_audioPreviewQueue); ok &= gst_element_link(m_audioPreviewQueue, m_audioPreview); ok &= gst_element_link(m_audioTee, m_encodeBin); + } else { + UNREF_ELEMENT(m_audioSrc); + UNREF_ELEMENT(m_audioPreview); + UNREF_ELEMENT(m_audioTee); + UNREF_ELEMENT(m_audioPreviewQueue); } } @@ -648,6 +665,11 @@ bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMo ok &= gst_element_link(m_videoSrc, m_videoTee); ok &= gst_element_link(m_videoTee, m_videoPreviewQueue); ok &= gst_element_link(m_videoPreviewQueue, m_videoPreview); + } else { + UNREF_ELEMENT(m_videoSrc); + UNREF_ELEMENT(m_videoTee); + UNREF_ELEMENT(m_videoPreviewQueue); + UNREF_ELEMENT(m_videoPreview); } if (ok && (m_captureMode & Video)) @@ -917,6 +939,7 @@ void QGstreamerCaptureSession::setMetaData(const QMap &dat } } + gst_iterator_free(elements); } } @@ -1096,8 +1119,10 @@ void QGstreamerCaptureSession::removeAudioBufferProbe() return; GstPad *pad = getAudioProbePad(); - if (pad) + if (pad) { gst_pad_remove_buffer_probe(pad, m_audioBufferProbeId); + gst_object_unref(G_OBJECT(pad)); + } m_audioBufferProbeId = -1; } @@ -1107,8 +1132,10 @@ void QGstreamerCaptureSession::addAudioBufferProbe() Q_ASSERT(m_audioBufferProbeId == -1); GstPad *pad = getAudioProbePad(); - if (pad) + if (pad) { m_audioBufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padAudioBufferProbe), this); + gst_object_unref(G_OBJECT(pad)); + } } QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp b/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp index 73112491f..c29735037 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp @@ -286,6 +286,8 @@ GstElement *QGstreamerVideoEncode::createEncoder() //qDebug() << "set video caps filter:" << gst_caps_to_string(caps); g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL); + + gst_caps_unref(caps); } return GST_ELEMENT(encoderBin); -- cgit v1.2.3