Search code examples
c++directxscreenshotscreen-capturedxgi

Custom output resolution DuplicateOutput DXGI


I'm using AcquireNextFrame to make a screenshot of my desktop. Is it possible to set a dimension of the output image I want on the setup ? I saw on the documentation this function IDXGIOutput::SetDisplaySurface that could help. Here is my code :

//Here I init a output texture with less resolution 
    D3D11_TEXTURE2D_DESC desc;
    desc.Width = 1280;
    desc.Height = 720;
    desc.MipLevels = desc.ArraySize = 1;
    desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    desc.SampleDesc.Count = 1;
    desc.Usage = D3D11_USAGE_DYNAMIC;
    desc.BindFlags = 0;
    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
    desc.MiscFlags = 0;

    ID3D11Texture2D *pTexture = NULL;
    gDevice->CreateTexture2D(&desc, NULL, &pTexture);
    IDXGISurface *surface = nullptr;
    hr = gDevice->QueryInterface(__uuidof(IDXGISurface), reinterpret_cast<void **>(&pTexture));
    if (FAILED(hr))
        return;
    // Here I should make lDxgiOutput->setDisplaySurface(surface)
    hr = lDxgiOutput->GetDesc(&gOutputDesc);
    if (FAILED(hr))
        return;
    IDXGIOutput1 *lDxgiOutput1 = nullptr;
    hr = lDxgiOutput->QueryInterface(IID_PPV_ARGS(&lDxgiOutput1));
    if (FAILED(hr))
        return;
    lDxgiOutput->Release();
    hr = lDxgiOutput1->DuplicateOutput(gDevice, &gDeskDupl);
    if (FAILED(hr))
        return;

My screen is 1920x1080 and I would like to get image in 1280x720 for example. I'm getting an error on queryinterface function. Can someone tell me what I'm missing ? Or is there any solution to customize the resolution easier ? Thanks


Solution

  • Desktop Duplication API gets you a copy of desktop as a texture with least overhead. That is, no scaling is included. You can grab frames and scale them down as you wish, but this is not what Desktop Duplication does or expected to do for you.

    This question suggests a few ways (and the question is also related to Desktop Duplication):

    Additionally, you can use Media Foundation's Video Processor MFT, which is somewhat inflexible and has a possibly inconvenient form factor if you don't use Media Foundation otherwise, but properly set up scales using Direct3D 11 in efficient way performance-wise.

    See also on another related API for GPU-enabled scaling: