DX11VideoRenderer 线程安全吗?

Posted

技术标签:

【中文标题】DX11VideoRenderer 线程安全吗?【英文标题】:Is DX11VideoRenderer thread safe? 【发布时间】:2018-05-10 01:04:24 【问题描述】:

我正在使用 Microsoft 示例 DX11VideoRenderer 在 Windows 10 中渲染实时视频。当我只运行一个流时,视频看起来很棒。但是,当我运行超过 4 或 5 个流时,它们各自窗口中的一些视频开始间歇性地消隐。效果可以只覆盖每个视频窗口的一部分或全部。

此外,我的日志文件中的此函数调用也出现了一些间歇性错误:

hr = pVideoContext->VideoProcessorBlt(m_pVideoProcessor, pOutputView, 0, 1, &StreamData );

返回的错误是:E_INVALIDARG 一个或多个参数无效0x80070057

我只在我的代码中使用 DX11VideoRendererPresenter.cppdisplay.cpp 模块。源码位于: DirectX video rendering sample

我在这个阶段最初的怀疑是 DXVideoRenderer 可能不是线程安全的。我找到了有关多线程的信息:Introduction to Multithreading in Direct3D 11 其中指出:

虽然使用设备上下文 (ID3D11DeviceContext) 不是线程安全的,但使用 Direct3D 11 设备 (ID3D11Device) 是线程安全的。

但似乎由于我为每个窗口使用 CPresenter 类的单独实例,因此 ID3D11DeviceContext 不是线程安全的应该没有问题,因为每个窗口应该有它自己的 ID3D11DeviceContext 实例。

是否有人对此 DX11VideoRenderer 软件示例以及可能导致此问题的原因有任何经验或想法?

谢谢!

-更新-

我已经能够仅用一个窗口复制问题,因此它不再是线程问题。如果我多次手动调整窗口大小,有时我会使窗口中的视频闪烁。发生这种情况时,我在日志中看到对VideoProcessorBlt() 的相同函数调用失败,返回代码相同,E_INVALIDARG

【问题讨论】:

您是为每个窗口创建一个新设备还是只是一个延迟上下文?如果您在单个设备上使用不同的上下文,其中一个或多个是延迟上下文,并且可能视频渲染器无法绘制到延迟上下文。要获得多个即时上下文,您需要多个设备实例。 也许一个或多个参数确实无效?也许您程序的其他部分存在线程安全相关问题? 我不认为 DX11VideoRenderer 存在线程问题,但这并不一定意味着您使用此代码的部分也是线程安全的。总的来说,我认为这里的问题是错误的。如果您将渲染器用作完整的原语,那么我们将讨论其线程安全性,否则问题在于您的代码,并且在这个意义上没有提供足够的细节。 @ChuckWalbourn 我正在为每个新窗口调用 CPresenter::SetVideoWindow()。这会调用 CPresenter::CreateDXGIManagerAndDevice(),然后调用 D3D11CreateDevice(),为每个窗口创建一个新设备。 @VTT 我快速检查了 VideoProcessorBlt() 调用参数中的指针值,它们都与函数调用成功时相同。我需要更详细地检查指针所指的结构,看看是否存在差异。 【参考方案1】:

如果我多次手动调整窗口大小,有时会导致窗口中的视频闪烁。发生这种情况时,我在日志中看到对 VideoProcessorBlt() 的相同函数调用失败并返回相同的代码 E_INVALIDARG。

Microsoft 未记录此行为。

问题与 DirectX9 相同,但 IDirect3DDevice9::Present 出现错误,就在 VideoProcessBltHD 之后。 HRESULT 代码为 0x88760872,0x88760872 未记录。

所以在调整窗口大小时,可能会发生错误。

见H264Dxva2Decoder:

在 Dxva2Renderer.cpp 中,检查 HANDLE_DIRECTX_ERROR_UNDOCUMENTED。

我选择的策略是在播放时暂停视频(请参阅 WindowsFormProc 和 WM_ENTERSIZEMOVE/WM_SYSCOMMAND), 另外,这样可以避免闪烁。

执行此操作,错误消失。

PS:通常可以安全地忽略此错误。

我认为这个错误只是告诉你,当窗口调整大小时,底层 API 正在努力将 DirectX 演示文稿与你的 HWND 同步,这会迅速改变大小。

【讨论】:

以上是关于DX11VideoRenderer 线程安全吗?的主要内容,如果未能解决你的问题,请参考以下文章

吃鸡出现运行引擎dx11 运行引擎需要dx11功能级别10.0怎么解决

c++ string线程安全吗

C++ 中的标准输出流是线程安全的(cout、cerr、clog)吗?

C++11中的局部静态变量初始化线程安全吗? [复制]

面试官:你对多线程熟悉吗,谈谈线程安全中的原子性,有序性和可见性?

SecureRandom 线程安全吗?