Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qavfscreencapture.mm
Go to the documentation of this file.
1// Copyright (C) 2022 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 <QtFFmpegMediaPluginImpl/private/qavfscreencapture_p.h>
5
6#include <QtGui/qscreen.h>
7
8#include <QtFFmpegMediaPluginImpl/private/qavfsamplebufferdelegate_p.h>
9#include <QtFFmpegMediaPluginImpl/private/qffmpegsurfacecapturegrabber_p.h>
10#define AVMediaType XAVMediaType
11#include <QtFFmpegMediaPluginImpl/private/qffmpeghwaccel_p.h>
12#undef AVMediaType
13
14#define AVMediaType XAVMediaType
15extern "C" {
16#include <libavutil/hwcontext_videotoolbox.h>
17#include <libavutil/hwcontext.h>
18}
19#undef AVMediaType
20
21#import <AppKit/NSScreen.h>
22
23#import <dispatch/dispatch.h>
24
25namespace {
26
27const auto DefaultCVPixelFormat = kCVPixelFormatType_32BGRA;
28
29CGDirectDisplayID findDisplayByName(const QString &name)
30{
31 for (NSScreen *screen in NSScreen.screens) {
32 if (name == QString::fromNSString(screen.localizedName))
33 return [screen.deviceDescription[@"NSScreenNumber"] unsignedIntValue];
34 }
35 return kCGNullDirectDisplay;
36}
37}
38
39QT_BEGIN_NAMESPACE
40
41namespace QFFmpeg {
42
44{
45public:
82
84 {
87
88 if (m_dispatchQueue) {
89 // Push a blocking job to the background frame thread,
90 // so we guarantee future frames are discarded. This
91 // causes the frameHandler to be destroyed, and the reference
92 // to this QAVFScreenCapture is cleared.
95 [this]() {
97 });
98
100 }
101
106 }
107
108private:
114};
115
120
125
127{
128 if (active) {
130 updateError(CaptureFailed, QLatin1String("Permissions denied"));
131 return false;
132 }
133
134 auto screen = source<ScreenSource>();
135
137 return false;
138
140 } else {
141 resetCapture();
142 }
143
144 return true;
145}
146
148{
149 // Since writing of the format is supposed to be only from one thread,
150 // the read-only comparison without a mutex is thread-safe
151 if (!m_format || m_format != frame.surfaceFormat()) {
153
155
156 locker.unlock();
157
159 }
160
162}
163
165{
166 if (!m_grabber)
167 return {};
168
170 while (!m_format)
172 return *m_format;
173}
174
179
181{
182 const auto screenID = findDisplayByName(screen->name());
183
185 updateError(InternalError, QLatin1String("Screen exists but couldn't been found by name"));
186 return false;
187 }
188
190
191 if (!hwAccel) {
192 updateError(CaptureFailed, QLatin1String("Couldn't create videotoolbox hw acceleration"));
193 return false;
194 }
195
198
200 updateError(CaptureFailed, QLatin1String("Couldn't create hw frames context"));
201 return false;
202 }
203
205 return true;
206}
207
209{
211 m_format = {};
212}
213
215{
216 return std::make_unique<QAVFScreenCapture>();
217}
218
219} // namespace QFFmpeg
220
221QT_END_NAMESPACE
222
223#include "moc_qavfscreencapture_p.cpp"
std::conditional_t< QT_FFMPEG_AVIO_WRITE_CONST, const uint8_t *, uint8_t * > AvioWriteBufferType
std::unique_ptr< QPlatformSurfaceCapture > makeQAvfScreenCapture()