summaryrefslogtreecommitdiffstats
path: root/src/multimedia/platform
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2023-06-21 20:48:21 +0200
committerArtem Dyomin <artem.dyomin@qt.io>2023-06-23 11:41:38 +0000
commit2bca3087d2b48bed46e6d959b35ebf34d5d256ac (patch)
treecd6606577fa6efa2cb2cb752afc2fc9f02566a2a /src/multimedia/platform
parentaff72ee9082ae770746b4da9ddafa1a867ba31d2 (diff)
Refactor internal design for QWindowCapture implementations
The idea is having internal naming ***SurfaceCapture for those ones that can capture windows and screens, and specific naming ***ScreenCapture, ***WindoiwCapture. QPlatformSurfaceCapture is a base class that is able to work with both, screens and windows. It should be useful since there's a bunch of similar code for screens a windows copturing. It's the first step of the refactoring, other steps are coming soon. Pick-to: 6.6 6.5 Change-Id: I9b03e4d0b1129f8d39a16195fe3261001eb451f4 Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/multimedia/platform')
-rw-r--r--src/multimedia/platform/qplatformmediaintegration_p.h2
-rw-r--r--src/multimedia/platform/qplatformsurfacecapture.cpp64
-rw-r--r--src/multimedia/platform/qplatformsurfacecapture_p.h68
3 files changed, 88 insertions, 46 deletions
diff --git a/src/multimedia/platform/qplatformmediaintegration_p.h b/src/multimedia/platform/qplatformmediaintegration_p.h
index 9f03024ad..feba057d7 100644
--- a/src/multimedia/platform/qplatformmediaintegration_p.h
+++ b/src/multimedia/platform/qplatformmediaintegration_p.h
@@ -28,6 +28,7 @@ class QMediaPlayer;
class QAudioDecoder;
class QCamera;
class QScreenCapture;
+class QWindowCapture;
class QMediaRecorder;
class QImageCapture;
class QMediaDevices;
@@ -66,6 +67,7 @@ public:
virtual QList<QCameraDevice> videoInputs();
virtual QMaybe<QPlatformCamera *> createCamera(QCamera *) { return notAvailable; }
virtual QPlatformSurfaceCapture *createScreenCapture(QScreenCapture *) { return nullptr; }
+ virtual QPlatformSurfaceCapture *createWindowCapture(QWindowCapture *) { return nullptr; }
virtual QMaybe<QPlatformAudioDecoder *> createAudioDecoder(QAudioDecoder *) { return notAvailable; }
virtual QMaybe<QPlatformMediaCaptureSession *> createCaptureSession() { return notAvailable; }
diff --git a/src/multimedia/platform/qplatformsurfacecapture.cpp b/src/multimedia/platform/qplatformsurfacecapture.cpp
index 5dbca230f..66bda4ce6 100644
--- a/src/multimedia/platform/qplatformsurfacecapture.cpp
+++ b/src/multimedia/platform/qplatformsurfacecapture.cpp
@@ -3,71 +3,81 @@
#include "platform/qplatformsurfacecapture_p.h"
#include "qvideoframe.h"
+#include "qguiapplication.h"
#include "qdebug.h"
QT_BEGIN_NAMESPACE
-QPlatformSurfaceCapture::QPlatformSurfaceCapture(QScreenCapture *screenCapture)
- : QPlatformVideoSource(screenCapture), m_screenCapture(screenCapture)
+QPlatformSurfaceCapture::QPlatformSurfaceCapture(Source initialSource) : m_source(initialSource)
{
+ Q_ASSERT(std::visit([](auto source) { return source == decltype(source){}; }, initialSource));
qRegisterMetaType<QVideoFrame>();
}
-void QPlatformSurfaceCapture::setWindow(QWindow *w)
+void QPlatformSurfaceCapture::setActive(bool active)
{
- if (w) {
- emit m_screenCapture->errorOccurred(QScreenCapture::InternalError,
- QLatin1String("Window capture is not supported"));
+ if (m_active == active)
+ return;
+
+ if (!setActiveInternal(active)) {
+ qWarning() << "Failed to change active status to value" << active;
+ return;
}
-}
-QWindow *QPlatformSurfaceCapture::window() const
-{
- return nullptr;
+ m_active = active;
+ emit activeChanged(active);
}
-void QPlatformSurfaceCapture::setWindowId(WId id)
+bool QPlatformSurfaceCapture::isActive() const
{
- if (id) {
- emit m_screenCapture->errorOccurred(QScreenCapture::InternalError,
- QLatin1String("Window capture is not supported"));
- }
+ return m_active;
}
-WId QPlatformSurfaceCapture::windowId() const
+void QPlatformSurfaceCapture::setSource(Source source)
{
- return 0;
+ Q_ASSERT(source.index() == m_source.index());
+
+ if (std::exchange(m_source, source) != source)
+ std::visit([this](auto source) { emit sourceChanged(source); }, m_source);
}
-QScreenCapture::Error QPlatformSurfaceCapture::error() const
+QPlatformSurfaceCapture::Error QPlatformSurfaceCapture::error() const
{
return m_error;
}
+
QString QPlatformSurfaceCapture::errorString() const
{
return m_errorString;
}
-QScreenCapture *QPlatformSurfaceCapture::screenCapture() const
-{
- return m_screenCapture;
-}
-
-void QPlatformSurfaceCapture::updateError(QScreenCapture::Error error, const QString &errorString)
+void QPlatformSurfaceCapture::updateError(Error error, const QString &errorString)
{
bool changed = error != m_error || errorString != m_errorString;
m_error = error;
m_errorString = errorString;
if (changed) {
- if (m_error != QScreenCapture::NoError) {
- emit m_screenCapture->errorOccurred(error, errorString);
+ if (m_error != NoError) {
+ emit errorOccurred(error, errorString);
qWarning() << "Screen capture fail:" << error << "," << errorString;
}
- emit m_screenCapture->errorChanged();
+ emit errorChanged();
}
}
+bool QPlatformSurfaceCapture::checkScreenWithError(ScreenSource &screen)
+{
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+
+ if (screen)
+ return true;
+
+ updateError(NotFound, QLatin1String("No screens found"));
+ return false;
+}
+
QT_END_NAMESPACE
#include "moc_qplatformsurfacecapture_p.cpp"
diff --git a/src/multimedia/platform/qplatformsurfacecapture_p.h b/src/multimedia/platform/qplatformsurfacecapture_p.h
index be26b2286..dca48e2a1 100644
--- a/src/multimedia/platform/qplatformsurfacecapture_p.h
+++ b/src/multimedia/platform/qplatformsurfacecapture_p.h
@@ -1,8 +1,8 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#ifndef QPLATFORMSURFACEAPTURE_H
-#define QPLATFORMSURFACEAPTURE_H
+#ifndef QPLATFORMSURFACECAPTURE_H
+#define QPLATFORMSURFACECAPTURE_H
//
// W A R N I N G
@@ -16,7 +16,12 @@
//
#include "qplatformvideosource_p.h"
-#include "qscreencapture.h"
+#include "qscreen.h"
+#include "qcapturablewindow.h"
+#include "qpointer.h"
+
+#include <optional>
+#include <variant>
QT_BEGIN_NAMESPACE
@@ -27,33 +32,58 @@ class Q_MULTIMEDIA_EXPORT QPlatformSurfaceCapture : public QPlatformVideoSource
Q_OBJECT
public:
- explicit QPlatformSurfaceCapture(QScreenCapture *screenCapture);
+ enum Error {
+ NoError = 0,
+ InternalError = 1,
+ CapturingNotSupported = 2,
+ CaptureFailed = 4,
+ NotFound = 5,
+ };
+
+ using ScreenSource = QPointer<QScreen>;
+ using WindowSource = QCapturableWindow;
+
+ using Source = std::variant<ScreenSource, WindowSource>;
+
+ explicit QPlatformSurfaceCapture(Source initialSource);
- virtual void setScreen(QScreen *s) = 0;
- virtual QScreen *screen() const = 0;
+ void setActive(bool active) override;
+ bool isActive() const override;
- // TODO: move the methods and implementations to QPlatformWindowCapture
- virtual void setWindow(QWindow *w);
- virtual QWindow *window() const;
+ void setSource(Source source);
- // to be removed
- virtual void setWindowId(WId id);
- virtual WId windowId() const;
+ template<typename Type>
+ Type source() const {
+ return *q_check_ptr(std::get_if<Type>(&m_source));
+ }
- virtual QScreenCapture::Error error() const;
- virtual QString errorString() const;
+ Source source() const { return m_source; }
- QScreenCapture *screenCapture() const;
+ Error error() const;
+ QString errorString() const;
+
+protected:
+ virtual bool setActiveInternal(bool) = 0;
+
+ bool checkScreenWithError(ScreenSource &screen);
public Q_SLOTS:
- void updateError(QScreenCapture::Error error, const QString &errorString);
+ void updateError(Error error, const QString &errorString);
+
+Q_SIGNALS:
+ void sourceChanged(WindowSource);
+ void sourceChanged(ScreenSource);
+ void activeChanged(bool);
+ void errorChanged();
+ void errorOccurred(Error error, QString errorString);
private:
- QScreenCapture::Error m_error = QScreenCapture::NoError;
+ Error m_error = NoError;
QString m_errorString;
- QScreenCapture *m_screenCapture = nullptr;
+ Source m_source;
+ bool m_active = false;
};
QT_END_NAMESPACE
-#endif // QPLATFORMSURFACEAPTURE_H
+#endif // QPLATFORMSURFACECAPTURE_H