10#define AVMediaType XAVMediaType
14#include <libavutil/hwcontext_videotoolbox.h>
15#include <libavutil/hwcontext.h>
19#include <AppKit/NSScreen.h>
21#include <dispatch/dispatch.h>
25const auto DefaultCVPixelFormat = kCVPixelFormatType_32BGRA;
27CGDirectDisplayID findDisplayByName(
const QString &
name)
29 for (NSScreen *
screen in NSScreen.screens) {
30 if (
name == QString::fromNSString(
screen.localizedName))
31 return [
screen.deviceDescription[
@"NSScreenNumber"] unsignedIntValue];
33 return kCGNullDirectDisplay;
41 CGRequestScreenCaptureAccess();
52 if (!CGPreflightScreenCaptureAccess()) {
57 auto screen = source<ScreenSource>();
62 return initScreenCapture(
screen);
74 if (!m_format || m_format !=
frame.surfaceFormat()) {
75 QMutexLocker<QMutex> locker(&m_formatMutex);
77 m_format =
frame.surfaceFormat();
92 QMutexLocker<QMutex> locker(&m_formatMutex);
94 m_waitForFormat.
wait(&m_formatMutex);
100 return AV_PIX_FMT_VIDEOTOOLBOX;
107 std::unique_ptr<QFFmpeg::HWAccel> hwAccel)
109 m_captureSession = [[AVCaptureSession alloc]
init];
113 capture.onNewFrame(
frame);
116 m_videoDataOutput = [[AVCaptureVideoDataOutput alloc]
init];
118 NSDictionary *videoSettings = [NSDictionary
119 dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:DefaultCVPixelFormat],
120 kCVPixelBufferPixelFormatTypeKey, nil];
122 [m_videoDataOutput setVideoSettings:videoSettings];
123 [m_videoDataOutput setAlwaysDiscardsLateVideoFrames:
true];
126 m_dispatchQueue = dispatch_queue_create(
"vf_queue",
nullptr);
127 [m_videoDataOutput setSampleBufferDelegate:m_sampleBufferDelegate
queue:m_dispatchQueue];
129 [m_captureSession addOutput:m_videoDataOutput];
131 [m_sampleBufferDelegate setHWAccel:std::move(hwAccel)];
134 [m_sampleBufferDelegate setVideoFormatFrameRate:
frameRate];
136 m_screenInput = [[AVCaptureScreenInput alloc] initWithDisplayID:screenID];
137 [m_screenInput setMinFrameDuration:CMTimeMake(1,
static_cast<int32_t
>(
frameRate))];
138 [m_captureSession addInput:m_screenInput];
140 [m_captureSession startRunning];
145 if (m_captureSession)
146 [m_captureSession stopRunning];
149 dispatch_release(m_dispatchQueue);
151 [m_sampleBufferDelegate
release];
158 AVCaptureSession *m_captureSession =
nullptr;
159 AVCaptureScreenInput *m_screenInput =
nullptr;
160 AVCaptureVideoDataOutput *m_videoDataOutput =
nullptr;
162 dispatch_queue_t m_dispatchQueue =
nullptr;
167 const auto screenID = findDisplayByName(
screen->
name());
169 if (screenID == kCGNullDirectDisplay) {
181 hwAccel->createFramesContext(av_map_videotoolbox_format_to_pixfmt(DefaultCVPixelFormat),
184 if (!hwAccel->hwFramesContextAsBuffer()) {
189 m_grabber = std::make_unique<Grabber>(*
this,
screen, screenID, std::move(hwAccel));
193void QAVFScreenCapture::resetCapture()
201#include "moc_qavfscreencapture_p.cpp"
Grabber(QAVFScreenCapture &capture, QScreen *screen, CGDirectDisplayID screenID, std::unique_ptr< QFFmpeg::HWAccel > hwAccel)
bool setActiveInternal(bool active) override
~QAVFScreenCapture() override
QVideoFrameFormat frameFormat() const override
std::optional< int > ffmpegHWPixelFormat() const override
static std::unique_ptr< HWAccel > create(AVHWDeviceType deviceType)
The QScreen class is used to query screen properties. \inmodule QtGui.
qreal devicePixelRatio
the screen's ratio between physical pixels and device-independent pixels
qreal refreshRate
the approximate vertical refresh rate of the screen in Hz
QSize size
the pixel resolution of the screen
QString name
a user presentable string representing the screen
\macro QT_RESTRICTED_CAST_FROM_ASCII
The QVideoFrame class represents a frame of video data.
bool wait(QMutex *, QDeadlineTimer=QDeadlineTimer(QDeadlineTimer::Forever))
Combined button and popup list for selecting options.
static constexpr qreal MaxScreenCaptureFrameRate
QLatin1StringView QLatin1String
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)