diff options
author | Artem Dyomin <artem.dyomin@qt.io> | 2023-06-21 20:48:21 +0200 |
---|---|---|
committer | Artem Dyomin <artem.dyomin@qt.io> | 2023-06-23 11:41:38 +0000 |
commit | 2bca3087d2b48bed46e6d959b35ebf34d5d256ac (patch) | |
tree | cd6606577fa6efa2cb2cb752afc2fc9f02566a2a /src/multimedia/platform | |
parent | aff72ee9082ae770746b4da9ddafa1a867ba31d2 (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.h | 2 | ||||
-rw-r--r-- | src/multimedia/platform/qplatformsurfacecapture.cpp | 64 | ||||
-rw-r--r-- | src/multimedia/platform/qplatformsurfacecapture_p.h | 68 |
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 |