DXGI API:AcquireNextFrame() 从不抓取更新的图像,始终为空白
Posted
技术标签:
【中文标题】DXGI API:AcquireNextFrame() 从不抓取更新的图像,始终为空白【英文标题】:DXGI API: AcquireNextFrame() never grabs an updated image, always blank 【发布时间】:2019-01-11 21:30:15 【问题描述】:我一直在使用其他人的实现 DXGI 桌面复制 API 的代码,但遇到了一个奇怪的问题。这是我正在使用的代码的 github 链接。
https://github.com/diederickh/screen_capture/blob/master/src/test/test_win_api_directx_research.cpp
所有代码都可以正常工作,直到我尝试查看 D3D11_MAPPED_SUBRESOURCE map.pData 中的内容,我得到的只是一个空白屏幕,特别是它是一组重复的 0xFF000000,全 alpha 为黑色。在寻找其他解决方案时,我发现有人使用 while 循环来检查框架何时成功更新,从而解决了这个问题。
while (true)
hr = duplication->AcquireNextFrame(INFINITE, &frame_info, &desktop_resource);
if (hr && frame_info.LastPresentTime.QuadPart)
break;
但是,当我运行此代码时,控制台永远不会退出并继续永远运行。显然,根据 frame_info.LastPresentTime.QuadPart,框架永远不会更新。这可能是什么原因造成的?是否存在可能导致这种情况的已知情况?
【问题讨论】:
【参考方案1】:IDXGIOutputDuplication::AcquireNextFrame
有充分的理由在没有框架的情况下返回。因此,确实您可能需要进行几次尝试并检查LastPresentTime
是否为非零。
代码sn-p有两个问题:
hr
零校验不太准确
ReleaseFrame
没有匹配成功的AcquireNextFrame
调用
原来如此:
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
【讨论】:
我按照你的描述实现了循环,但我仍然得到一个空白帧。如果这很重要,我正在通过在 d3d_context->Map() 调用之后将像素数据保存在 24 位位图中进行检查。奇怪的是,每次我运行程序时,我都会从 duplication->ReleaseFrame() 结果中得到一个 printf 警报。 (时间阈值机会?)如果您想查看,我可以粘贴我正在使用的代码。 当然,您可能在代码中遇到其他问题。这只是给你一个有效的纹理。您可能想要复制到 staging 然后映射(原始 link here 的代码所做的),所以那里可能还有其他问题。 事实证明,当我使用适合屏幕的桌面背景时,我确实获得了像素数据。可能与屏幕上的更新区域有关? 您将获得一个纹理将完整复制桌面(在多显示器系统上属于特定显示器的部分)。以上是关于DXGI API:AcquireNextFrame() 从不抓取更新的图像,始终为空白的主要内容,如果未能解决你的问题,请参考以下文章
AcquireNextFrame 不工作(桌面复制 API 和 D3D11)
DXGI EnumOutputs - 没有 DXGI_OUTPUT_DESC 和空显示模式数组
DXGI 1.5 DuplicateOutput1 因 DXGI_ERROR_UNSUPPORTED (0x887a0004) 而失败