Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qeglfsscreencapture.cpp
Go to the documentation of this file.
1
// Copyright (C) 2023 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#
include
"qeglfsscreencapture_p.h"
5
6
#
include
<
QtMultimedia
/
private
/
qsurfacecapturegrabber_p
.
h
>
7
#
include
"qguiapplication.h"
8
#
include
"qopenglvideobuffer_p.h"
9
#
include
"private/qimagevideobuffer_p.h"
10
#
include
"private/qvideoframe_p.h"
11
12
#
include
<
QtMultimedia
/
private
/
qmultimedia_ranges_p
.
h
>
13
#
include
<
QtOpenGL
/
private
/
qopenglcompositor_p
.
h
>
14
#
include
<
QtOpenGL
/
private
/
qopenglframebufferobject_p
.
h
>
15
16
#
ifndef
QT_NO_QUICK
17
#
include
<
QtQuick
/
qquickwindow
.
h
>
18
#
endif
19
20
QT_BEGIN_NAMESPACE
21
namespace
ranges = QtMultimediaPrivate::ranges;
22
23
class
QEglfsScreenCapture::
Grabber
:
public
QSurfaceCaptureGrabber
24
{
25
public
:
26
Grabber
(QEglfsScreenCapture &screenCapture, QScreen *screen)
27
:
QSurfaceCaptureGrabber
(
QSurfaceCaptureGrabber
::
UseCurrentThread
)
28
{
29
addFrameCallback(&screenCapture, &QEglfsScreenCapture::newVideoFrame);
30
connect(
this
, &Grabber::errorUpdated, &screenCapture, &QEglfsScreenCapture::updateError);
31
32
Q_ASSERT(screen);
33
setFrameRate(screenCapture.frameRate().value_or(qMin(screen->refreshRate(), 30.f)));
34
}
35
36
~
Grabber
()
override
{ stop(); }
37
38
QVideoFrameFormat
format
() {
return
m_format; }
39
40
protected
:
41
QVideoFrame
grabFrame
()
override
42
{
43
auto
nativeSize = QOpenGLCompositor::instance()->nativeTargetGeometry().size();
44
auto
fbo =
std
::make_unique<QOpenGLFramebufferObject>(nativeSize);
45
46
if
(!QOpenGLCompositor::instance()->grabToFrameBufferObject(
47
fbo.get(), QOpenGLCompositor::NotFlipped)) {
48
updateError(Error::InternalError, QLatin1String(
"Couldn't grab to framebuffer object"
));
49
return
{};
50
}
51
52
if
(!fbo->isValid()) {
53
updateError(Error::InternalError, QLatin1String(
"Framebuffer object invalid"
));
54
return
{};
55
}
56
57
auto
videoBuffer =
std
::make_unique<
QOpenGLVideoBuffer
>(
std
::move(fbo));
58
59
if
(!m_format.isValid()) {
60
auto
image = videoBuffer->ensureImageBuffer().underlyingImage();
61
m_format = { image.size(),
62
QVideoFrameFormat::pixelFormatFromImageFormat(image.format()) };
63
}
64
65
if
(m_format.streamFrameRate() != activeFrameRate())
66
m_format.setStreamFrameRate(activeFrameRate());
67
68
return
QVideoFramePrivate::createFrame(std::move(videoBuffer), m_format);
69
}
70
71
QVideoFrameFormat
m_format
;
72
};
73
74
#
ifndef
QT_NO_QUICK
75
class
QEglfsScreenCapture::
QuickGrabber
:
public
Grabber
76
{
77
public
:
78
QuickGrabber
(QEglfsScreenCapture &screenCapture, QScreen *screen, QQuickWindow *quickWindow)
79
:
Grabber
(
screenCapture
,
screen
)
,
m_quickWindow
(
quickWindow
)
80
{
81
Q_ASSERT(m_quickWindow);
82
}
83
84
protected
:
85
QVideoFrame
grabFrame
()
override
86
{
87
if
(!m_quickWindow) {
88
updateError(Error::InternalError, QLatin1String(
"Window deleted"
));
89
return
{};
90
}
91
92
QImage image = m_quickWindow->grabWindow();
93
94
if
(image.isNull()) {
95
updateError(Error::InternalError, QLatin1String(
"Image invalid"
));
96
return
{};
97
}
98
99
if
(!m_format.isValid()) {
100
m_format = { image.size(),
101
QVideoFrameFormat::pixelFormatFromImageFormat(image.format()) };
102
}
103
104
if
(m_format.streamFrameRate() != activeFrameRate())
105
m_format.setStreamFrameRate(activeFrameRate());
106
107
return
QVideoFramePrivate::createFrame(
108
std::make_unique<QImageVideoBuffer>(std::move(image)), m_format);
109
}
110
111
private
:
112
QPointer<QQuickWindow> m_quickWindow;
113
};
114
#
endif
// QT_NO_QUICK
115
116
QEglfsScreenCapture::QEglfsScreenCapture() : QPlatformSurfaceCapture(ScreenSource{}) { }
117
118
QEglfsScreenCapture::~QEglfsScreenCapture() =
default
;
119
120
QVideoFrameFormat QEglfsScreenCapture::frameFormat()
const
121
{
122
return
m_grabber ? m_grabber->format() : QVideoFrameFormat();
123
}
124
125
bool
QEglfsScreenCapture::setActiveInternal(
bool
active)
126
{
127
if
(
static_cast
<
bool
>(m_grabber) == active)
128
return
true
;
129
130
if
(m_grabber)
131
m_grabber.reset();
132
133
if
(!active)
134
return
true
;
135
136
m_grabber = createGrabber();
137
138
if
(!m_grabber) {
139
// TODO: This could mean that the UI is not started yet, so we should wait and try again,
140
// and then give error if still not started. Might not be possible here.
141
return
false
;
142
}
143
144
m_grabber->start();
145
return
true
;
146
}
147
148
bool
QEglfsScreenCapture::isSupported()
149
{
150
return
QGuiApplication::platformName() == QLatin1String(
"eglfs"
);
151
}
152
153
std::unique_ptr<QEglfsScreenCapture::Grabber> QEglfsScreenCapture::createGrabber()
154
{
155
auto
screen = source<ScreenSource>();
156
if
(!checkScreenWithError(screen))
157
return
nullptr
;
158
159
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
160
161
if
(compositor->context() && QOpenGLContext::currentContext()) {
162
// Create OpenGL grabber
163
if
(!compositor->targetWindow()) {
164
updateError(Error::CaptureFailed,
165
QLatin1String(
"Target window is not set for OpenGL compositor"
));
166
return
nullptr
;
167
}
168
169
return
std
::make_unique<
Grabber
>(*
this
, screen);
170
}
171
172
#
ifndef
QT_NO_QUICK
173
// Check for QQuickWindow
174
auto
windows = QGuiApplication::topLevelWindows();
175
auto
it = ranges::find_if(windows, [screen](QWindow *window) {
176
auto
quickWindow = qobject_cast<QQuickWindow *>(window);
177
if
(!quickWindow)
178
return
false
;
179
180
return
quickWindow->screen() == screen;
181
});
182
183
if
(it != windows.end()) {
184
// Create grabber that calls QQuickWindow::grabWindow
185
return
std
::make_unique<
QuickGrabber
>(*
this
, screen, qobject_cast<QQuickWindow *>(*it));
186
}
187
#
endif
// QT_NO_QUICK
188
189
updateError(Error::CaptureFailed, QLatin1String(
"No existing OpenGL context or QQuickWindow"
));
190
return
nullptr
;
191
}
192
193
QT_END_NAMESPACE
QEglfsScreenCapture::Grabber
Definition
qeglfsscreencapture.cpp:24
QEglfsScreenCapture::Grabber::Grabber
Grabber(QEglfsScreenCapture &screenCapture, QScreen *screen)
Definition
qeglfsscreencapture.cpp:26
QEglfsScreenCapture::Grabber::~Grabber
~Grabber() override
Definition
qeglfsscreencapture.cpp:36
QEglfsScreenCapture::Grabber::m_format
QVideoFrameFormat m_format
Definition
qeglfsscreencapture.cpp:71
QEglfsScreenCapture::Grabber::format
QVideoFrameFormat format()
Definition
qeglfsscreencapture.cpp:38
QEglfsScreenCapture::Grabber::grabFrame
QVideoFrame grabFrame() override
Definition
qeglfsscreencapture.cpp:41
QEglfsScreenCapture::QuickGrabber
Definition
qeglfsscreencapture.cpp:76
QEglfsScreenCapture::QuickGrabber::grabFrame
QVideoFrame grabFrame() override
Definition
qeglfsscreencapture.cpp:85
QEglfsScreenCapture::QuickGrabber::QuickGrabber
QuickGrabber(QEglfsScreenCapture &screenCapture, QScreen *screen, QQuickWindow *quickWindow)
Definition
qeglfsscreencapture.cpp:78
QOpenGLVideoBuffer
Definition
qopenglvideobuffer_p.h:26
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
qtmultimedia
src
plugins
multimedia
ffmpeg
qeglfsscreencapture.cpp
Generated on
for Qt by
1.18.0