【问题标题】:Retrieving ID3D11Texture2D data to be sent over network检索要通过网络发送的 ID3D11Texture2D 数据
【发布时间】:2016-11-05 00:54:45
【问题描述】:

我正在修改桌面复制 api 示例 kindly provided by Microsoft 以捕获屏幕并通过网络将更新发送到我的应用程序。我知道如何实际发送数据;我的问题是从 ID3D11Texture2D 对象获取数据。

ID3D11Texture2D* m_AcquiredDesktopImage;
IDXGIResource* desktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;

// Get new frame
HRESULT hr = m_DeskDupl->AcquireNextFrame(500, &FrameInfo, &desktopResource);

// QI for IDXGIResource
hr = desktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&m_AcquiredDesktopImage));

此时,我认为屏幕更新在m_AcquiredDesktopImage。我需要通过网络传输这些数据(尽可能高效)。

This answer 似乎在正确的轨道上,但我是 Windows 编程新手,所以我需要一些额外的帮助。

这是我能想到的唯一使用IDXGIObject::GetPrivateData

的解决方案

【问题讨论】:

    标签: c++ windows winapi directx dxgi


    【解决方案1】:

    私人数据根本不是您想要的。它们仅用于将自定义值附加到 d3d 对象。

    一旦你有了ID3D11Texture2D 对象,你需要从中读回图像,你需要从ID3D11Device 在暂存内存池中创建第二个(获取原始描述,更改池,并删除绑定)。

    然后,您需要使用ID3D11DeviceContext 将纹理复制到使用CopyResource 的暂存区。然后就可以使用上下文MapUnmap api读取图片了。

    【讨论】:

    • 谢谢。我想我也许可以做到这一点。结果数据将采用什么格式? (因为我需要更新客户端上相应的屏幕区域)另外,一些伪代码会非常有帮助。
    • ID3D11Texture2D::GetDesc 为您提供格式。它将是基本相同的格式,因为ID3D11DeviceContext::CopyResource 的转换能力有限:“必须具有兼容的 DXGI 格式,这意味着格式必须相同或至少来自同一类型组”。
    • @RomanR。这就说得通了。我对此很有信心,但是在“暂存内存池”中创建第二个 ID2D11Texture2D 时遇到了麻烦。我需要什么方法来完成这个?我知道如何获取旧的描述,但我迷失了“更改池并删除绑定”。这是正确的方法吗:ID3D11Device::CreateTexture2D
    • 是的,CreateTexture2DD3D11_USAGE_STAGING。此外,如果您要编码(尤其是 H.264),那么您想使用采用视频内存支持纹理的硬件编码器 - 应该比先提取原始视频数据更有效。
    • 您说您将通过网络发送,并且您通常为此压缩视频,因为原始视频的大小很大。当然,您不必为此使用 H.264 - 考虑到脏/移动区域的屏幕编解码器可能更有效。另一方面,H.264 可能会提供高效的硬件辅助编码,这本身就是一大优势。
    【解决方案2】:

    我有一个很好的链接可以做到这一点.. 寻找方法SaveTextureToBmp

    [...]
    
    // map the texture
    ComPtr<ID3D11Texture2D> mappedTexture;
    D3D11_MAPPED_SUBRESOURCE mapInfo;
    mapInfo.RowPitch;
    hr = d3dContext->Map(
            Texture,
            0,  // Subresource
            D3D11_MAP_READ,
            0,  // MapFlags
            &mapInfo);
    
    if (FAILED(hr)) {
        // If we failed to map the texture, copy it to a staging resource
        if (hr == E_INVALIDARG) {
            D3D11_TEXTURE2D_DESC desc2;
            desc2.Width = desc.Width;
            desc2.Height = desc.Height;
            desc2.MipLevels = desc.MipLevels;
            desc2.ArraySize = desc.ArraySize;
            desc2.Format = desc.Format;
            desc2.SampleDesc = desc.SampleDesc;
            desc2.Usage = D3D11_USAGE_STAGING;
            desc2.BindFlags = 0;
            desc2.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
            desc2.MiscFlags = 0;
    
            ComPtr<ID3D11Texture2D> stagingTexture;
            hr = d3dDevice->CreateTexture2D(&desc2, nullptr, &stagingTexture);
            if (FAILED(hr)) {
                throw MyException::Make(hr, L"Failed to create staging texture");
            }
    
            // copy the texture to a staging resource
            d3dContext->CopyResource(stagingTexture.Get(), Texture);
    
            // now, map the staging resource
            hr = d3dContext->Map(
                    stagingTexture.Get(),
                    0,
                    D3D11_MAP_READ,
                    0,
                    &mapInfo);
            if (FAILED(hr)) {
                throw MyException::Make(hr, L"Failed to map staging texture");
            }
    
            mappedTexture = std::move(stagingTexture);
        } else {
            throw MyException::Make(hr, L"Failed to map texture.");
        }
    } else {
        mappedTexture = Texture;
    }
    auto unmapResource = Finally([&] {
        d3dContext->Unmap(mappedTexture.Get(), 0);
        });
    
        [...]
    
        hr = frameEncode->WritePixels(
                desc.Height,
                mapInfo.RowPitch,
                desc.Height * mapInfo.RowPitch,
                reinterpret_cast<BYTE*>(mapInfo.pData));
        if (FAILED(hr)) {
            throw MyException::Make(hr, L"frameEncode->WritePixels(...) failed.");
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-29
      • 2011-10-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多