78 Grabber(QCGWindowCapture &capture, CGWindowID wid) : m_capture(capture), m_wid(wid)
80 addFrameCallback(*
this, &Grabber::onNewFrame);
81 connect(
this, &Grabber::errorUpdated, &capture, &QCGWindowCapture::updateError);
83 if (
auto screen = QGuiApplication::primaryScreen())
84 setFrameRate(screen->refreshRate());
100 QVideoFrame grabFrame() override
102 if (
auto rate = frameRateForWindow(m_wid))
105 auto imageRef = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow,
106 m_wid, kCGWindowImageBoundsIgnoreFraming);
108 updateError(QPlatformSurfaceCapture::CaptureFailed,
109 QLatin1String(
"Cannot create image by window"));
113 auto imageDeleter = qScopeGuard([imageRef]() { CGImageRelease(imageRef); });
115 if (CGImageGetBitsPerPixel(imageRef) != 32
116 || CGImageGetPixelFormatInfo(imageRef) != kCGImagePixelFormatPacked
117 || CGImageGetByteOrderInfo(imageRef) != kCGImageByteOrder32Little) {
118 qWarning() <<
"Unexpected image format. PixelFormatInfo:"
119 << CGImageGetPixelFormatInfo(imageRef)
120 <<
"BitsPerPixel:" << CGImageGetBitsPerPixel(imageRef) <<
"AlphaInfo"
121 << CGImageGetAlphaInfo(imageRef)
122 <<
"ByteOrderInfo:" << CGImageGetByteOrderInfo(imageRef);
124 updateError(QPlatformSurfaceCapture::CapturingNotSupported,
125 QLatin1String(
"Not supported pixel format"));
129 QVideoFrameFormat format(QSize(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)),
130 QVideoFrameFormat::Format_BGRA8888);
131 format.setStreamFrameRate(frameRate());
133 return QVideoFramePrivate::createFrame(std::make_unique<QCGImageVideoBuffer>(imageRef),
137 void onNewFrame(QVideoFrame frame)
141 if (!m_format || m_format != frame.surfaceFormat()) {
142 QMutexLocker<QMutex> locker(&m_formatMutex);
144 m_format = frame.surfaceFormat();
148 m_waitForFormat.notify_one();
151 emit m_capture.newVideoFrame(frame);