1

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?

Roman R.
  • 68,205
  • 6
  • 94
  • 158

1 Answers1

3

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
}
Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • I implemented the loop as you've described, but I'm still getting a blank frame. I'm checking by saving the pixel data in a 24-bit bitmap right after the d3d_context->Map() call, if that matters. It's curious that every time I run the program I'm getting exactly one printf alert from the duplication->ReleaseFrame() result. (timing threshold chance?) I can paste the code I'm working with if you want to look at it. – AcolyticSubstrate Aug 04 '18 at 07:59
  • You might have other problems in code, of course. This just gets you a valid texture. You probably want to copy to staging then map (what the code at your original [link here](https://github.com/diederickh/screen_capture/blob/master/src/test/test_win_api_directx_research.cpp#L392) does), so there might be other issues there too. – Roman R. Aug 04 '18 at 08:16
  • It turns out that I do get pixel data when I use a desktop background that fits the screen. Might it have something to do with updated regions on the screen? – AcolyticSubstrate Aug 04 '18 at 09:56
  • You get a texture will full copy of desktop (part that belongs to specific monitor on a multi-monitor system). – Roman R. Aug 04 '18 at 10:03