From 7220147c1be55a40c5f8ff1b7bb1d0a0984ef829 Mon Sep 17 00:00:00 2001 From: Artem Dyomin Date: Fri, 22 Dec 2023 13:01:37 +0100 Subject: Add empty eglfs screen capture We need custom eglfs screen capture implementation as common QScreen::grabWindow implementation has valuable overhead. The patch adds matching classes and methods, implementation is supposed to go in next commits. Pick-to: 6.6 6.5 Change-Id: I40a605f3bd3651de51c75732041ffe28e385db91 Reviewed-by: Artem Dyomin Reviewed-by: Mikko Hallamaa Reviewed-by: Qt CI Bot (cherry picked from commit 8c814014c4131ca1193c443714e2d2756e4f7e58) Reviewed-by: Qt Cherry-pick Bot --- src/plugins/multimedia/ffmpeg/CMakeLists.txt | 5 ++ .../multimedia/ffmpeg/qeglfsscreencapture.cpp | 61 ++++++++++++++++++++++ .../multimedia/ffmpeg/qeglfsscreencapture_p.h | 45 ++++++++++++++++ .../multimedia/ffmpeg/qffmpegmediaintegration.cpp | 9 ++++ 4 files changed, 120 insertions(+) create mode 100644 src/plugins/multimedia/ffmpeg/qeglfsscreencapture.cpp create mode 100644 src/plugins/multimedia/ffmpeg/qeglfsscreencapture_p.h diff --git a/src/plugins/multimedia/ffmpeg/CMakeLists.txt b/src/plugins/multimedia/ffmpeg/CMakeLists.txt index 806d31635..8ba9a9264 100644 --- a/src/plugins/multimedia/ffmpeg/CMakeLists.txt +++ b/src/plugins/multimedia/ffmpeg/CMakeLists.txt @@ -195,6 +195,11 @@ qt_internal_extend_target(QFFmpegMediaPlugin CONDITION QT_FEATURE_xlib Xext ) +qt_internal_extend_target(QFFmpegMediaPlugin CONDITION QT_FEATURE_eglfs + SOURCES + qeglfsscreencapture.cpp qeglfsscreencapture_p.h +) + set_source_files_properties(qx11surfacecapture.cpp qx11capturablewindows.cpp # X headers PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) diff --git a/src/plugins/multimedia/ffmpeg/qeglfsscreencapture.cpp b/src/plugins/multimedia/ffmpeg/qeglfsscreencapture.cpp new file mode 100644 index 000000000..1837c3c57 --- /dev/null +++ b/src/plugins/multimedia/ffmpeg/qeglfsscreencapture.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2023 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 + +#include "qeglfsscreencapture_p.h" +#include "qffmpegsurfacecapturegrabber_p.h" +#include "qguiapplication.h" + +QT_BEGIN_NAMESPACE + +class QEglfsScreenCapture::Grabber : public QFFmpegSurfaceCaptureGrabber +{ +public: + Grabber(QEglfsScreenCapture &screenCapture, QScreen *screen) + : QFFmpegSurfaceCaptureGrabber(false) + { + setFrameRate(screen->refreshRate()); + addFrameCallback(screenCapture, &QEglfsScreenCapture::newVideoFrame); + connect(this, &Grabber::errorUpdated, &screenCapture, &QEglfsScreenCapture::updateError); + } + + ~Grabber() override { stop(); } + + QVideoFrameFormat format() { return m_format; } + + QVideoFrame grabFrame() override + { + // To be implemented: take a frame and updare m_format + return {}; + } + +private: + QVideoFrameFormat m_format; +}; + +QEglfsScreenCapture::QEglfsScreenCapture() : QPlatformSurfaceCapture(ScreenSource{}) { } + +QEglfsScreenCapture::~QEglfsScreenCapture() = default; + +QVideoFrameFormat QEglfsScreenCapture::frameFormat() const +{ + return m_grabber ? m_grabber->format() : QVideoFrameFormat(); +} + +bool QEglfsScreenCapture::setActiveInternal(bool active) +{ + if (m_grabber) + m_grabber.reset(); + else if (auto screen = source(); checkScreenWithError(screen)) + m_grabber = std::make_unique(*this, screen); + + return static_cast(m_grabber) == active; +} + +bool QEglfsScreenCapture::isSupported() +{ + // return QGuiApplication::platformName() == QLatin1String("eglfs")) + return false; +} + +QT_END_NAMESPACE diff --git a/src/plugins/multimedia/ffmpeg/qeglfsscreencapture_p.h b/src/plugins/multimedia/ffmpeg/qeglfsscreencapture_p.h new file mode 100644 index 000000000..bbef78428 --- /dev/null +++ b/src/plugins/multimedia/ffmpeg/qeglfsscreencapture_p.h @@ -0,0 +1,45 @@ +// Copyright (C) 2023 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 QEGLFSSCREENCAPTURE_H +#define QEGLFSSCREENCAPTURE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +class QEglfsScreenCapture : public QPlatformSurfaceCapture +{ +public: + QEglfsScreenCapture(); + + ~QEglfsScreenCapture() override; + + QVideoFrameFormat frameFormat() const override; + + static bool isSupported(); + +private: + bool setActiveInternal(bool active) override; + +private: + class Grabber; + std::unique_ptr m_grabber; +}; + +QT_END_NAMESPACE + +#endif // QEGLFSSCREENCAPTURE_H diff --git a/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp b/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp index 5c97e66b8..7d8859ebc 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp @@ -59,6 +59,10 @@ extern "C" { #include "qx11capturablewindows_p.h" #endif +#if QT_CONFIG(eglfs) +#include "qeglfsscreencapture_p.h" +#endif + QT_BEGIN_NAMESPACE class QFFmpegMediaPlugin : public QPlatformMediaPlugin @@ -213,6 +217,11 @@ QPlatformSurfaceCapture *QFFmpegMediaIntegration::createScreenCapture(QScreenCap return new QX11SurfaceCapture(QPlatformSurfaceCapture::ScreenSource{}); #endif +#if QT_CONFIG(eglfs) + if (QEglfsScreenCapture::isSupported()) + return new QEglfsScreenCapture; +#endif + #if defined(Q_OS_WINDOWS) return new QFFmpegScreenCaptureDxgi; #elif defined(Q_OS_MACOS) // TODO: probably use it for iOS as well -- cgit v1.2.3