9#include "private/qimagevideobuffer_p.h"
10#include "private/qvideoframe_p.h"
12#include <QtOpenGL/private/qopenglcompositor_p.h>
13#include <QtOpenGL/private/qopenglframebufferobject_p.h>
16#include <QtQuick/qquickwindow.h>
24 Grabber(QEglfsScreenCapture &screenCapture, QScreen *screen)
27 addFrameCallback(screenCapture, &QEglfsScreenCapture::newVideoFrame);
28 connect(
this, &Grabber::errorUpdated, &screenCapture, &QEglfsScreenCapture::updateError);
31 setFrameRate(std::min(screen->refreshRate(), qreal(30.0)));
41 auto nativeSize = QOpenGLCompositor::instance()->nativeTargetGeometry().size();
42 auto fbo =
std::make_unique<QOpenGLFramebufferObject>(nativeSize);
44 if (!QOpenGLCompositor::instance()->grabToFrameBufferObject(
45 fbo.get(), QOpenGLCompositor::NotFlipped)) {
46 updateError(Error::InternalError, QLatin1String(
"Couldn't grab to framebuffer object"));
50 if (!fbo->isValid()) {
51 updateError(Error::InternalError, QLatin1String(
"Framebuffer object invalid"));
57 if (!m_format.isValid()) {
58 auto image = videoBuffer->ensureImageBuffer().underlyingImage();
59 m_format = { image.size(), QVideoFrameFormat::pixelFormatFromImageFormat(image.format()) };
60 m_format.setStreamFrameRate(frameRate());
63 return QVideoFramePrivate::createFrame(std::move(videoBuffer), m_format);
73 QuickGrabber(QEglfsScreenCapture &screenCapture, QScreen *screen, QQuickWindow *quickWindow)
76 Q_ASSERT(m_quickWindow);
83 updateError(Error::InternalError, QLatin1String(
"Window deleted"));
87 QImage image = m_quickWindow->grabWindow();
90 updateError(Error::InternalError, QLatin1String(
"Image invalid"));
94 if (!m_format.isValid()) {
95 m_format = { image.size(),
96 QVideoFrameFormat::pixelFormatFromImageFormat(image.format()) };
97 m_format.setStreamFrameRate(frameRate());
100 return QVideoFramePrivate::createFrame(
101 std::make_unique<QImageVideoBuffer>(std::move(image)), m_format);
105 QPointer<QQuickWindow> m_quickWindow;
109QEglfsScreenCapture::QEglfsScreenCapture() : QPlatformSurfaceCapture(ScreenSource{}) { }
111QEglfsScreenCapture::~QEglfsScreenCapture() =
default;
113QVideoFrameFormat QEglfsScreenCapture::frameFormat()
const
115 return m_grabber ? m_grabber->format() : QVideoFrameFormat();
118bool QEglfsScreenCapture::setActiveInternal(
bool active)
120 if (
static_cast<
bool>(m_grabber) == active)
129 m_grabber = createGrabber();
141bool QEglfsScreenCapture::isSupported()
143 return QGuiApplication::platformName() == QLatin1String(
"eglfs");
146std::unique_ptr<QEglfsScreenCapture::Grabber> QEglfsScreenCapture::createGrabber()
148 auto screen = source<ScreenSource>();
149 if (!checkScreenWithError(screen))
152 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
154 if (compositor->context()) {
156 if (!compositor->targetWindow()) {
157 updateError(Error::CaptureFailed,
158 QLatin1String(
"Target window is not set for OpenGL compositor"));
162 return std::make_unique<
Grabber>(*
this, screen);
167 auto windows = QGuiApplication::topLevelWindows();
168 auto it = std::find_if(windows.begin(), windows.end(), [screen](QWindow *window) {
169 auto quickWindow = qobject_cast<QQuickWindow *>(window);
173 return quickWindow->screen() == screen;
176 if (it != windows.end()) {
178 return std::make_unique<QuickGrabber>(*
this, screen, qobject_cast<QQuickWindow *>(*it));
182 updateError(Error::CaptureFailed, QLatin1String(
"No existing OpenGL context or QQuickWindow"));
Grabber(QEglfsScreenCapture &screenCapture, QScreen *screen)
QVideoFrameFormat m_format
QVideoFrameFormat format()
QVideoFrame grabFrame() override
QVideoFrame grabFrame() override
QuickGrabber(QEglfsScreenCapture &screenCapture, QScreen *screen, QQuickWindow *quickWindow)