6#include <private/qabstractvideobuffer_p.h> 
   10#include <QtCore/private/qfactorycacheregistration_p.h> 
   15template <
typename Async>
 
   16auto wait_for(Async 
const& async, Windows::Foundation::TimeSpan 
const& 
timeout);
 
   18#include <winrt/Windows.Foundation.h> 
   19#include <winrt/Windows.Foundation.Collections.h> 
   20#include <winrt/Windows.Graphics.Capture.h> 
   21#include <winrt/Windows.Graphics.DirectX.h> 
   22#include <winrt/Windows.Graphics.DirectX.Direct3D11.h> 
   23#include <Windows.Graphics.Capture.h> 
   24#include <Windows.Graphics.Capture.Interop.h> 
   25#include <windows.graphics.directx.direct3d11.interop.h> 
   30#include <lowlevelmonitorconfigurationapi.h> 
   31#include <physicalmonitorenumerationapi.h> 
   37#include <private/qmultimediautils_p.h> 
   38#include <private/qwindowsmultimediautils_p.h> 
   39#include <private/qcapturablewindow_p.h> 
   40#include <qpa/qplatformscreen_p.h> 
   43#include <system_error> 
   49    using namespace winrt::Windows::Graphics::Capture;
 
   50    using namespace winrt::Windows::Graphics::DirectX;
 
   51    using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
 
   56using namespace Windows::Graphics::DirectX::Direct3D11;
 
   57using namespace std::chrono;
 
   88            DXGI_MAPPED_RECT 
rect = {};
 
   91                DXGI_SURFACE_DESC 
desc = {};
 
   92                hr = m_surface->GetDesc(&
desc);
 
  117        HRESULT hr = m_surface->Unmap();
 
  126    winrt::com_ptr<IDXGISurface> m_surface;
 
  134            winrt::GraphicsCaptureItem 
item, 
qreal maxFrameRate)
 
  135        : m_capture(capture),
 
  136          m_devicePool(devicePool),
 
  137          m_session(devicePool.framePool.CreateCaptureSession(
item)),
 
  151        m_session.IsCursorCaptureEnabled(
false);
 
  152        m_session.StartCapture();
 
  161        auto d3dFrame = m_devicePool.
framePool.TryGetNextFrame();
 
  165        if (m_frameSize != d3dFrame.ContentSize()) {
 
  166            m_frameSize = d3dFrame.ContentSize();
 
  168                                            winrt::DirectXPixelFormat::R8G8B8A8UIntNormalized, 1,
 
  169                                            d3dFrame.ContentSize());
 
  172        auto d3dSurface = d3dFrame.Surface();
 
  173        winrt::com_ptr<IDirect3DDxgiInterfaceAccess> dxgiInterfaceAccess{ d3dSurface.as<IDirect3DDxgiInterfaceAccess>() };
 
  174        if (!dxgiInterfaceAccess)
 
  177        winrt::com_ptr<IDXGISurface> dxgiSurface;
 
  178        HRESULT hr = dxgiInterfaceAccess->GetInterface(__uuidof(dxgiSurface), dxgiSurface.put_void());
 
  181                        "Failed to get DXGI surface interface");
 
  185        DXGI_SURFACE_DESC 
desc = {};
 
  186        hr = dxgiSurface->GetDesc(&
desc);
 
  189                        "Failed to get DXGI surface description");
 
  193        D3D11_TEXTURE2D_DESC texDesc = {};
 
  194        texDesc.Width = 
desc.Width;
 
  195        texDesc.Height = 
desc.Height;
 
  196        texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
 
  197        texDesc.Usage = D3D11_USAGE_STAGING;
 
  198        texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
 
  199        texDesc.MiscFlags = 0;
 
  200        texDesc.BindFlags = 0;
 
  201        texDesc.ArraySize = 1;
 
  202        texDesc.MipLevels = 1;
 
  203        texDesc.SampleDesc = { 1, 0 };
 
  205        winrt::com_ptr<ID3D11Texture2D> 
texture;
 
  206        hr = m_devicePool.
d3d11dev->CreateTexture2D(&texDesc, 
nullptr, 
texture.put());
 
  212        winrt::com_ptr<ID3D11DeviceContext> 
ctx;
 
  213        m_devicePool.
