diff options
author | Lars Knoll <lars.knoll@qt.io> | 2021-07-28 15:23:48 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2021-07-30 10:18:11 +0200 |
commit | c1fefff0cd436a4225670c6636275bb967025a39 (patch) | |
tree | d5f9f4a28c7bdf7aececd4c2dbc70ded4bc4dc97 | |
parent | 6fc0b29b053492c1071be80059547f54af8d15b5 (diff) |
Simplify pipeline manipulation handling for gstreamer
Add begin/endConfig() methods to QGstPipeline that can be nested if
required. Those methods take care to pause the pipeline before changing
it's layout, and restarting playback afterwards if required.
Ported QGStreamerAudioInput over to use this instead of trying to change
the pipeline without pausing.
Adjust all other places where we do pipeline changes to use the new calls.
Change-Id: Ibe1b6c94a761bcc402c1c16368cc471d3efb2db9
Reviewed-by: André de la Rocha <andre.rocha@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
13 files changed, 122 insertions, 129 deletions
diff --git a/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp b/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp index e240b52e2..f6026a6fa 100644 --- a/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp @@ -66,6 +66,9 @@ public: mutable qint64 m_position = 0; double m_rate = 1.; + int m_configCounter = 0; + GstState m_savedState = GST_STATE_NULL; + QGstPipelinePrivate(GstBus* bus, QObject* parent = 0); ~QGstPipelinePrivate(); @@ -262,6 +265,38 @@ void QGstPipeline::removeMessageFilter(QGstreamerBusMessageFilter *filter) d->removeMessageFilter(filter); } +void QGstPipeline::beginConfig() +{ + if (!d) + return; + Q_ASSERT(!isNull()); + + ++d->m_configCounter; + if (d->m_configCounter > 1) + return; + + d->m_savedState = state(); + if (d->m_savedState == GST_STATE_PLAYING) + setStateSync(GST_STATE_PAUSED); +} + +void QGstPipeline::endConfig() +{ + if (!d) + return; + Q_ASSERT(!isNull()); + + --d->m_configCounter; + if (d->m_configCounter) + return; + + if (d->m_savedState != GST_STATE_NULL) + flush(); + if (d->m_savedState == GST_STATE_PLAYING) + setStateSync(GST_STATE_PLAYING); + d->m_savedState = GST_STATE_NULL; +} + void QGstPipeline::flush() { seek(position(), d->m_rate); diff --git a/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h b/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h index d49a318cb..019925af0 100644 --- a/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h @@ -102,6 +102,9 @@ public: void dumpGraph(const char *fileName) { + if (isNull()) + return; + #if 1 //def QT_GST_CAPTURE_DEBUG GST_DEBUG_BIN_TO_DOT_FILE(bin(), GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL | @@ -112,6 +115,9 @@ public: #endif } + void beginConfig(); + void endConfig(); + void flush(); bool seek(qint64 pos, double rate); diff --git a/src/multimedia/platform/gstreamer/common/qgstreameraudioinput.cpp b/src/multimedia/platform/gstreamer/common/qgstreameraudioinput.cpp index 46e941a00..f406462e4 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreameraudioinput.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreameraudioinput.cpp @@ -111,18 +111,8 @@ void QGstreamerAudioInput::setAudioDevice(const QAudioDevice &device) qCDebug(qLcMediaAudioInput) << "setAudioInput" << device.description() << device.isNull(); m_audioDevice = device; - if (gstPipeline.isNull() || gstPipeline.state() != GST_STATE_PLAYING) { - changeAudioInput(); - return; - } - - auto pad = audioVolume.staticPad("src"); - pad.addProbe<&QGstreamerAudioInput::prepareAudioInputChange>(this, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM); -} + gstPipeline.beginConfig(); -bool QGstreamerAudioInput::changeAudioInput() -{ - qCDebug(qLcMediaAudioInput) << "Changing audio Input"; QGstElement newSrc; auto *deviceInfo = static_cast<const QGStreamerAudioDeviceInfo *>(m_audioDevice.handle()); if (deviceInfo && deviceInfo->gstDevice) @@ -138,16 +128,7 @@ bool QGstreamerAudioInput::changeAudioInput() audioSrc.link(audioVolume); audioSrc.setState(GST_STATE_PAUSED); - return true; -} - -void QGstreamerAudioInput::prepareAudioInputChange(const QGstPad &/*pad*/) -{ - qCDebug(qLcMediaAudioInput) << "Reconfiguring audio Input"; - - gstPipeline.setStateSync(GST_STATE_PAUSED); - changeAudioInput(); - gstPipeline.setState(GST_STATE_PLAYING); + gstPipeline.endConfig(); } QAudioDevice QGstreamerAudioInput::audioInput() const diff --git a/src/multimedia/platform/gstreamer/common/qgstreameraudioinput_p.h b/src/multimedia/platform/gstreamer/common/qgstreameraudioinput_p.h index 5a6a330ac..b45f96b6c 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreameraudioinput_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstreameraudioinput_p.h @@ -92,9 +92,6 @@ Q_SIGNALS: void volumeChanged(int); private: - void prepareAudioInputChange(const QGstPad &pad); - bool changeAudioInput(); - float m_volume = 1.; bool m_muted = false; diff --git a/src/multimedia/platform/gstreamer/common/qgstreameraudiooutput.cpp b/src/multimedia/platform/gstreamer/common/qgstreameraudiooutput.cpp index 461a7e146..0060d20fc 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreameraudiooutput.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreameraudiooutput.cpp @@ -96,10 +96,10 @@ void QGstreamerAudioOutput::setAudioDevice(const QAudioDevice &info) qCDebug(qLcMediaAudioOutput) << "setAudioOutput" << info.description() << info.isNull(); m_audioOutput = info; - auto state = gstPipeline.isNull() ? GST_STATE_NULL : gstPipeline.state(); - if (state == GST_STATE_PLAYING) - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); + audioSink.setStateSync(GST_STATE_NULL); + gstAudioOutput.remove(audioSink); QGstElement newSink; auto *deviceInfo = static_cast<const QGStreamerAudioDeviceInfo *>(m_audioOutput.handle()); @@ -109,17 +109,12 @@ void QGstreamerAudioOutput::setAudioDevice(const QAudioDevice &info) if (newSink.isNull()) newSink = QGstElement("autoaudiosink", "audiosink"); - gstAudioOutput.remove(audioSink); audioSink = newSink; gstAudioOutput.add(audioSink); audioVolume.link(audioSink); + audioSink.setState(GST_STATE_PAUSED); - if (state != GST_STATE_NULL) { - audioSink.setState(GST_STATE_PAUSED); - gstPipeline.flush(); - } - if (state == GST_STATE_PLAYING) - gstPipeline.setState(state); + gstPipeline.endConfig(); } QT_END_NAMESPACE diff --git a/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp b/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp index b0c1c7201..ec0a679bd 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp @@ -601,9 +601,7 @@ void QGstreamerMediaPlayer::setAudioOutput(QPlatformAudioOutput *output) { if (gstAudioOutput == output) return; - auto state = playerPipeline.state(); - if (state == GST_STATE_PLAYING) - playerPipeline.setStateSync(GST_STATE_PAUSED); + playerPipeline.beginConfig(); if (gstAudioOutput) { removeOutput(AudioStream); gstAudioOutput->setPipeline({}); @@ -613,8 +611,7 @@ void QGstreamerMediaPlayer::setAudioOutput(QPlatformAudioOutput *output) gstAudioOutput->setPipeline(playerPipeline); connectOutput(AudioStream); } - if (state == GST_STATE_PLAYING) - playerPipeline.setState(GST_STATE_PLAYING); + playerPipeline.endConfig(); } QMediaMetaData QGstreamerMediaPlayer::metaData() const diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp b/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp index a34969de1..7e77aa099 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp @@ -72,23 +72,51 @@ QGstreamerVideoOutput::~QGstreamerVideoOutput() void QGstreamerVideoOutput::setVideoSink(QVideoSink *sink) { - auto *videoSink = sink ? static_cast<QGstreamerVideoSink *>(sink->platformVideoSink()) : nullptr; - if (videoSink == m_videoWindow) + auto *gstVideoSink = sink ? static_cast<QGstreamerVideoSink *>(sink->platformVideoSink()) : nullptr; + if (gstVideoSink == m_videoWindow) return; if (m_videoWindow) m_videoWindow->setPipeline({}); - m_videoWindow = videoSink; + m_videoWindow = gstVideoSink; if (m_videoWindow) m_videoWindow->setPipeline(gstPipeline); - auto state = gstPipeline.state(); - if (state == GST_STATE_PLAYING) - gstPipeline.setStateSync(GST_STATE_PAUSED); - sinkChanged(); - if (state == GST_STATE_PLAYING) - gstPipeline.setState(GST_STATE_PLAYING); + QGstElement gstSink; + if (m_videoWindow) { + gstSink = m_videoWindow->gstSink(); + isFakeSink = false; + } else { + gstSink = QGstElement("fakesink", "fakevideosink"); + isFakeSink = true; + } + + if (videoSink == gstSink) + return; + + gstPipeline.beginConfig(); + if (!videoSink.isNull()) { + videoSink.setStateSync(GST_STATE_NULL); + gstVideoOutput.remove(videoSink); + } + videoSink = gstSink; + gstVideoOutput.add(videoSink); + + videoConvert.link(videoSink); + GstEvent *event = gst_event_new_reconfigure(); + gst_element_send_event(videoSink.element(), event); + videoSink.setState(GST_STATE_PAUSED); + + gstPipeline.endConfig(); + + qCDebug(qLcMediaVideoOutput) << "sinkChanged" << gstSink.name(); + + GST_DEBUG_BIN_TO_DOT_FILE(gstPipeline.bin(), + GstDebugGraphDetails(/*GST_DEBUG_GRAPH_SHOW_ALL |*/ GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | + GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES), + videoSink.name()); + } void QGstreamerVideoOutput::setPipeline(const QGstPipeline &pipeline) @@ -104,9 +132,7 @@ void QGstreamerVideoOutput::linkSubtitleStream(QGstElement src) if (src == subtitleSrc) return; - auto state = gstPipeline.state(); - if (state == GST_STATE_PLAYING) - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); if (!subtitleSrc.isNull()) { subtitleSrc.unlink(subTitleQueue); @@ -120,7 +146,7 @@ void QGstreamerVideoOutput::linkSubtitleStream(QGstElement src) qCDebug(qLcMediaVideoOutput) << "link subtitle stream 1 failed"; } - gstPipeline.setState(state); + gstPipeline.endConfig(); } void QGstreamerVideoOutput::setIsPreview() @@ -134,40 +160,4 @@ void QGstreamerVideoOutput::setIsPreview() videoQueue.set("max-size-time", 0); } -void QGstreamerVideoOutput::sinkChanged() -{ - QGstElement gstSink; - if (m_videoWindow) { - gstSink = m_videoWindow->gstSink(); - isFakeSink = false; - } else { - gstSink = QGstElement("fakesink", "fakevideosink"); - isFakeSink = true; - } - - if (videoSink == gstSink) - return; - - if (!videoSink.isNull()) { - videoSink.setStateSync(GST_STATE_NULL); - gstVideoOutput.remove(videoSink); - } - videoSink = gstSink; - gstVideoOutput.add(videoSink); - - videoConvert.link(videoSink); - GstEvent *event = gst_event_new_reconfigure(); - gst_element_send_event(videoSink.element(), event); - videoSink.setState(GST_STATE_PAUSED); - - gstPipeline.setState(GST_STATE_PLAYING); - qCDebug(qLcMediaVideoOutput) << "sinkChanged" << gstSink.name(); - - GST_DEBUG_BIN_TO_DOT_FILE(gstPipeline.bin(), - GstDebugGraphDetails(/*GST_DEBUG_GRAPH_SHOW_ALL |*/ GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | - GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES), - videoSink.name()); -} - - QT_END_NAMESPACE diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideooutput_p.h b/src/multimedia/platform/gstreamer/common/qgstreamervideooutput_p.h index 26fde3c4f..2cadb9cc3 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamervideooutput_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstreamervideooutput_p.h @@ -82,9 +82,6 @@ public: void setIsPreview(); private: - void sinkChanged(); - -private: QVideoSink *m_videoSink = nullptr; QPointer<QGstreamerVideoSink> m_videoWindow; diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp b/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp index 7b4533da7..e505060be 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp @@ -172,9 +172,7 @@ void QGstreamerVideoSink::updateSinkElement() if (newSink == gstVideoSink) return; - auto state = gstPipeline.isNull() ? GST_STATE_NULL : gstPipeline.state(); - if (state == GST_STATE_PLAYING) - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); if (!gstVideoSink.isNull()) { gstVideoSink.setStateSync(GST_STATE_NULL); @@ -186,6 +184,5 @@ void QGstreamerVideoSink::updateSinkElement() gstPreprocess.link(gstVideoSink); gstVideoSink.setState(GST_STATE_PAUSED); - if (state == GST_STATE_PLAYING) - gstPipeline.setState(GST_STATE_PLAYING); + gstPipeline.endConfig(); } diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp index 99a44b70e..02a2214cf 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp @@ -101,10 +101,7 @@ void QGstreamerCamera::setCamera(const QCameraDevice &camera) m_cameraDevice = camera; - bool havePipeline = !gstPipeline.isNull(); - - if (havePipeline) - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); Q_ASSERT(!gstCamera.isNull()); @@ -128,10 +125,8 @@ void QGstreamerCamera::setCamera(const QCameraDevice &camera) gstCamera.setState(GST_STATE_PAUSED); - if (havePipeline) { - gstPipeline.dumpGraph("setCamera"); - gstPipeline.setState(GST_STATE_PLAYING); - } + gstPipeline.endConfig(); + gstPipeline.dumpGraph("setCamera"); updateCameraProperties(); } @@ -170,13 +165,9 @@ bool QGstreamerCamera::setCameraFormat(const QCameraFormat &format) { if (!m_cameraDevice.videoFormats().contains(format)) return false; - bool havePipeline = !gstPipeline.isNull(); - auto state = havePipeline ? gstPipeline.state() : GST_STATE_NULL; - if (havePipeline) - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); setCameraFormatInternal(format); - if (havePipeline) - gstPipeline.setStateSync(state); + gstPipeline.endConfig(); return true; } diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture.cpp index 4570f1d69..17404de7c 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture.cpp @@ -257,8 +257,10 @@ void QGstreamerImageCapture::setCaptureSession(QPlatformMediaCaptureSession *ses pendingImages.clear(); passImage = false; cameraActive = false; + gstPipeline.beginConfig(); bin.setStateSync(GST_STATE_NULL); gstPipeline.remove(bin); + gstPipeline.endConfig(); gstPipeline = {}; } @@ -267,8 +269,10 @@ void QGstreamerImageCapture::setCaptureSession(QPlatformMediaCaptureSession *ses return; gstPipeline = captureSession->pipeline(); + gstPipeline.beginConfig(); gstPipeline.add(bin); bin.setStateSync(GST_STATE_READY); + gstPipeline.endConfig(); connect(m_session, &QPlatformMediaCaptureSession::cameraChanged, this, &QGstreamerImageCapture::onCameraChanged); onCameraChanged(); } @@ -342,13 +346,13 @@ void QGstreamerImageCapture::unlink() return; if (gstPipeline.isNull()) return; - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); videoSrcPad.unlinkPeer(); m_session->releaseVideoPad(videoSrcPad); videoSrcPad = {}; bin.setStateSync(GST_STATE_READY); bin.lockState(true); - gstPipeline.setStateSync(GST_STATE_PLAYING); + gstPipeline.endConfig(); } void QGstreamerImageCapture::link() @@ -357,12 +361,12 @@ void QGstreamerImageCapture::link() return; if (!bin.staticPad("sink").peer().isNull() || gstPipeline.isNull()) return; - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); videoSrcPad = m_session->getVideoPad(); videoSrcPad.link(bin.staticPad("sink")); bin.lockState(false); bin.setState(GST_STATE_PAUSED); - gstPipeline.setStateSync(GST_STATE_PLAYING); + gstPipeline.endConfig(); } QImageEncoderSettings QGstreamerImageCapture::imageSettings() const diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp index 237b2a505..b5c3249fe 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp @@ -84,7 +84,7 @@ void QGstreamerMediaCapture::setCamera(QPlatformCamera *camera) if (gstCamera == control) return; - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); if (gstVideoTee.isNull()) { gstVideoTee = QGstElement("tee", "videotee"); @@ -111,7 +111,7 @@ void QGstreamerMediaCapture::setCamera(QPlatformCamera *camera) camera.setState(GST_STATE_PAUSED); } - gstPipeline.setState(GST_STATE_PLAYING); + gstPipeline.endConfig(); emit cameraChanged(); gstPipeline.dumpGraph("camera"); @@ -128,7 +128,7 @@ void QGstreamerMediaCapture::setImageCapture(QPlatformImageCapture *imageCapture if (m_imageCapture == control) return; - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); if (m_imageCapture) m_imageCapture->setCaptureSession(nullptr); @@ -137,7 +137,7 @@ void QGstreamerMediaCapture::setImageCapture(QPlatformImageCapture *imageCapture if (m_imageCapture) m_imageCapture->setCaptureSession(this); - gstPipeline.setState(GST_STATE_PLAYING); + gstPipeline.endConfig(); emit imageCaptureChanged(); } @@ -168,7 +168,7 @@ void QGstreamerMediaCapture::setAudioInput(QPlatformAudioInput *input) { if (gstAudioInput == input) return; - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); if (gstAudioInput) { gstAudioOutput->setPipeline({}); gstAudioInput = nullptr; @@ -198,7 +198,7 @@ void QGstreamerMediaCapture::setAudioInput(QPlatformAudioInput *input) gstAudioOutputPad.link(gstAudioOutput->gstElement().staticPad("sink")); } - gstPipeline.setState(GST_STATE_PLAYING); + gstPipeline.endConfig(); } void QGstreamerMediaCapture::setVideoPreview(QVideoSink *sink) @@ -210,7 +210,7 @@ void QGstreamerMediaCapture::setAudioOutput(QPlatformAudioOutput *output) { if (gstAudioOutput == output) return; - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); if (gstAudioOutput) { gstAudioOutput->setPipeline({}); @@ -234,7 +234,7 @@ void QGstreamerMediaCapture::setAudioOutput(QPlatformAudioOutput *output) gstAudioOutputPad.link(gstAudioOutput->gstElement().staticPad("sink")); } - gstPipeline.setState(GST_STATE_PLAYING); + gstPipeline.endConfig(); } diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp index 210e6d3b6..71c9d3a39 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp @@ -251,8 +251,8 @@ void QGstreamerMediaEncoder::record(const QMediaEncoderSettings &) Q_ASSERT(!actualSink.isEmpty()); gstFileSink.set("location", QFile::encodeName(actualSink.toLocalFile()).constData()); - //auto state = gstPipeline.state(); - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); + gstEncoder.lockState(false); gstFileSink.lockState(false); @@ -272,7 +272,8 @@ void QGstreamerMediaEncoder::record(const QMediaEncoderSettings &) gstEncoder.setState(GST_STATE_PAUSED); gstFileSink.setState(GST_STATE_PAUSED); - gstPipeline.setState(GST_STATE_PLAYING); + + gstPipeline.endConfig(); m_duration.start(); heartbeat.start(); @@ -308,7 +309,8 @@ void QGstreamerMediaEncoder::stop() qCDebug(qLcMediaEncoder) << "stop"; heartbeat.stop(); - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); + if (!audioSrcPad.isNull()) { audioSrcPad.unlinkPeer(); m_session->releaseAudioPad(audioSrcPad); @@ -320,7 +322,8 @@ void QGstreamerMediaEncoder::stop() videoSrcPad = {}; } - gstPipeline.setState(GST_STATE_PLAYING); + gstPipeline.endConfig(); + //with live sources it's necessary to send EOS even to pipeline //before going to STOPPED state qCDebug(qLcMediaEncoder) << ">>>>>>>>>>>>> sending EOS"; @@ -336,12 +339,12 @@ void QGstreamerMediaEncoder::finalize() qCDebug(qLcMediaEncoder) << "finalize"; // The filesink can only be used once, replace it with a new one - gstPipeline.setStateSync(GST_STATE_PAUSED); + gstPipeline.beginConfig(); gstEncoder.lockState(true); gstFileSink.lockState(true); gstEncoder.setState(GST_STATE_NULL); gstFileSink.setState(GST_STATE_NULL); - gstPipeline.setStateSync(GST_STATE_PLAYING); + gstPipeline.endConfig(); } void QGstreamerMediaEncoder::applySettings(const QMediaEncoderSettings &settings) |