Directx DX11VideoRenderer线程安全吗?

Directx DX11VideoRenderer线程安全吗?,directx,directx-11,ms-media-foundation,hardware-acceleration,dxva,Directx,Directx 11,Ms Media Foundation,Hardware Acceleration,Dxva,我正在使用Microsoft示例DX11VideoRenderer在Windows 10中渲染实时视频。当我只运行一个流时,视频看起来很棒。但是,当我运行超过4或5个流时,它们各自窗口中的一些视频开始间歇性地消失。效果可以覆盖每个视频窗口的一部分或全部 此外,我的日志文件中的此函数调用也会出现一些间歇性错误: hr = pVideoContext->VideoProcessorBlt(m_pVideoProcessor, pOutputView, 0, 1, &StreamData

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

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

hr = pVideoContext->VideoProcessorBlt(m_pVideoProcessor, pOutputView, 0, 1, &StreamData );
返回的错误为:E_INVALIDARG一个或多个参数无效0x80070057

我在代码中只使用了DX11VideoRendererPresenter.cppdisplay.cpp模块。资料来源位于:

在这个阶段,我最初的怀疑是DXVideoRenderer可能不是线程安全的。我发现了有关多线程的以下信息:哪些状态:

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

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

是否有人对此DX11VideoRenderer软件示例有任何经验或想法,以及是什么导致了此问题

谢谢大家!

-更新-

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

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

Microsoft没有记录这种行为

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

因此,在调整窗口大小时,可能会发生错误

见:

在Dxva2Renderer.cpp中,检查句柄\u DIRECTX\u错误\u未记录

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

这样,错误就会消失

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


我认为这个错误只是告诉您,当窗口调整大小时,底层API正在努力使DirectX演示文稿与HWND同步,而HWND的大小变化很快。

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