d3d11dev->GetImmediateContext(
ctx.put());
 
  214        ctx->CopyResource(
texture.as<ID3D11Resource>().get(), dxgiSurface.as<ID3D11Resource>().get());
 
  225    winrt::GraphicsCaptureSession m_session;
 
  226    winrt::Windows::Graphics::SizeInt32 m_frameSize;
 
  231    qCDebug(qLcWindowCaptureUwp) << 
"Creating UWP screen capture";
 
  239    winrt::com_ptr<ID3D11Device> d3d11dev;
 
  241            D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, 
nullptr, 0,
 
  242                              nullptr, 0, D3D11_SDK_VERSION, d3d11dev.put(), 
nullptr, 
nullptr);
 
  244        return { 
"Failed to create ID3D11Device device" + 
errorString(hr) };
 
  246    winrt::com_ptr<IDXGIDevice> dxgiDevice;
 
  247    hr = d3d11dev->QueryInterface(__uuidof(IDXGIDevice), dxgiDevice.put_void());
 
  249        return { 
"Failed to obtain dxgi for D3D11Device face" };
 
  251    winrt::IDirect3DDevice iDirect3DDevice{};
 
  252    hr = CreateDirect3D11DeviceFromDXGIDevice(
 
  253            dxgiDevice.get(), 
reinterpret_cast<::IInspectable **
>(winrt::put_abi(iDirect3DDevice)));
 
  255        return { 
"Failed to create IDirect3DDevice device" + 
errorString(hr) };
 
  257    auto pool = winrt::Direct3D11CaptureFramePool::Create(
 
  258        iDirect3DDevice, winrt::DirectXPixelFormat::R8G8B8A8UIntNormalized, 1, 
item.Size());
 
  262        return { 
"Failed to create capture frame pool" };
 
  273        return { 
"Cannot find nullptr screen" };
 
  276    HMONITOR 
handle = winScreen ? winScreen->handle() : 
nullptr;
 
  278    winrt::com_ptr<IDXGIFactory1> 
factory;
 
  279    HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), 
factory.put_void());
 
  281        return { 
"Failed to create IDXGIFactory" + 
errorString(hr) };
 
  283    winrt::com_ptr<IDXGIAdapter1> adapter;
 
  284    for (
quint32 i = 0; SUCCEEDED(
factory->EnumAdapters1(
i, adapter.put())); 
i++, adapter = {}) {
 
  285        winrt::com_ptr<IDXGIOutput> 
output;
 
  287            DXGI_OUTPUT_DESC 
desc = {};
 
  296    return { 
"Could not find screen adapter " + 
screen->
name() };
 
  301    HMONITOR 
handle = MonitorFromWindow(wh, MONITOR_DEFAULTTONULL);
 
  303        return { 
"Cannot find window screen" };
 
  305    winrt::com_ptr<IDXGIFactory1> 
factory;
 
  306    HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), 
