22 static std::unique_ptr<Grabber> create(QGdiWindowCapture &capture, HWND hWnd)
24 auto hdcWindow = GetDC(hWnd);
26 capture.updateError(QPlatformSurfaceCapture::CaptureFailed,
27 QLatin1String(
"Cannot create a window drawing context"));
31 auto hdcMem = CreateCompatibleDC(hdcWindow);
34 capture.updateError(QPlatformSurfaceCapture::CaptureFailed,
35 QLatin1String(
"Cannot create a compatible drawing context"));
39 std::unique_ptr<Grabber> result(
new Grabber(capture, hWnd, hdcWindow, hdcMem));
40 if (!result->update())
64 Grabber(QGdiWindowCapture &capture, HWND hWnd, HDC hdcWindow, HDC hdcMem)
71 connect(
this, &Grabber::errorUpdated, &capture, &QGdiWindowCapture::updateError);
113 QVideoFrame grabFrame() override
118 const auto oldBitmap = SelectObject(m_hdcMem, m_hBitmap);
119 auto deselect = qScopeGuard([&]() { SelectObject(m_hdcMem, oldBitmap); });
121 const auto size = m_format.frameSize();
123 if (!BitBlt(m_hdcMem, 0, 0, size.width(), size.height(), m_hdcWindow, 0, 0, SRCCOPY)) {
124 updateError(QPlatformSurfaceCapture::CaptureFailed,
125 QLatin1String(
"Cannot copy image to the compatible DC"));
130 auto &header = info.bmiHeader;
131 header.biSize =
sizeof(BITMAPINFOHEADER);
132 header.biWidth = size.width();
133 header.biHeight = -size.height();
135 header.biBitCount = 32;
136 header.biCompression = BI_RGB;
138 const auto bytesPerLine = size.width() * 4;
140 QByteArray array(size.height() * bytesPerLine, Qt::Uninitialized);
142 const auto copiedHeight = GetDIBits(m_hdcMem, m_hBitmap, 0, size.height(), array.data(), &info, DIB_RGB_COLORS);
143 if (copiedHeight != size.height()) {
144 qCWarning(qLcGdiWindowCapture) << copiedHeight <<
"lines have been copied, expected:" << size.height();
152 if (header.biWidth != size.width() || header.biHeight != -size.height()
153 || header.biPlanes != 1 || header.biBitCount != 32 || header.biCompression != BI_RGB) {
154 updateError(QPlatformSurfaceCapture::CaptureFailed,
155 QLatin1String(
"Output bitmap info is unexpected"));
159 return QVideoFramePrivate::createFrame(
160 std::make_unique<QMemoryVideoBuffer>(std::move(array), bytesPerLine), m_format);