summaryrefslogtreecommitdiffstats
path: root/src/multimedia/platform
diff options
context:
space:
mode:
authorPiotr Srebrny <piotr.srebrny@qt.io>2021-09-30 14:00:50 +0200
committerPiotr Srebrny <piotr.srebrny@qt.io>2021-10-01 17:29:37 +0000
commit078701abf256fb91cd9824cc8e6d48556200c1ef (patch)
tree9462e27fe267760e4bd88d0f08fd5aeb50155f11 /src/multimedia/platform
parent0964df62a9d6e1b2cdeeb201f4e06481c3f5a760 (diff)
GStreamer: remove an element from a pipeline before setState(NULL)
If an element is a part of a pipeline bin, the bin tries to synchronize its state with its own. Thus, after setting the element state to NULL, the state can be set back to READY, PAUSE, or PLAYING before it is removed from the pipeline. This patch first removes an element from the pipeline and then sets its state to NULL to avoid this race. Pick-to: 6.2 Change-Id: Ied9cd037fabab19682a53c5ab3d0c7335c58d9c9 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/multimedia/platform')
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp6
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp21
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp4
3 files changed, 16 insertions, 15 deletions
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp b/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp
index 36e0823d8..56cf0a9a4 100644
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp
+++ b/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp
@@ -95,8 +95,8 @@ void QGstreamerVideoOutput::setVideoSink(QVideoSink *sink)
gstPipeline.beginConfig();
if (!videoSink.isNull()) {
- videoSink.setStateSync(GST_STATE_NULL);
gstVideoOutput.remove(videoSink);
+ videoSink.setStateSync(GST_STATE_NULL);
}
videoSink = gstSink;
gstVideoOutput.add(videoSink);
@@ -104,7 +104,7 @@ void QGstreamerVideoOutput::setVideoSink(QVideoSink *sink)
videoConvert.link(videoSink);
GstEvent *event = gst_event_new_reconfigure();
gst_element_send_event(videoSink.element(), event);
- videoSink.setState(GST_STATE_PAUSED);
+ videoSink.syncStateWithParent();
doLinkSubtitleStream();
@@ -141,8 +141,8 @@ void QGstreamerVideoOutput::linkSubtitleStream(QGstElement src)
void QGstreamerVideoOutput::doLinkSubtitleStream()
{
if (!subtitleSink.isNull()) {
- subtitleSink.setStateSync(GST_STATE_NULL);
gstPipeline.remove(subtitleSink);
+ subtitleSink.setStateSync(GST_STATE_NULL);
subtitleSink = {};
}
if (!m_videoSink || subtitleSrc.isNull())
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp
index 6a0f103a4..3c1793b15 100644
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp
+++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp
@@ -119,14 +119,15 @@ void QGstreamerMediaCapture::setCamera(QPlatformCamera *camera)
unlinkTeeFromPad(gstVideoTee, imageCaptureSink);
auto camera = gstCamera->gstElement();
- camera.setStateSync(GST_STATE_NULL);
- gstVideoTee.setStateSync(GST_STATE_NULL);
- gstVideoOutput->gstElement().setStateSync(GST_STATE_NULL);
gstPipeline.remove(camera);
gstPipeline.remove(gstVideoTee);
gstPipeline.remove(gstVideoOutput->gstElement());
+ camera.setStateSync(GST_STATE_NULL);
+ gstVideoTee.setStateSync(GST_STATE_NULL);
+ gstVideoOutput->gstElement().setStateSync(GST_STATE_NULL);
+
gstVideoTee = {};
gstCamera->setCaptureSession(nullptr);
}
@@ -168,8 +169,8 @@ void QGstreamerMediaCapture::setImageCapture(QPlatformImageCapture *imageCapture
if (m_imageCapture) {
unlinkTeeFromPad(gstVideoTee, imageCaptureSink);
- m_imageCapture->gstElement().setStateSync(GST_STATE_NULL);
gstPipeline.remove(m_imageCapture->gstElement());
+ m_imageCapture->gstElement().setStateSync(GST_STATE_NULL);
imageCaptureSink = {};
m_imageCapture->setCaptureSession(nullptr);
}
@@ -245,16 +246,16 @@ void QGstreamerMediaCapture::unlinkEncoder()
if (!encoderVideoCapsFilter.isNull()) {
encoderVideoCapsFilter.src().unlinkPeer();
unlinkTeeFromPad(gstVideoTee, encoderVideoCapsFilter.sink());
- encoderVideoCapsFilter.setStateSync(GST_STATE_NULL);
gstPipeline.remove(encoderVideoCapsFilter);
+ encoderVideoCapsFilter.setStateSync(GST_STATE_NULL);
encoderVideoCapsFilter = {};
}
if (!encoderAudioCapsFilter.isNull()) {
encoderAudioCapsFilter.src().unlinkPeer();
unlinkTeeFromPad(gstAudioTee, encoderAudioCapsFilter.sink());
- encoderAudioCapsFilter.setStateSync(GST_STATE_NULL);
gstPipeline.remove(encoderAudioCapsFilter);
+ encoderAudioCapsFilter.setStateSync(GST_STATE_NULL);
encoderAudioCapsFilter = {};
}
@@ -272,14 +273,14 @@ void QGstreamerMediaCapture::setAudioInput(QPlatformAudioInput *input)
if (gstAudioOutput) {
unlinkTeeFromPad(gstAudioTee, gstAudioOutput->gstElement().staticPad("sink"));
- gstAudioOutput->gstElement().setStateSync(GST_STATE_NULL);
gstPipeline.remove(gstAudioOutput->gstElement());
+ gstAudioOutput->gstElement().setStateSync(GST_STATE_NULL);
}
- gstAudioInput->gstElement().setStateSync(GST_STATE_NULL);
gstPipeline.remove(gstAudioInput->gstElement());
- gstAudioTee.setStateSync(GST_STATE_NULL);
gstPipeline.remove(gstAudioTee);
+ gstAudioInput->gstElement().setStateSync(GST_STATE_NULL);
+ gstAudioTee.setStateSync(GST_STATE_NULL);
gstAudioTee = {};
}
@@ -317,8 +318,8 @@ void QGstreamerMediaCapture::setAudioOutput(QPlatformAudioOutput *output)
if (gstAudioOutput && gstAudioInput) {
// If audio input is set, the output is in the pipeline
unlinkTeeFromPad(gstAudioTee, gstAudioOutput->gstElement().staticPad("sink"));
- gstAudioOutput->gstElement().setStateSync(GST_STATE_NULL);
gstPipeline.remove(gstAudioOutput->gstElement());
+ gstAudioOutput->gstElement().setStateSync(GST_STATE_NULL);
}
gstAudioOutput = static_cast<QGstreamerAudioOutput *>(output);
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp
index 618544d0d..0461b9576 100644
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp
+++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp
@@ -390,10 +390,10 @@ void QGstreamerMediaEncoder::finalize()
qCDebug(qLcMediaEncoder) << "finalize";
- gstEncoder.setStateSync(GST_STATE_NULL);
- gstFileSink.setStateSync(GST_STATE_NULL);
gstPipeline.remove(gstEncoder);
gstPipeline.remove(gstFileSink);
+ gstEncoder.setStateSync(GST_STATE_NULL);
+ gstFileSink.setStateSync(GST_STATE_NULL);
gstFileSink = {};
gstEncoder = {};
m_finalizing = false;