summaryrefslogtreecommitdiffstats
path: root/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp')
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp124
1 files changed, 65 insertions, 59 deletions
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp
index b5ca6c881..1ee0244ef 100644
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp
+++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp
@@ -53,16 +53,16 @@
#include <QtCore/qdebug.h>
QGstreamerCamera::QGstreamerCamera(QCamera *camera)
- : QPlatformCamera(camera),
- gstCameraBin("camerabin")
+ : QPlatformCamera(camera)
{
gstCamera = QGstElement("videotestsrc");
+ gstCapsFilter = QGstElement("capsfilter", "videoCapsFilter");
gstDecode = QGstElement("identity");
gstVideoConvert = QGstElement("videoconvert", "videoConvert");
gstVideoScale = QGstElement("videoscale", "videoScale");
- gstCameraBin.add(gstCamera, gstDecode, gstVideoConvert, gstVideoScale);
- gstCamera.link(gstDecode, gstVideoConvert, gstVideoScale);
-
+ gstCameraBin = QGstBin("camerabin");
+ gstCameraBin.add(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert, gstVideoScale);
+ gstCamera.link(gstCapsFilter, gstDecode, gstVideoConvert, gstVideoScale);
gstCameraBin.addGhostPad(gstVideoScale, "src");
}
@@ -97,88 +97,94 @@ void QGstreamerCamera::setCamera(const QCameraDevice &camera)
{
if (m_cameraDevice == camera)
return;
-// qDebug() << "setCamera" << camera;
+ qDebug() << "setCamera" << camera;
m_cameraDevice = camera;
- gstPipeline.beginConfig();
-
- Q_ASSERT(!gstCamera.isNull());
-
- gstCamera.setStateSync(GST_STATE_NULL);
- gstCameraBin.remove(gstCamera);
-
+ QGstElement gstNewCamera;
if (camera.isNull()) {
- gstCamera = QGstElement("videotestsrc");
+ gstNewCamera = QGstElement("videotestsrc");
} else {
auto *devices = static_cast<QGstreamerMediaDevices *>(QGstreamerIntegration::instance()->devices());
auto *device = devices->videoDevice(camera.id());
- gstCamera = gst_device_create_element(device, "camerasrc");
+ gstNewCamera = gst_device_create_element(device, "camerasrc");
QGstStructure properties = gst_device_get_properties(device);
if (properties.name() == "v4l2deviceprovider")
m_v4l2Device = QString::fromUtf8(properties["device.path"].toString());
}
- gstCameraBin.add(gstCamera);
- // set the camera up with a decent format
- setCameraFormatInternal({});
+ QCameraFormat f = findBestCameraFormat(camera);
+ auto caps = QGstMutableCaps::fromCameraFormat(f);
+ auto gstNewDecode = QGstElement(f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity");
+
+ gstCamera.setStateSync(GST_STATE_NULL);
+ gstDecode.setStateSync(GST_STATE_NULL);
- gstCamera.setState(GST_STATE_PAUSED);
+ gstCamera.unlink(gstCapsFilter);
+ gstCapsFilter.unlink(gstDecode);
+ gstDecode.unlink(gstVideoConvert);
- gstPipeline.endConfig();
- gstPipeline.dumpGraph("setCamera");
+ gstCameraBin.remove(gstCamera);
+ gstCameraBin.remove(gstDecode);
+
+ gstCapsFilter.set("caps", caps);
+
+ gstCameraBin.add(gstNewCamera, gstNewDecode);
+
+ gstNewDecode.link(gstVideoConvert);
+ gstCapsFilter.link(gstNewDecode);
+
+ if (!gstNewCamera.link(gstCapsFilter))
+ qWarning() << "linking camera failed" << gstCamera.name() << caps.toString();
+
+ // 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
+ gstCapsFilter.syncStateWithParent();
+ gstNewDecode.syncStateWithParent();
+ gstNewCamera.syncStateWithParent();
+
+ gstCamera = gstNewCamera;
+ gstDecode = gstNewDecode;
updateCameraProperties();
}
-void QGstreamerCamera::setCameraFormatInternal(const QCameraFormat &format)
+bool QGstreamerCamera::setCameraFormat(const QCameraFormat &format)
{
+ if (!format.isNull() && !m_cameraDevice.videoFormats().contains(format))
+ return false;
+
+ qDebug() << "Set camera format";
+
QCameraFormat f = format;
if (f.isNull())
f = findBestCameraFormat(m_cameraDevice);
- // add jpeg decoder where required
- gstDecode.setStateSync(GST_STATE_NULL);
- gstCameraBin.remove(gstDecode);
+ auto caps = QGstMutableCaps::fromCameraFormat(f);
- if (f.pixelFormat() == QVideoFrameFormat::Format_Jpeg) {
-// qDebug() << " enabling jpeg decoder";
- gstDecode = QGstElement("jpegdec");
- } else {
-// qDebug() << " camera delivers raw video";
- gstDecode = QGstElement("identity");
- }
- gstCameraBin.add(gstDecode);
- gstDecode.link(gstVideoConvert);
+ auto newGstDecode = QGstElement(f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity");
+ gstCameraBin.add(newGstDecode);
+ newGstDecode.syncStateWithParent();
- auto caps = QGstMutableCaps::fromCameraFormat(f);
- if (!caps.isNull()) {
- if (!gstCamera.linkFiltered(gstDecode, caps))
- qWarning() << "linking filtered camera to decoder failed" << gstCamera.name() << gstDecode.name() << caps.toString();
- } else {
- if (!gstCamera.link(gstDecode))
- qWarning() << "linking camera to decoder failed" << gstCamera.name() << gstDecode.name();
- }
-}
+ gstCamera.staticPad("src").doInIdleProbe([&](){
+ gstCamera.unlink(gstCapsFilter);
+ gstCapsFilter.unlink(gstDecode);
+ gstDecode.unlink(gstVideoConvert);
-bool QGstreamerCamera::setCameraFormat(const QCameraFormat &format)
-{
- if (!format.isNull() && !m_cameraDevice.videoFormats().contains(format))
- return false;
- gstPipeline.beginConfig();
- setCameraFormatInternal(format);
- gstPipeline.endConfig();
- return true;
-}
+ gstCapsFilter.set("caps", caps);
-void QGstreamerCamera::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- QGstreamerMediaCapture *captureSession = static_cast<QGstreamerMediaCapture *>(session);
- if (m_session == captureSession)
- return;
+ newGstDecode.link(gstVideoConvert);
+ gstCapsFilter.link(newGstDecode);
+ if (!gstCamera.link(gstCapsFilter))
+ qWarning() << "linking filtered camera to decoder failed" << gstCamera.name() << caps.toString();
+ });
- m_session = captureSession;
- gstPipeline = m_session ? m_session->pipeline() : QGstPipeline();
+ gstDecode.setStateSync(GST_STATE_NULL);
+ gstCameraBin.remove(gstDecode);
+
+ gstDecode = newGstDecode;
+
+ return true;
}
void QGstreamerCamera::updateCameraProperties()