examples/qml: fix some leaks in the multisink example

A GstPad was being leaked and possibly the qmlglsink element depending
on if Qt runs the scenegraph thread again when destroying the example
video item.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6160>
This commit is contained in:
Matthew Waters 2024-02-21 19:11:59 +11:00 committed by Tim-Philipp Müller
parent 392fd00f4c
commit f1637a3601

View file

@ -230,6 +230,7 @@ void VideoItem::componentComplete()
if (window) { if (window) {
GstElement *glsink = gst_element_factory_make("qmlglsink", nullptr); GstElement *glsink = gst_element_factory_make("qmlglsink", nullptr);
Q_ASSERT(glsink); Q_ASSERT(glsink);
gst_object_ref_sink (glsink);
GstState current {GST_STATE_NULL}, pending {GST_STATE_NULL}, target {GST_STATE_NULL}; GstState current {GST_STATE_NULL}, pending {GST_STATE_NULL}, target {GST_STATE_NULL};
auto status = gst_element_get_state(_priv->pipeline, &current, &pending, 0); auto status = gst_element_get_state(_priv->pipeline, &current, &pending, 0);
@ -253,13 +254,12 @@ void VideoItem::componentComplete()
gst_element_set_state(_priv->pipeline, GST_STATE_NULL); gst_element_set_state(_priv->pipeline, GST_STATE_NULL);
glsink = GST_ELEMENT(gst_object_ref(glsink));
window->scheduleRenderJob(new RenderJob([=] { window->scheduleRenderJob(new RenderJob([=] {
g_object_set(glsink, "widget", videoItem, nullptr); g_object_set(glsink, "widget", videoItem, nullptr);
_priv->renderPad = gst_element_get_static_pad(glsink, "sink"); _priv->renderPad = gst_element_get_static_pad(glsink, "sink");
g_object_set(_priv->sink, "sink", glsink, nullptr); g_object_set(_priv->sink, "sink", glsink, nullptr);
gst_element_set_state(_priv->pipeline, target); gst_element_set_state(_priv->pipeline, target);
gst_object_unref (glsink);
}), }),
QQuickWindow::BeforeSynchronizingStage); QQuickWindow::BeforeSynchronizingStage);
} }
@ -272,20 +272,16 @@ void VideoItem::componentComplete()
void VideoItem::releaseResources() void VideoItem::releaseResources()
{ {
GstElement *sink { nullptr }; GstElement *sink { nullptr };
QQuickWindow *win { window() };
gst_element_set_state(_priv->pipeline, GST_STATE_NULL); gst_element_set_state(_priv->pipeline, GST_STATE_NULL);
g_object_get(_priv->sink, "sink", &sink, nullptr); g_object_get(_priv->sink, "sink", &sink, nullptr);
if (_priv->renderPad) { if (sink && _priv->renderPad) {
g_object_set(sink, "widget", nullptr, nullptr); g_object_set(sink, "widget", nullptr, nullptr);
_priv->renderPad = nullptr;
} }
connect(this, &VideoItem::destroyed, this, [sink, win] { gst_clear_object (&_priv->renderPad);
auto job = new RenderJob(std::bind(&gst_object_unref, sink)); gst_clear_object (&sink);
win->scheduleRenderJob(job, QQuickWindow::AfterSwapStage);
});
} }
void VideoItem::updateRect() void VideoItem::updateRect()
@ -318,6 +314,7 @@ void VideoItem::updateRect()
setRect(QRect(span / 2, 0, winWidth - span, winHeight)); setRect(QRect(span / 2, 0, winWidth - span, winHeight));
} }
setResolution(QSize(picWidth, picHeight)); setResolution(QSize(picWidth, picHeight));
gst_clear_caps(&caps);
} }
VideoItem::State VideoItem::state() const VideoItem::State VideoItem::state() const