美文网首页
DXGI捕获桌面

DXGI捕获桌面

作者: 上官宏竹 | 来源:发表于2022-01-13 10:19 被阅读0次

    DXGI与D3D关系

    DXGI 为未来的图形组件提供了一个通用框架。
    DXGI 的目的是与内核模式驱动程序和系统硬件进行通信,如下图所示。


    image.png

    DXGI捕获桌面图像流程

    1. 创建d3d设备,并通过d3d设备查询到DXGI设备
    2. 通过DXGI设备获取DXGI适配器IDXGIAdapter
    3. 通过DXGI适配器IDXGIAdapter,获取DXGI IDXGIOutputIDXGIOutput1
    4. 然后获取DXGI IDXGIOutputDuplication
    5. 通过IDXGIOutputDuplication的接口AcquireNextFrame获取桌面图像帧资源IDXGIResource
    6. 查询到桌面图像帧资源的纹理数据(数据类型是RGB数据)
    7. 释放帧ReleaseFrame

    获取DXGI适配器IDXGIAdapter

    // 为抓取桌面图像创建DXGI设备
    // 2.创建DXGI设备
    hr = m_device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&m_dxgiDevice));
    if (FAILED(hr)) {
        return false;
    }
    
    // 3.获取DXGI适配器
    hr = m_dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&m_dxgiAdapter));
    if (FAILED(hr)) {
        return false;
    }
    

    枚举显示器

    // 3.1 枚举所有显示器
    for (int i = 0; i < 6; i++) {
        IDXGIOutput* dxgiOutput;
        HRESULT hr = m_dxgiAdapter->EnumOutputs(i, &dxgiOutput);
        if (FAILED(hr)) {           
            break;
        }
        DXGI_OUTPUT_DESC desc;
        dxgiOutput->GetDesc(&desc);
    }
    

    获取DXGI IDXGIOutputDuplication

    // 4.获取DXGI output
    IDXGIOutput* dxgiOutput;
    HRESULT hr = dxgiAdapter->EnumOutputs(monitorIdx, &dxgiOutput);
    if (FAILED(hr)) {
        Log(LOG_ERROR, "failed for get EnumOutputs");
        return false;
    }     
    
    // 5.获取DXGI output1  
    IDXGIOutput1* dxgiOutput1;
    hr = dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), reinterpret_cast<void**>(&dxgiOutput1));
    if (FAILED(hr)) {
        Log(LOG_ERROR, "failed for get IDXGIOutput1");
        return false;
    }
    
    // 6.获取DXGI OutputDuplication    
    IDXGIOutputDuplication* outputDup;
    hr = dxgiOutput1->DuplicateOutput(device, &outputDup);
    if (FAILED(hr)) {
        Log(LOG_ERROR, "failed for DuplicateOutput");
        if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
            Log(LOG_ERROR, "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE");
        }
        return false;
    }
    

    获取图像帧

    // 7. 获取桌面图像
    DXGI_OUTDUPL_FRAME_INFO frameInfo;
    IDXGIResource* idxgiRes;
    HRESULT hr = m_outputDupV[idx]->AcquireNextFrame(1000, &frameInfo, &idxgiRes);
    
    ID3D11Texture2D* desktopTexture2d;
    hr = idxgiRes->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&desktopTexture2d));
    
    D3D11_TEXTURE2D_DESC desktopDesc;
    desktopTexture2d->GetDesc(&desktopDesc);
    

    捕获光标

    使用Windows API GetCursorInfo将捕获到光标数据。

    DXGI捕获桌面及光标处理
    NVENC编码

    NVENC编码

    NVENC 视频编码器 API 编程指南

    相关文章

      网友评论

          本文标题:DXGI捕获桌面

          本文链接:https://www.haomeiwen.com/subject/nhlpqrtx.html