summaryrefslogtreecommitdiffstats
path: root/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp')
-rw-r--r--src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp129
1 files changed, 95 insertions, 34 deletions
diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp
index 8d3cd6baf..c54e8b74b 100644
--- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp
+++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp
@@ -5,6 +5,7 @@
#include <QtMultimedia/qcameradevice.h>
#include <QtMultimedia/qmediacapturesession.h>
+#include <QtMultimedia/private/qcameradevice_p.h>
#include <QtCore/qdebug.h>
#include <common/qgst_debug_p.h>
@@ -21,36 +22,35 @@ QT_BEGIN_NAMESPACE
QMaybe<QPlatformCamera *> QGstreamerCamera::create(QCamera *camera)
{
- QGstElement videotestsrc = QGstElement::createFromFactory("videotestsrc");
- if (!videotestsrc)
- return errorMessageCannotFindElement("videotestsrc");
+ static const auto error = qGstErrorMessageIfElementsNotAvailable(
+ "videotestsrc", "capsfilter", "videoconvert", "videoscale", "identity");
+ if (error)
+ return *error;
- QGstElement capsFilter = QGstElement::createFromFactory("capsfilter", "videoCapsFilter");
- if (!capsFilter)
- return errorMessageCannotFindElement("capsfilter");
-
- QGstElement videoconvert = QGstElement::createFromFactory("videoconvert", "videoConvert");
- if (!videoconvert)
- return errorMessageCannotFindElement("videoconvert");
-
- QGstElement videoscale = QGstElement::createFromFactory("videoscale", "videoScale");
- if (!videoscale)
- return errorMessageCannotFindElement("videoscale");
-
- return new QGstreamerCamera(videotestsrc, capsFilter, videoconvert, videoscale, camera);
+ return new QGstreamerCamera(camera);
}
-QGstreamerCamera::QGstreamerCamera(QGstElement videotestsrc, QGstElement capsFilter,
- QGstElement videoconvert, QGstElement videoscale,
- QCamera *camera)
- : QPlatformCamera(camera),
- gstCamera(std::move(videotestsrc)),
- gstCapsFilter(std::move(capsFilter)),
- gstVideoConvert(std::move(videoconvert)),
- gstVideoScale(std::move(videoscale))
+QGstreamerCamera::QGstreamerCamera(QCamera *camera)
+ : QGstreamerCameraBase(camera),
+ gstCameraBin{
+ QGstBin::create("camerabin"),
+ },
+ gstCamera{
+ QGstElement::createFromFactory("videotestsrc"),
+ },
+ gstCapsFilter{
+ QGstElement::createFromFactory("capsfilter", "videoCapsFilter"),
+ },
+ gstDecode{
+ QGstElement::createFromFactory("identity"),
+ },
+ gstVideoConvert{
+ QGstElement::createFromFactory("videoconvert", "videoConvert"),
+ },
+ gstVideoScale{
+ QGstElement::createFromFactory("videoscale", "videoScale"),
+ }
{
- gstDecode = QGstElement::createFromFactory("identity");
- gstCameraBin = QGstBin::create("camerabin");
gstCameraBin.add(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert, gstVideoScale);
qLinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert, gstVideoScale);
gstCameraBin.addGhostPad(gstVideoScale, "src");
@@ -80,6 +80,8 @@ void QGstreamerCamera::setActive(bool active)
void QGstreamerCamera::setCamera(const QCameraDevice &camera)
{
+ using namespace Qt::Literals;
+
if (m_cameraDevice == camera)
return;
@@ -90,12 +92,24 @@ void QGstreamerCamera::setCamera(const QCameraDevice &camera)
gstNewCamera = QGstElement::createFromFactory("videotestsrc");
} else {
auto *integration = static_cast<QGstreamerIntegration *>(QGstreamerIntegration::instance());
- auto *device = integration->videoDevice(camera.id());
+ GstDevice *device = integration->videoDevice(camera.id());
+
+ if (!device) {
+ updateError(QCamera::Error::CameraError,
+ u"Failed to create GstDevice for camera: "_s
+ + QString::fromUtf8(camera.id()));
+ return;
+ }
+
gstNewCamera = QGstElement::createFromDevice(device, "camerasrc");
- if (QGstStructure properties = gst_device_get_properties(device); !properties.isNull()) {
- if (properties.name() == "v4l2deviceprovider")
- m_v4l2DevicePath = QString::fromUtf8(properties["device.path"].toString());
- properties.free();
+ QUniqueGstStructureHandle properties{
+ gst_device_get_properties(device),
+ };
+
+ if (properties) {
+ QGstStructureView propertiesView{ properties };
+ if (propertiesView.name() == "v4l2deviceprovider")
+ m_v4l2DevicePath = QString::fromUtf8(propertiesView["device.path"].toString());
}
}
@@ -105,6 +119,8 @@ void QGstreamerCamera::setCamera(const QCameraDevice &camera)
f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity");
QGstPipeline::modifyPipelineWhileNotRunning(gstCamera.getPipeline(), [&] {
+ gstCamera.setStateSync(GST_STATE_READY); // stop camera, as it may have active tasks
+
qUnlinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert);
gstCameraBin.stopAndRemoveElements(gstCamera, gstDecode);
@@ -137,7 +153,7 @@ bool QGstreamerCamera::setCameraFormat(const QCameraFormat &format)
f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity");
QGstPipeline::modifyPipelineWhileNotRunning(gstCamera.getPipeline(), [&] {
- newGstDecode.syncStateWithParent();
+ gstCamera.setStateSync(GST_STATE_READY); // stop camera, as it may have active tasks
qUnlinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert);
gstCameraBin.stopAndRemoveElements(gstDecode);
@@ -703,8 +719,53 @@ int QGstreamerCamera::getV4L2Parameter(quint32 id) const
});
}
+QGstreamerCustomCamera::QGstreamerCustomCamera(QCamera *camera)
+ : QGstreamerCameraBase{
+ camera,
+ },
+ m_userProvidedGstElement{
+ false,
+ }
+{
+}
+
+QGstreamerCustomCamera::QGstreamerCustomCamera(QCamera *camera, QGstElement element)
+ : QGstreamerCameraBase{
+ camera,
+ },
+ gstCamera{
+ std::move(element),
+ },
+ m_userProvidedGstElement{
+ true,
+ }
+{
+}
+
+void QGstreamerCustomCamera::setCamera(const QCameraDevice &device)
+{
+ if (m_userProvidedGstElement)
+ return;
+
+ gstCamera = QGstBin::createFromPipelineDescription(device.id(), /*name=*/nullptr,
+ /* ghostUnlinkedPads=*/true);
+}
+
+bool QGstreamerCustomCamera::isActive() const
+{
+ return m_active;
+}
+
+void QGstreamerCustomCamera::setActive(bool active)
+{
+ if (m_active == active)
+ return;
+
+ m_active = active;
+
+ emit activeChanged(active);
+}
+
#endif
QT_END_NAMESPACE
-
-#include "moc_qgstreamercamera_p.cpp"