如何使用Direct3D设备管理器?

Chr*_*ian 6 c++ direct3d direct3d9 dxva ms-media-foundation

我想在Direct3D应用程序中的多个线程和对象之间共享一个Direct3D设备.我遇到了Direct3D设备管理器,它看起来像我想要的,虽然我没有做任何视频处理或视频加速:http: //msdn.microsoft.com/en-us/library/windows/desktop/aa965267( v = vs.85)的.aspx

在我的代码中,我正在做以下事情:

  // Create the device manager
  UINT resetToken = 0;
  IDirect3DDeviceManager9* deviceManager = NULL;
  if (FAILED(DXVA2CreateDirect3DDeviceManager9(&resetToken, &deviceManager)))
    return false;

  // Add the device to the device manager
  if (FAILED(deviceManager->ResetDevice(device, resetToken)))
    return false;

  deviceManager->AddRef();
Run Code Online (Sandbox Code Playgroud)

我的问题是,一旦我创建了Direct3D设备管理器,如何在不传递指向设备管理器的指针的情况下与其他对象共享direct3d设备管理器?微软已经明确表示会做以下事情,但我不知道以下内容的真正含义:

设备所有者必须为其他对象提供一种获取指向IDirect3DDeviceManager9接口的指针的方法.标准机制是实现IMFGetService接口.服务GUID是MR_VIDEO_ACCELERATION_SERVICE.

有人可以告诉我如何使用IMFGetService接口共享设备管理器吗?

Pau*_*oke 4

如果您不进行任何视频处理,那么我认为实现和/或使用该IDirect3DDeviceManager9界面没有意义。

只需实现您自己的方式来管理 Direct3D 设备的生命周期,使接口指针可供您的对象/线程使用并进行同步。Direct3D 设备并不是什么神奇的东西,只能通过IDirect3DDeviceManager9. 它就像任何其他资源一样。如果你正确地初始化它,你甚至可以从不同的线程同时调用某些方法(即几乎所有不依赖于可能被另一个线程更改的设备状态的东西)。

使接口指针可用就像使用一个保存指针的单例一样简单。或者,如果您的对象/线程已经以某种方式进行协作,那么它们必须已经具有某种交换信息的方法。因此,我认为您应该能够扩展已有的功能,让对象/线程能够访问 Direct3D 设备。并且可以通过使用 轻松完成同步CRITICAL_SECTION

如果您确实想使用IDirect3DDeviceManager9,那么 - 据我了解 - 您必须IMFGetService在您想要访问的所有对象上实现该接口IDirect3DDeviceManager9。实现该GetService函数,以便在请求MR_VIDEO_ACCELERATION_SERVICE/时IDirect3DDeviceManager9返回一个指向管理 Direct3D 设备的对象的接口指针。


编辑:关于代码示例:我希望这里给出的解释足够了。我不敢尝试用简短的代码示例来解释在多个线程之间共享内容。如果您知道如何编写多线程应用程序,那么使用 Direct3D 设备与使用其他资源的方式没有什么不同。如果您不知道如何编写多线程应用程序,那么该主题到目前为止对于单个 stackoverflow 答案来说太复杂了。

关于为什么微软建议使用IDirect3DDeviceManager9......的问题,我不知道这样的一般性建议。仅建议在进行视频处理(使用 DXVA、EVR 等)时使用。或者更像是强制的;我不确定您是否可以在不使用 D3D 设备管理器的情况下与增强型视频渲染器等共享 D3D 设备。毕竟,这就是 D3D 设备管理器的用途。对于 VMR9 与渲染器共享设备只能通过两种方式实现:

记录的方式:仅从 VMR9 的“当前”回调访问设备。这是相当有限的 - 例如,您受限于视频的帧速率。

未记录的方式:不调用IVMRFilterConfig9::SetNumberOfStreams并且仅连接一个输入流。这样,VMR9 将不会切换到“混合器模式”,并且当不处于“混合器模式”时,VMR9 将不会更改任何设备状态。因此,如果 D3D 设备是多线程初始化的,那么您可以在 VMR9 使用同一设备时自由使用 D3D 设备。

此外,对于 VMR9,根本不可能在另一个 DirectShow 过滤器中使用 D3D 设备。D3D 设备管理器对此进行了改进,使过滤器和您自己的应用程序代码能够使用 D3D 设备 - 包括更改状态。然而,如果您自己实现将使用 D3D 设备的每个组件,那么使用 D3D 设备管理器实际上没有任何意义。即使您使用需要 D3D 设备的第三方组件,您也只能在这些组件支持的情况下使用 D3D 设备管理器。情况可能并非如此,除非这些组件恰好是 DirectShow 或 MediaFoundation 过滤器/组件。