如何使用Direct3D设备管理器?

时间:2012-06-21 21:38:50

标签: c++ direct3d ms-media-foundation direct3d9 dxva

我想在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();

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

  

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

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

1 个答案:

答案 0 :(得分:4)

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

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

使接口指针可用就像拥有一个包含指针的单例一样简单。或者,如果您的对象/线程已经以某种方式进行协作,那么它们必须已经有一些交换信息的方法。所以我想你应该能够扩展已有的东西,让对象/线程访问Direct3D设备。使用CRITICAL_SECTION可以轻松完成同步。

如果你确实想要使用IDirect3DDeviceManager9,那么 - 据我所知 - 你必须在所有想要访问{{{}的对象上实现IMFGetService接口。 1}}。实现IDirect3DDeviceManager9函数,以便在询问GetService / MR_VIDEO_ACCELERATION_SERVICE时,它返回一个指向管理Direct3D设备的对象的接口指针。


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

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

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

未记录的方式:不要调用IDirect3DDeviceManager9并且只连接一个输入流。这样VMR9就不会切换到“混音模式”,而当不处于“混音模式”时,VMR9不会改变任何设备状态。因此,如果D3D设备已初始化为多线程,则可以在VMR9使用同一设备时自由使用D3D设备。

同样使用VMR9,根本无法在另一个DirectShow过滤器中使用D3D设备。 D3D设备管理器对此进行了改进,为过滤器和您自己的应用程序代码提供了使用D3D设备的能力 - 包括更改状态。但是,如果您自己实现了将使用D3D设备的每个组件,那么使用D3D设备管理器并没有任何意义。即使您使用的是需要D3D设备的第三方组件,如果这些组件支持D3D设备管理器,您也只能使用它。除非这些组件碰巧是DirectShow或MediaFoundation过滤器/组件,否则可能不会出现这种情况。