diff options
author | Tim Blechmann <tim@klingt.org> | 2024-04-02 08:33:14 +0800 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-04-03 09:15:22 +0000 |
commit | 401848ec816a0d23d2b56aece7305a7f3479753e (patch) | |
tree | 1272679a52d49d24e250cb9965bec25998736d6c | |
parent | ed9807159c24278bd87205fa171af738c84ade01 (diff) |
GStreamer: improve pipeline modification code
* avoid setPipeline in `QGstreamerCamera` and `QGstreamerAudioOutput`,
since we now can obtain the pipeline from the output/camera elements
* introduce static `modifyPipelineWhileNotRunning` helper to
`QGstPipeline`
* Ensure that `setAudioDevice` only modifies the pipeline while the
pipeline is not running
Task-number: QTBUG-119535
Pick-to: 6.5
Change-Id: Iad4cc887d8d2acddea4cf0c515545588558b652f
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit e0ff2ec5c8f8517f5cb55f3c2596abe262350ffc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 5b3803a70eed01d059a0a161da9925684983c4b2)
9 files changed, 40 insertions, 60 deletions
diff --git a/src/plugins/multimedia/gstreamer/common/qgstpipeline_p.h b/src/plugins/multimedia/gstreamer/common/qgstpipeline_p.h index c13196d12..d04bd84d8 100644 --- a/src/plugins/multimedia/gstreamer/common/qgstpipeline_p.h +++ b/src/plugins/multimedia/gstreamer/common/qgstpipeline_p.h @@ -81,6 +81,15 @@ public: endConfig(); } + template <typename Functor> + static void modifyPipelineWhileNotRunning(QGstPipeline &&pipeline, Functor &&fn) + { + if (pipeline) + pipeline.modifyPipelineWhileNotRunning(fn); + else + fn(); + } + void flush(); bool seek(qint64 pos, double rate); diff --git a/src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp b/src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp index d6b40ea21..0381b921e 100644 --- a/src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp +++ b/src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp @@ -89,13 +89,14 @@ void QGstreamerAudioInput::setAudioDevice(const QAudioDevice &device) newSrc = QGstElement::createFromFactory("autoaudiosrc", "audiosrc"); } - // FIXME: most probably source can be disconnected outside of idle probe - audioSrc.staticPad("src").doInIdleProbe([&]() { qUnlinkGstElements(audioSrc, audioVolume); }); - gstAudioInput.stopAndRemoveElements(audioSrc); - audioSrc = newSrc; - gstAudioInput.add(audioSrc); - qLinkGstElements(audioSrc, audioVolume); - audioSrc.syncStateWithParent(); + QGstPipeline::modifyPipelineWhileNotRunning(gstAudioInput.getPipeline(), [&] { + qUnlinkGstElements(audioSrc, audioVolume); + gstAudioInput.stopAndRemoveElements(audioSrc); + audioSrc = std::move(newSrc); + gstAudioInput.add(audioSrc); + qLinkGstElements(audioSrc, audioVolume); + audioSrc.syncStateWithParent(); + }); } QAudioDevice QGstreamerAudioInput::audioInput() const diff --git a/src/plugins/multimedia/gstreamer/common/qgstreameraudiooutput.cpp b/src/plugins/multimedia/gstreamer/common/qgstreameraudiooutput.cpp index efb1789e8..f45c371e9 100644 --- a/src/plugins/multimedia/gstreamer/common/qgstreameraudiooutput.cpp +++ b/src/plugins/multimedia/gstreamer/common/qgstreameraudiooutput.cpp @@ -68,11 +68,6 @@ void QGstreamerAudioOutput::setMuted(bool muted) audioVolume.set("mute", muted); } -void QGstreamerAudioOutput::setPipeline(const QGstPipeline &pipeline) -{ - gstPipeline = pipeline; -} - void QGstreamerAudioOutput::setAudioDevice(const QAudioDevice &info) { if (info == m_audioOutput) @@ -101,16 +96,14 @@ void QGstreamerAudioOutput::setAudioDevice(const QAudioDevice &info) newSink = QGstElement::createFromFactory("autoaudiosink", "audiosink"); } - audioVolume.staticPad("src").doInIdleProbe([&]() { + QGstPipeline::modifyPipelineWhileNotRunning(gstAudioOutput.getPipeline(), [&] { qUnlinkGstElements(audioVolume, audioSink); - gstAudioOutput.remove(audioSink); - gstAudioOutput.add(newSink); - newSink.syncStateWithParent(); - qLinkGstElements(audioVolume, newSink); + gstAudioOutput.stopAndRemoveElements(audioSink); + audioSink = std::move(newSink); + gstAudioOutput.add(audioSink); + audioSink.syncStateWithParent(); + qLinkGstElements(audioVolume, audioSink); }); - - audioSink.setStateSync(GST_STATE_NULL); - audioSink = newSink; } QT_END_NAMESPACE diff --git a/src/plugins/multimedia/gstreamer/common/qgstreameraudiooutput_p.h b/src/plugins/multimedia/gstreamer/common/qgstreameraudiooutput_p.h index a8680b634..4b528d9ee 100644 --- a/src/plugins/multimedia/gstreamer/common/qgstreameraudiooutput_p.h +++ b/src/plugins/multimedia/gstreamer/common/qgstreameraudiooutput_p.h @@ -38,8 +38,6 @@ public: void setVolume(float) override; void setMuted(bool) override; - void setPipeline(const QGstPipeline &pipeline); - QGstElement gstElement() const { return gstAudioOutput; } private: diff --git a/src/plugins/multimedia/gstreamer/common/qgstreamermediaplayer.cpp b/src/plugins/multimedia/gstreamer/common/qgstreamermediaplayer.cpp index e318c14eb..a4e2036e7 100644 --- a/src/plugins/multimedia/gstreamer/common/qgstreamermediaplayer.cpp +++ b/src/plugins/multimedia/gstreamer/common/qgstreamermediaplayer.cpp @@ -771,15 +771,12 @@ void QGstreamerMediaPlayer::setAudioOutput(QPlatformAudioOutput *output) auto &ts = trackSelector(AudioStream); playerPipeline.modifyPipelineWhileNotRunning([&] { - if (gstAudioOutput) { + if (gstAudioOutput) removeOutput(ts); - gstAudioOutput->setPipeline({}); - } + gstAudioOutput = static_cast<QGstreamerAudioOutput *>(output); - if (gstAudioOutput) { - gstAudioOutput->setPipeline(playerPipeline); + if (gstAudioOutput) connectOutput(ts); - } }); } diff --git a/src/plugins/multimedia/gstreamer/common/qgstreamervideosink.cpp b/src/plugins/multimedia/gstreamer/common/qgstreamervideosink.cpp index 21b64f997..c70428485 100644 --- a/src/plugins/multimedia/gstreamer/common/qgstreamervideosink.cpp +++ b/src/plugins/multimedia/gstreamer/common/qgstreamervideosink.cpp @@ -133,7 +133,7 @@ QGstElement QGstreamerVideoSink::gstSink() void QGstreamerVideoSink::setPipeline(QGstPipeline pipeline) { - gstPipeline = pipeline; + gstPipeline = std::move(pipeline); } bool QGstreamerVideoSink::inStoppedState() const diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp index c14a34c22..8d3cd6baf 100644 --- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp +++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp @@ -104,25 +104,20 @@ void QGstreamerCamera::setCamera(const QCameraDevice &camera) auto gstNewDecode = QGstElement::createFromFactory( f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity"); - auto updateCameraBin = [&] { + QGstPipeline::modifyPipelineWhileNotRunning(gstCamera.getPipeline(), [&] { qUnlinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert); gstCameraBin.stopAndRemoveElements(gstCamera, gstDecode); gstCapsFilter.set("caps", caps); - gstCameraBin.add(gstNewCamera, gstNewDecode); - qLinkGstElements(gstNewCamera, gstCapsFilter, gstNewDecode, gstVideoConvert); + gstCamera = std::move(gstNewCamera); + gstDecode = std::move(gstNewDecode); - gstCameraBin.syncChildrenState(); - }; - - if (gstPipeline) - gstPipeline.modifyPipelineWhileNotRunning(updateCameraBin); - else - updateCameraBin(); + gstCameraBin.add(gstCamera, gstDecode); + qLinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert); - gstCamera = gstNewCamera; - gstDecode = gstNewDecode; + gstCameraBin.syncChildrenState(); + }); updateCameraProperties(); } @@ -141,7 +136,7 @@ bool QGstreamerCamera::setCameraFormat(const QCameraFormat &format) auto newGstDecode = QGstElement::createFromFactory( f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity"); - auto updateCameraBin = [&] { + QGstPipeline::modifyPipelineWhileNotRunning(gstCamera.getPipeline(), [&] { newGstDecode.syncStateWithParent(); qUnlinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert); @@ -149,26 +144,16 @@ bool QGstreamerCamera::setCameraFormat(const QCameraFormat &format) gstCapsFilter.set("caps", caps); - gstCameraBin.add(newGstDecode); - qLinkGstElements(gstCamera, gstCapsFilter, newGstDecode, gstVideoConvert); - gstCameraBin.syncChildrenState(); - }; - - if (gstPipeline) - gstPipeline.modifyPipelineWhileNotRunning(updateCameraBin); - else - updateCameraBin(); + gstDecode = std::move(newGstDecode); - gstDecode = newGstDecode; + gstCameraBin.add(gstDecode); + qLinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert); + gstCameraBin.syncChildrenState(); + }); return true; } -void QGstreamerCamera::setPipeline(QGstPipeline const &pipeline) -{ - gstPipeline = pipeline; -} - void QGstreamerCamera::updateCameraProperties() { #if QT_CONFIG(linux_v4l) diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera_p.h b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera_p.h index a85180595..74f12f918 100644 --- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera_p.h +++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera_p.h @@ -38,7 +38,6 @@ public: void setCamera(const QCameraDevice &camera) override; bool setCameraFormat(const QCameraFormat &format) override; - void setPipeline(const QGstPipeline &); QGstElement gstElement() const { return gstCameraBin; } #if QT_CONFIG(gstreamer_photography) GstPhotography *photography() const; diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp index e28712aea..40ad0bc74 100644 --- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp +++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp @@ -92,13 +92,11 @@ void QGstreamerMediaCapture::setCamera(QPlatformCamera *platformCamera) QObject::disconnect(gstCameraActiveConnection); if (gstVideoTee) setCameraActive(false); - gstCamera->setPipeline({}); } gstCamera = camera; if (gstCamera) { - gstCamera->setPipeline(gstPipeline); gstCameraActiveConnection = QObject::connect(camera, &QGstreamerCamera::activeChanged, this, &QGstreamerMediaCapture::setCameraActive); if (gstCamera->isActive()) |