【问题标题】:DXGI Desktop Duplication Screen Capture Speed [closed]DXGI 桌面复制屏幕捕获速度
【发布时间】:2018-01-16 09:41:22
【问题描述】:

我正在使用Desktop Duplication API 中的AcquireNextFrame 来捕获屏幕。屏幕刷新率为120Hz。以 120FPS 运行游戏时,屏幕截图可以以 120FPS 的速度捕获帧。但是当游戏的帧率增加到 240FPS 时,屏幕截图实际上下降到了 70FPS 左右。我的猜测是额外的帧正在累积,这会增加开销,但我不确定。有没有办法避免这种性能下降?

【问题讨论】:

  • 做一些粗略的计算:视频内存到系统内存的最大传输速率与 240 fps(在您选择的分辨率下)需要多少带宽。我敢打赌你的内存总线超载了。
  • @RichardCritten:桌面复制本身不会将视频传输到系统内存。 API 使用者可能会进行传输。
  • 这不是关于“通用计算硬件和软件”的问题。从他们的个人资料来看,没有一个接近投票者甚至拥有足够的特定领域知识来理解这个问题。投票重新开放。如果这是可能的,我也会投票暂停每一个近距离投票者的故意破坏账户。
  • 问题很切题;投票重新开放。关闭背后应该有一些不明显的原因,例如盲目跟随其他投票,尤其是。争取各自的徽章,或失去对其帐户的控制权。
  • 这就是为什么人们拒绝 SO 的原因。这是一个完全合法的问题。

标签: c++ winapi screen-capture dxgi desktop-duplication


【解决方案1】:

Desktop Duplication API 通过设计累积监视器(DXGI 术语中的“输出”)更新,直到您通过AcquireNextFrame 请求它们。该 API 并非旨在首先捕获每个更新。此外,您没有指定是否在 AcquireNextFrame 循环中执行其他任何操作,或者您只是测量性能(尽管问题的语言建议后者)。

也就是说,对于一个真正密集的前端应用程序输出复制 API 来说,很可能会错过更新。那里也没有太大的灵活性。 ReleaseFrame 备注部分中提到的最重要的可用 MSDN 提示可能是:

出于性能原因,我们建议您在调用IDXGIOutputDuplication::AcquireNextFrame 方法获取下一帧之前释放帧。当客户端不拥有框架时,操作系统会将所有桌面更新复制到表面。如果操作系统为发生的每一帧更新相同的区域,这可能会导致浪费 GPU 周期。当客户端获取帧时,客户端只知道对该区域的最终更新;因此,前一帧中的任何重叠更新都被浪费了。当客户端获取帧时,客户端拥有表面;因此,操作系统只能跟踪更新的区域,而不能将桌面更新复制到表面。由于这种行为,我们建议您尽量减少调用释放当前帧和调用获取下一帧之间的时间。

也就是说,更早或更晚调用ReleaseFrame 会影响API 的内部行为。它要么在一般情况下累积更新,要么不断将实际有效负载数据复制到重复的帧资源中。

【讨论】:

  • 我不明白的是这些累积的帧丢失了还是像 FIFO 队列?因为当机器上的性能问题导致累积帧数上升时,当机器恢复正常并且我们继续成功获取时,它似乎永远不会下降。
  • @SimonMourier:操作系统维护组合桌面框架的侧面副本。只是桌面复制会话的复制资源(纹理),无需任何排队。 AcquireNextFrame/ReleaseFrame 是与访问此资源的操作系统协作的方式。在这两个调用之间,纹理是你的,操作系统正在跟踪脏部分。在 Acquire/Release 之外,除了跟踪之外,系统还会更新纹理。
  • 也就是说,在性能方面,如果获取器速度较慢,系统只会覆盖此复制纹理中的更改,直到下一个 AcquireNextFrame 调用到达。上面的 MSDN 引用解释说,操作系统将停止更新纹理(只是跟踪哪些区域需要稍后更新),直到ReleaseFrame 调用,这种方式延迟发布有助于防止过度更新 - 将有一个单一的联合更新稍后释放复制纹理时。
  • 谢谢!我错过了“侧面副本”的概念。
猜你喜欢
  • 2017-11-08
  • 1970-01-01
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
  • 2021-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多