factory.put_void());
 
  308        return { 
"Failed to create IDXGIFactory" + 
errorString(hr) };
 
  310    winrt::com_ptr<IDXGIAdapter1> adapter;
 
  311    for (
quint32 i = 0; SUCCEEDED(
factory->EnumAdapters1(
i, adapter.put())); 
i++, adapter = {}) {
 
  312        winrt::com_ptr<IDXGIOutput> 
output;
 
  314            DXGI_OUTPUT_DESC 
desc = {};
 
  322    return { 
"Could not find window screen adapter" };
 
  327    auto factory = winrt::get_activation_factory<winrt::GraphicsCaptureItem>();
 
  328    auto interop = 
factory.as<IGraphicsCaptureItemInterop>();
 
  330    winrt::GraphicsCaptureItem 
item = {
nullptr};
 
  331    HRESULT hr = interop->CreateForMonitor(
handle, __uuidof(ABI::Windows::Graphics::Capture::IGraphicsCaptureItem), winrt::put_abi(
item));
 
  333        return "Failed to create capture item for monitor" + 
errorString(hr);
 
  340    auto factory = winrt::get_activation_factory<winrt::GraphicsCaptureItem>();
 
  341    auto interop = 
factory.as<IGraphicsCaptureItemInterop>();
 
  343    winrt::GraphicsCaptureItem 
item = {
nullptr};
 
  344    HRESULT hr = interop->CreateForWindow(
handle, __uuidof(ABI::Windows::Graphics::Capture::IGraphicsCaptureItem), winrt::put_abi(
item));
 
  346        return "Failed to create capture item for window" + 
errorString(hr);
 
  353    if (hwnd == GetShellWindow())
 
  354        return "Cannot capture the shell window";
 
  359        return "Cannot capture windows without a class name";
 
  361    if (!IsWindowVisible(hwnd))
 
  362        return "Cannot capture invisible windows";
 
  364    if (GetParent(hwnd) != 0)
 
  365        return "Can only capture root windows";
 
  367    LONG style = GetWindowLong(hwnd, GWL_STYLE);
 
  368    if (style & WS_DISABLED)
 
  369        return "Cannot capture disabled windows";
 
  371    LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
 
  372    if (exStyle & WS_EX_TOOLWINDOW)
 
  373        return "No tooltips";
 
  375    DWORD cloaked = FALSE;
 
  376    HRESULT hr = DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, &cloaked, 
sizeof(cloaked));
 
  377    if (SUCCEEDED(hr) && cloaked == DWM_CLOAKED_SHELL)
 
  378        return "Cannot capture cloaked windows";
 
  386    if (GetNumberOfPhysicalMonitorsFromHMONITOR(
handle, &
count)) {
 
  390                MC_TIMING_REPORT screenTiming = {};
 
  391                if (GetTimingReport(monitor.hPhysicalMonitor, &screenTiming))
 
  392                    return qreal(screenTiming.dwVerticalFrequencyInHZ) / 100.;
 
  401    if (
bool(m_grabber) == active)
 
  413    const auto windowHandle = 
reinterpret_cast<HWND
>(
handle ? 
handle->id : 0);
 
  416        if (!
error.isEmpty()) {
 
  446    m_grabber = std::make_unique<Grabber>(*
this, maybePool.value(), maybeItem.value(), refreshRate);
 
  454    return winrt::GraphicsCaptureSession::IsSupported();
 
  464#include "qffmpegwindowcapture_uwp.moc" 
The QAbstractVideoBuffer class is an abstraction for video data. \inmodule QtMultimedia.
static const QCapturableWindowPrivate * handle(const QCapturableWindow &window)
void addFrameCallback(Object &object, Method method)
void errorUpdated(QPlatformSurfaceCapture::Error error, const QString &description)
void setFrameRate(qreal rate)
Grabber(QFFmpegWindowCaptureUwp &capture, DeviceFramePool &devicePool, winrt::GraphicsCaptureItem item, qreal maxFrameRate)
QVideoFrame grabFrame() override
bool setActiveInternal(bool active) override
QFFmpegWindowCaptureUwp()
static bool isSupported()
~QFFmpegWindowCaptureUwp() override
QVideoFrameFormat frameFormat() const override
Native interface to QScreen, to be retrieved from QPlatformIntegration. \inmodule QtGui.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
The QScreen class is used to query screen properties. \inmodule QtGui.
QString name
a user presentable string representing the screen
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
~QUwpTextureVideoBuffer()
QVideoFrame::MapMode mapMode() const override
QUwpTextureVideoBuffer(winrt::com_ptr< IDXGISurface > &&surface)
MapData map(QVideoFrame::MapMode mode) override
Independently maps the planes of a video buffer to memory.
void unmap() override
Releases the memory mapped by the map() function.
The QVideoFrame class represents a frame of video data.
MapMode
Enumerates how a video buffer's data is mapped to system memory.
Combined button and popup list for selecting options.
auto wait_for(Async const &async, Windows::Foundation::TimeSpan const &timeout)
static qreal getMonitorRefreshRateHz(HMONITOR handle)
static QMaybe< Monitor > findScreenForWindow(HWND wh)
static QString isCapturableWindow(HWND hwnd)
static QMaybe< DeviceFramePool > createCaptureFramePool(IDXGIAdapter1 *adapter, const winrt::GraphicsCaptureItem &item)
static QMaybe< winrt::GraphicsCaptureItem > createWindowCaptureItem(HWND handle)
static QMaybe< winrt::GraphicsCaptureItem > createScreenCaptureItem(HMONITOR handle)
static QMaybe< Monitor > findScreen(const QScreen *screen)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLuint64 GLenum void * handle
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLbitfield GLuint64 timeout
[4]
GLint GLsizei GLsizei GLenum format
GLsizei GLsizei GLchar * source
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
QT_BEGIN_NAMESPACE typedef uchar * output
const char className[16]
[1]
QItemEditorFactory * factory
winrt::Direct3D11CaptureFramePool framePool
winrt::IDirect3DDevice iDirect3DDevice
winrt::com_ptr< ID3D11Device > d3d11dev
winrt::com_ptr< IDXGIAdapter1 > adapter