AcolyticSubstrate
AcolyticSubstrate

Reputation: 49

DXGI API: AcquireNextFrame() never grabs an updated image, always blank

I've been playing around with someone else's code that implements the DXGI desktop duplication API and I've run into a strange issue. Here's the github link to the code I am using.

https://github.com/diederickh/screen_capture/blob/master/src/test/test_win_api_directx_research.cpp

All the code works fine up until I try to see what's in D3D11_MAPPED_SUBRESOURCE map.pData where all I get is a blank screen, specifically it's a repeating set of 0xFF000000, black at full alpha. Looking around for other solutions, I found that someone solved this problem using a while loop to check for when the frame successfully updates.

while (true)
{
    hr = duplication->AcquireNextFrame(INFINITE, &frame_info, &desktop_resource);
    if (hr && frame_info.LastPresentTime.QuadPart)
    {
        break;
    }
}

However, when I run this code, the console never exits and continues to run forever. Apparently, according to frame_info.LastPresentTime.QuadPart, the frame is never updating. What could be causing this? Is there a known condition that can cause this?

Upvotes: 1

Views: 2448

Answers (1)

Roman Ryltsov
Roman Ryltsov

Reputation: 69716

IDXGIOutputDuplication::AcquireNextFrame has good reasons to return without a frame. So it is true you might need to make a few attempts and check LastPresentTime to be non-zero.

The code snippet has two problems:

  1. hr check against zero is not quite accurate
  2. no matching ReleaseFrame for successful AcquireNextFrame call

So it's about this:

while (true)
{
    hr = duplication->AcquireNextFrame(INFINITE, &frame_info, &desktop_resource);
    if (FAILED(hr))
    {
        // TODO: Handle error
    }
    if (frame_info.LastPresentTime.QuadPart)
    {
        break;
    }
    duplication->ReleaseFrame(); // TODO: check returned value here as well
}

Upvotes: 3

Related Questions