summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Blechmann <tim@klingt.org>2024-03-08 12:48:45 +0800
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-03-14 03:43:38 +0000
commit1e23d963376c03feb40d474d766efee8bec7e727 (patch)
tree2c14a2dc6cd20e7fb2dc3faccee0b4a56939ac4d
parentb1ca01a8b22755150fc7d3de19445ebb315826cf (diff)
GStreamer: camera - prevent pipeline changes while pipeline is running
When switching cameras, `QGstreamerCamera::setCamera` would modify the pipeline while it's running Pick-to: 6.5 Change-Id: I96895b882270018f900126979f161ca614adfb16 Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> (cherry picked from commit d0e41971ea34dd802bb04159e1a7f49e50e4dac5) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit 992812185cf2c207b75b2455c85327cac3475e51)
-rw-r--r--src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp44
-rw-r--r--src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera_p.h9
-rw-r--r--src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp2
3 files changed, 37 insertions, 18 deletions
diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp
index c1aaab818..226a08bc9 100644
--- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp
+++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp
@@ -103,20 +103,22 @@ void QGstreamerCamera::setCamera(const QCameraDevice &camera)
auto gstNewDecode = QGstElement::createFromFactory(
f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity");
- qUnlinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert);
- gstCameraBin.stopAndRemoveElements(gstCamera, gstDecode);
-
- gstCapsFilter.set("caps", caps);
+ auto updateCameraBin = [&] {
+ qUnlinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert);
+ gstCameraBin.stopAndRemoveElements(gstCamera, gstDecode);
- gstCameraBin.add(gstNewCamera, gstNewDecode);
- qLinkGstElements(gstNewCamera, gstCapsFilter, gstNewDecode, gstVideoConvert);
+ gstCapsFilter.set("caps", caps);
- // Start sending frames once pipeline is linked
- // FIXME: put camera to READY state before linking to decoder as in the NULL state it does not
- // know its true caps
+ gstCameraBin.add(gstNewCamera, gstNewDecode);
+ qLinkGstElements(gstNewCamera, gstCapsFilter, gstNewDecode, gstVideoConvert);
- gstCameraBin.syncChildrenState();
+ gstCameraBin.syncChildrenState();
+ };
+ if (gstPipeline)
+ gstPipeline.modifyPipelineWhileNotRunning(updateCameraBin);
+ else
+ updateCameraBin();
gstCamera = gstNewCamera;
gstDecode = gstNewDecode;
@@ -137,23 +139,35 @@ bool QGstreamerCamera::setCameraFormat(const QCameraFormat &format)
auto newGstDecode = QGstElement::createFromFactory(
f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity");
- gstCameraBin.add(newGstDecode);
- newGstDecode.syncStateWithParent();
- gstCamera.staticPad("src").doInIdleProbe([&]() {
+ auto updateCameraBin = [&] {
+ newGstDecode.syncStateWithParent();
+
qUnlinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert);
+ gstCameraBin.stopAndRemoveElements(gstDecode);
gstCapsFilter.set("caps", caps);
+
+ gstCameraBin.add(newGstDecode);
qLinkGstElements(gstCamera, gstCapsFilter, newGstDecode, gstVideoConvert);
- });
+ gstCameraBin.syncChildrenState();
+ };
- gstCameraBin.stopAndRemoveElements(gstDecode);
+ if (gstPipeline)
+ gstPipeline.modifyPipelineWhileNotRunning(updateCameraBin);
+ else
+ updateCameraBin();
gstDecode = newGstDecode;
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 7926f9004..59d69337f 100644
--- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera_p.h
+++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera_p.h
@@ -15,11 +15,12 @@
// We mean it.
//
-#include <QHash>
#include <private/qplatformcamera_p.h>
#include <private/qmultimediautils_p.h>
-#include "qgstreamermediacapture_p.h"
-#include <qgst_p.h>
+
+#include <mediacapture/qgstreamermediacapture_p.h>
+#include <common/qgst_p.h>
+#include <common/qgstpipeline_p.h>
QT_BEGIN_NAMESPACE
@@ -37,6 +38,7 @@ public:
void setCamera(const QCameraDevice &camera) override;
bool setCameraFormat(const QCameraFormat &format) override;
+ void setPipeline(const QGstPipeline &);
QGstElement gstElement() const { return QGstElement(gstCameraBin.element()); }
#if QT_CONFIG(gstreamer_photography)
GstPhotography *photography() const;
@@ -117,6 +119,7 @@ private:
QGstElement gstDecode;
QGstElement gstVideoConvert;
QGstElement gstVideoScale;
+ QGstPipeline gstPipeline;
bool m_active = false;
QString m_v4l2DevicePath;
diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp
index 8eb37ac06..4a5fbe6e6 100644
--- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp
+++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp
@@ -93,11 +93,13 @@ 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())