diff options
author | Yoann Lopes <yoann.lopes@digia.com> | 2014-03-20 19:20:24 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-21 19:16:09 +0100 |
commit | 023c6ebcb9d990042f0e9a750fd6238d22001022 (patch) | |
tree | b98e068ccbdae0a587179d657541cc857c9daf0c /src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp | |
parent | 60ba0afbde0ef53a12afb6c755ca6fd64aabf5da (diff) | |
download | qtmultimedia-023c6ebcb9d990042f0e9a750fd6238d22001022.tar.gz |
GStreamer: fix memory leaks.
Many GStreamer objects were not properly managed or never released.
Change-Id: I38b3854e8b9e2264b5b647f331d3bb16b886e2d6
Reviewed-by: Andrew den Exter <andrew.den.exter@qinetic.com.au>
Diffstat (limited to 'src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp')
-rw-r--r-- | src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp | 39 |
1 files changed, 33 insertions, 6 deletions
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 <private/qgstreamervideorendererinterface_p.h> #include <private/qgstreameraudioprobecontrol_p.h> #include <private/qgstreamerbushelper_p.h> +#include <private/qgstutils_p.h> #include <gst/gsttagsetter.h> #include <gst/gstversion.h> @@ -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<QByteArray, QVariant> &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 |