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:
83
85 {
88
89 if (m_dispatchQueue) {
90 // Push a blocking job to the background frame thread,
91 // so we guarantee future frames are discarded. This
92 // causes the frameHandler to be destroyed, and the reference
93 // to this QAVFScreenCapture is cleared.
96 [this]() {
98 });
99
101 }
102
107 }
108
109private:
115};
116
121
126
128{
129 if (active) {
131 updateError(CaptureFailed, QLatin1String("Permissions denied"));
132 return false;
133 }
134
135 auto screen = source<ScreenSource>();
136
138 return false;
139
141 } else {
142 resetCapture();
143 }
144
145 return true;
146}
147
149{
150 // Since writing of the format is supposed to be only from one thread,
151 // the read-only comparison without a mutex is thread-safe
152 if (!m_format || m_format != frame.surfaceFormat()) {
154
156
157 locker.unlock();
158
160 }
161
163}
164
166{
167 if (!m_grabber)
168 return {};
169
171 while (!m_format)
173 return *m_format;
174}
175
180
182{
183 const auto screenID = findDisplayByName(screen->name());
184
186 updateError(InternalError, QLatin1String("Screen exists but couldn't been found by name"));
187 return false;
188 }
189
191
192 if (!hwAccel) {
193 updateError(CaptureFailed, QLatin1String("Couldn't create videotoolbox hw acceleration"));
194 return false;
195 }
196
199
201 updateError(CaptureFailed, QLatin1String("Couldn't create hw frames context"));
202 return false;
203 }
204
206 return true;
207}
208
210{
212 m_format = {};
213}
214
216{
217 return std::make_unique<QAVFScreenCapture>();
218}
219
220} // namespace QFFmpeg
221
222QT_END_NAMESPACE
223
224#include "moc_qavfscreencapture_p.cpp"
std::conditional_t< QT_FFMPEG_AVIO_WRITE_CONST, const uint8_t *, uint8_t * > AvioWriteBufferType
std::unique_ptr< QPlatformSurfaceCapture > makeQAvfScreenCapture()