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 --- src/gsttools/qgstappsrc.cpp | 4 +++ src/gsttools/qgstcodecsinfo.cpp | 6 +++- src/gsttools/qgstreamergltexturerenderer.cpp | 1 + src/gsttools/qgstreamervideorenderer.cpp | 4 +-- src/gsttools/qgstreamervideowidget.cpp | 4 +-- src/gsttools/qgstreamervideowindow.cpp | 6 ++-- src/gsttools/qgstutils.cpp | 18 ++++++++++ src/multimedia/gsttools_headers/qgstutils_p.h | 2 ++ .../qgstreameraudiodecoderserviceplugin.cpp | 1 + .../audiodecoder/qgstreameraudiodecodersession.cpp | 5 ++- .../gstreamer/camerabin/camerabinaudioencoder.cpp | 14 +++++--- .../gstreamer/camerabin/camerabincontainer.cpp | 14 +++++--- .../gstreamer/camerabin/camerabinrecorder.cpp | 12 ++++--- .../gstreamer/camerabin/camerabinsession.cpp | 22 +++++++----- .../gstreamer/camerabin/camerabinvideoencoder.cpp | 2 ++ .../mediacapture/qgstreameraudioencode.cpp | 2 ++ .../qgstreamercaptureserviceplugin.cpp | 1 + .../mediacapture/qgstreamercapturesession.cpp | 39 ++++++++++++++++++---- .../mediacapture/qgstreamervideoencode.cpp | 2 ++ .../mediaplayer/qgstreamerplayersession.cpp | 16 ++++++--- 20 files changed, 134 insertions(+), 41 deletions(-) diff --git a/src/gsttools/qgstappsrc.cpp b/src/gsttools/qgstappsrc.cpp index 8917bda85..2c9f64c34 100644 --- a/src/gsttools/qgstappsrc.cpp +++ b/src/gsttools/qgstappsrc.cpp @@ -72,7 +72,11 @@ bool QGstAppSrc::setup(GstElement* appsrc) if (m_setup || m_stream == 0 || appsrc == 0) return false; + if (m_appSrc) + gst_object_unref(G_OBJECT(m_appSrc)); + m_appSrc = GST_APP_SRC(appsrc); + gst_object_ref(G_OBJECT(m_appSrc)); gst_app_src_set_callbacks(m_appSrc, (GstAppSrcCallbacks*)&m_callbacks, this, (GDestroyNotify)&QGstAppSrc::destroy_notify); g_object_get(G_OBJECT(m_appSrc), "max-bytes", &m_maxBytes, NULL); diff --git a/src/gsttools/qgstcodecsinfo.cpp b/src/gsttools/qgstcodecsinfo.cpp index ade79fd44..6db9b016a 100644 --- a/src/gsttools/qgstcodecsinfo.cpp +++ b/src/gsttools/qgstcodecsinfo.cpp @@ -93,6 +93,9 @@ QGstCodecsInfo::QGstCodecsInfo(QGstCodecsInfo::ElementType elementType) gst_caps_remove_structure(caps, 0); } + + gst_caps_unref(caps); + gst_caps_unref(allCaps); #else Q_UNUSED(elementType); #endif // GST_CHECK_VERSION(0,10,31) @@ -143,7 +146,7 @@ GstCaps* QGstCodecsInfo::supportedElementCaps(GstElementFactoryListType elementT padTemplates = padTemplates->next; if (padTemplate->direction == padDirection) { - const GstCaps *caps = gst_static_caps_get(&padTemplate->static_caps); + GstCaps *caps = gst_static_caps_get(&padTemplate->static_caps); for (uint i=0; i +#include #include #include @@ -62,8 +63,7 @@ GstElement *QGstreamerVideoRenderer::videoSink() { if (!m_videoSink && m_surface) { m_videoSink = QVideoSurfaceGstSink::createSink(m_surface); - gst_object_ref(GST_OBJECT(m_videoSink)); //Take ownership - gst_object_sink(GST_OBJECT(m_videoSink)); + qt_gst_object_ref_sink(GST_OBJECT(m_videoSink)); //Take ownership } return reinterpret_cast(m_videoSink); diff --git a/src/gsttools/qgstreamervideowidget.cpp b/src/gsttools/qgstreamervideowidget.cpp index 8297040c1..7e11bfb21 100644 --- a/src/gsttools/qgstreamervideowidget.cpp +++ b/src/gsttools/qgstreamervideowidget.cpp @@ -137,8 +137,7 @@ void QGstreamerVideoWidgetControl::createVideoWidget() if (!m_videoSink) m_videoSink = gst_element_factory_make ("ximagesink", NULL); - gst_object_ref (GST_OBJECT (m_videoSink)); //Take ownership - gst_object_sink (GST_OBJECT (m_videoSink)); + qt_gst_object_ref_sink(GST_OBJECT (m_videoSink)); //Take ownership } @@ -219,6 +218,7 @@ void QGstreamerVideoWidgetControl::updateNativeVideoSize() //find video native size to update video widget size hint GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); GstCaps *caps = gst_pad_get_negotiated_caps(pad); + gst_object_unref(GST_OBJECT(pad)); if (caps) { m_widget->setNativeSize(QGstUtils::capsCorrectedResolution(caps)); diff --git a/src/gsttools/qgstreamervideowindow.cpp b/src/gsttools/qgstreamervideowindow.cpp index 70d321575..2dc351065 100644 --- a/src/gsttools/qgstreamervideowindow.cpp +++ b/src/gsttools/qgstreamervideowindow.cpp @@ -63,11 +63,11 @@ QGstreamerVideoWindow::QGstreamerVideoWindow(QObject *parent, const char *elemen m_videoSink = gst_element_factory_make("xvimagesink", NULL); if (m_videoSink) { - gst_object_ref(GST_OBJECT(m_videoSink)); //Take ownership - gst_object_sink(GST_OBJECT(m_videoSink)); + qt_gst_object_ref_sink(GST_OBJECT(m_videoSink)); //Take ownership GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this); + gst_object_unref(GST_OBJECT(pad)); } } @@ -114,6 +114,7 @@ bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message) GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this); + gst_object_unref(GST_OBJECT(pad)); return true; } @@ -319,6 +320,7 @@ void QGstreamerVideoWindow::updateNativeVideoSize() //find video native size to update video widget size hint GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); GstCaps *caps = gst_pad_get_negotiated_caps(pad); + gst_object_unref(GST_OBJECT(pad)); if (caps) { m_nativeSize = QGstUtils::capsCorrectedResolution(caps); diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp index e93b46753..41bd005bd 100644 --- a/src/gsttools/qgstutils.cpp +++ b/src/gsttools/qgstutils.cpp @@ -401,4 +401,22 @@ QMultimedia::SupportEstimate QGstUtils::hasSupport(const QString &mimeType, return QMultimedia::MaybeSupported; } +void qt_gst_object_ref_sink(gpointer object) +{ +#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 24) + gst_object_ref_sink(object); +#else + g_return_if_fail (GST_IS_OBJECT(object)); + + GST_OBJECT_LOCK(object); + if (G_LIKELY(GST_OBJECT_IS_FLOATING(object))) { + GST_OBJECT_FLAG_UNSET(object, GST_OBJECT_FLOATING); + GST_OBJECT_UNLOCK(object); + } else { + GST_OBJECT_UNLOCK(object); + gst_object_ref(object); + } +#endif +} + QT_END_NAMESPACE diff --git a/src/multimedia/gsttools_headers/qgstutils_p.h b/src/multimedia/gsttools_headers/qgstutils_p.h index 568580264..eea1e15d9 100644 --- a/src/multimedia/gsttools_headers/qgstutils_p.h +++ b/src/multimedia/gsttools_headers/qgstutils_p.h @@ -78,6 +78,8 @@ namespace QGstUtils { const QSet &supportedMimeTypeSet); } +void qt_gst_object_ref_sink(gpointer object); + QT_END_NAMESPACE #endif diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp index d34c10e10..3085d1391 100644 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp +++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp @@ -147,6 +147,7 @@ void QGstreamerAudioDecoderServicePlugin::updateSupportedMimeTypes() const } } } + gst_caps_unref(caps); } } gst_object_unref (factory); diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp index 5bcf1aa54..9f1a765ec 100644 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp +++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp @@ -158,6 +158,8 @@ void QGstreamerAudioDecoderSession::configureAppSrcElement(GObject* object, GObj if (!self->appsrc()->setup(appsrc)) qWarning()<<"Could not setup appsrc element"; + + g_object_unref(G_OBJECT(appsrc)); } #endif @@ -372,7 +374,8 @@ void QGstreamerAudioDecoderSession::start() if (mFormat.isValid()) { setAudioFlags(false); GstCaps *caps = QGstUtils::capsForAudioFormat(mFormat); - gst_app_sink_set_caps(m_appSink, caps); // appsink unrefs caps + gst_app_sink_set_caps(m_appSink, caps); + gst_caps_unref(caps); } else { // We want whatever the native audio format is setAudioFlags(true); diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp index 0fa854cc5..332891a47 100644 --- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp @@ -114,11 +114,15 @@ GstEncodingProfile *CameraBinAudioEncoder::createProfile() else caps = gst_caps_from_string(codec.toLatin1()); - return (GstEncodingProfile *)gst_encoding_audio_profile_new( - caps, - !preset.isEmpty() ? preset.toLatin1().constData() : NULL, //preset - NULL, //restriction - 0); //presence + GstEncodingProfile *profile = (GstEncodingProfile *)gst_encoding_audio_profile_new( + caps, + !preset.isEmpty() ? preset.toLatin1().constData() : NULL, //preset + NULL, //restriction + 0); //presence + + gst_caps_unref(caps); + + return profile; } QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabincontainer.cpp b/src/plugins/gstreamer/camerabin/camerabincontainer.cpp index 4c2a3bda9..44eb36818 100644 --- a/src/plugins/gstreamer/camerabin/camerabincontainer.cpp +++ b/src/plugins/gstreamer/camerabin/camerabincontainer.cpp @@ -124,11 +124,15 @@ GstEncodingContainerProfile *CameraBinContainer::createProfile() caps = gst_caps_from_string(format.toLatin1()); } - return (GstEncodingContainerProfile *)gst_encoding_container_profile_new( - "camerabin2_profile", - (gchar *)"custom camera profile", - caps, - NULL); //preset + GstEncodingContainerProfile *profile = (GstEncodingContainerProfile *)gst_encoding_container_profile_new( + "camerabin2_profile", + (gchar *)"custom camera profile", + caps, + NULL); //preset + + gst_caps_unref(caps); + + return profile; } /*! diff --git a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp index 4ac0d942e..7cef82a69 100644 --- a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp @@ -191,10 +191,14 @@ GstEncodingContainerProfile *CameraBinRecorder::videoProfile() GstEncodingProfile *audioProfile = m_session->audioEncodeControl()->createProfile(); GstEncodingProfile *videoProfile = m_session->videoEncodeControl()->createProfile(); - if (audioProfile) - gst_encoding_container_profile_add_profile(containerProfile, audioProfile); - if (videoProfile) - gst_encoding_container_profile_add_profile(containerProfile, videoProfile); + if (audioProfile) { + if (!gst_encoding_container_profile_add_profile(containerProfile, audioProfile)) + gst_encoding_profile_unref(audioProfile); + } + if (videoProfile) { + if (!gst_encoding_container_profile_add_profile(containerProfile, videoProfile)) + gst_encoding_profile_unref(videoProfile); + } } return containerProfile; diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index 8ca6bfd83..6e3448ffe 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -61,6 +61,7 @@ #include "camerabincapturebufferformat.h" #include #include +#include #include #ifdef HAVE_GST_PHOTOGRAPHY @@ -108,9 +109,6 @@ #define CAMERABIN_IMAGE_MODE 1 #define CAMERABIN_VIDEO_MODE 2 -#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; } } - #define PREVIEW_CAPS_4_3 \ "video/x-raw-rgb, width = (int) 640, height = (int) 480" @@ -146,7 +144,7 @@ CameraBinSession::CameraBinSession(QObject *parent) { m_camerabin = gst_element_factory_make("camerabin2", "camerabin2"); g_signal_connect(G_OBJECT(m_camerabin), "notify::idle", G_CALLBACK(updateBusyStatus), this); - gstRef(m_camerabin); + qt_gst_object_ref_sink(m_camerabin); m_bus = gst_element_get_bus(m_camerabin); @@ -192,9 +190,11 @@ CameraBinSession::~CameraBinSession() gst_element_set_state(m_camerabin, GST_STATE_NULL); gst_element_get_state(m_camerabin, NULL, NULL, GST_CLOCK_TIME_NONE); - gstUnref(m_camerabin); - gstUnref(m_viewfinderElement); + gst_object_unref(GST_OBJECT(m_bus)); + gst_object_unref(GST_OBJECT(m_camerabin)); } + if (m_viewfinderElement) + gst_object_unref(GST_OBJECT(m_viewfinderElement)); } #ifdef HAVE_GST_PHOTOGRAPHY @@ -239,7 +239,7 @@ bool CameraBinSession::setupCameraBin() qWarning() << "Staring camera without viewfinder available"; m_viewfinderElement = gst_element_factory_make("fakesink", NULL); } - gst_object_ref(GST_OBJECT(m_viewfinderElement)); + qt_gst_object_ref_sink(GST_OBJECT(m_viewfinderElement)); gst_element_set_state(m_camerabin, GST_STATE_NULL); g_object_set(G_OBJECT(m_camerabin), VIEWFINDER_SINK_PROPERTY, m_viewfinderElement, NULL); } @@ -438,6 +438,9 @@ GstElement *CameraBinSession::buildCameraSource() if (m_videoSrc != videoSrc) g_object_set(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, m_videoSrc, NULL); + if (videoSrc) + gst_object_unref(GST_OBJECT(videoSrc)); + return m_videoSrc; } @@ -680,10 +683,12 @@ void CameraBinSession::setState(QCamera::State newState) m_recorderControl->applySettings(); + GstEncodingContainerProfile *profile = m_recorderControl->videoProfile(); g_object_set (G_OBJECT(m_camerabin), "video-profile", - m_recorderControl->videoProfile(), + profile, NULL); + gst_encoding_profile_unref(profile); setAudioCaptureCaps(); @@ -803,6 +808,7 @@ void CameraBinSession::setMetaData(const QMap &data) } } } + gst_iterator_free(elements); } } diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp index cb479d8df..146e150ec 100644 --- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp @@ -175,6 +175,8 @@ GstEncodingProfile *CameraBinVideoEncoder::createProfile() NULL, //restriction 1); //presence + gst_caps_unref(caps); + gst_encoding_video_profile_set_pass(profile, 0); gst_encoding_video_profile_set_variableframerate(profile, TRUE); 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); diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp index f5b4be72b..f4ac59420 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -157,17 +158,20 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) } } - m_videoOutputBin = gst_bin_new("video-output-bin"); - gst_object_ref(GST_OBJECT(m_videoOutputBin)); - - m_videoIdentity = GST_ELEMENT(g_object_new(gst_video_connector_get_type(), 0)); + m_videoIdentity = GST_ELEMENT(g_object_new(gst_video_connector_get_type(), 0)); // floating ref g_signal_connect(G_OBJECT(m_videoIdentity), "connection-failed", G_CALLBACK(insertColorSpaceElement), (gpointer)this); + m_colorSpace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-vo"); - gst_object_ref(GST_OBJECT(m_colorSpace)); + // might not get a parent, take ownership to avoid leak + qt_gst_object_ref_sink(GST_OBJECT(m_colorSpace)); m_nullVideoSink = gst_element_factory_make("fakesink", NULL); g_object_set(G_OBJECT(m_nullVideoSink), "sync", true, NULL); gst_object_ref(GST_OBJECT(m_nullVideoSink)); + + m_videoOutputBin = gst_bin_new("video-output-bin"); + // might not get a parent, take ownership to avoid leak + qt_gst_object_ref_sink(GST_OBJECT(m_videoOutputBin)); gst_bin_add_many(GST_BIN(m_videoOutputBin), m_videoIdentity, m_nullVideoSink, NULL); gst_element_link(m_videoIdentity, m_nullVideoSink); @@ -238,6 +242,8 @@ void QGstreamerPlayerSession::configureAppSrcElement(GObject* object, GObject *o if (!self->appsrc()->setup(appsrc)) qWarning()<<"Could not setup appsrc element"; + + g_object_unref(G_OBJECT(appsrc)); } #endif -- cgit v1.2.1