我如何使用Direct3D设备管理器?

6
我希望分享如何在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个回答

4
如果您没有进行任何视频处理,则我认为实现和/或使用IDirect3DDeviceManager9接口是没有意义的。
只需实现自己的管理Direct3D设备的方式,使接口指针可用于对象/线程并进行同步。 Direct3D设备并不是一种仅能通过IDirect3DDeviceManager9接口在对象/线程之间共享的神奇东西,它就像任何其他资源一样。如果初始化正确,甚至可以从不同线程同时调用某些方法(即几乎所有不依赖于可能被另一个线程更改的设备状态的内容)。
使接口指针可用可以很简单,例如使用持有指针的单例模式。或者,如果您的对象/线程已经以某种方式协作,它们必须已经具有交换信息的某些手段。因此,我认为您应该能够扩展您已经拥有的内容以让对象/线程可以访问Direct3D设备。同步可以通过使用CRITICAL_SECTION轻松完成。
如果您确实想使用IDirect3DDeviceManager9,那么只要我所理解的范围内,您必须在希望获得对IDirect3DDeviceManager9访问权限的所有对象上实现IMFGetService接口。实现GetService函数,以便在要求MR_VIDEO_ACCELERATION_SERVICE/IDirect3DDeviceManager9时返回一个指向管理Direct3D设备的对象的接口指针。
关于代码示例:希望这里给出的解释足够了。在多个线程之间共享东西是我不敢尝试用短代码示例来解释的事情。如果您知道如何编写多线程应用程序,则使用Direct3D设备与其他资源无异。如果您不知道如何编写多线程应用程序,则该主题远远超出了单个stackoverflow答案的复杂性。
关于为什么微软建议使用IDirect3DDeviceManager9的问题...好吧,我不知道是否存在这样的一般推荐。只有在进行视频处理(使用DXVA、EVR等)时才建议使用它。或者更准确地说是强制性的;我不确定是否可以在不使用D3D设备管理器的情况下与增强型视频呈现器共享D3D设备。毕竟,这就是D3D设备管理器的用途。使用VMR9与呈现器共享设备的方式只有两种:
已记录的方法:仅从VMR9的“present”回调中访问设备。这相当受限-例如,您受限于视频的帧率。

The undocumented way: 不要调用IVMRFilterConfig9::SetNumberOfStreams,并且只连接一个输入流。这样 VMR9 就不会切换到“混合器模式”,而当不在“混合器模式”下时,VMR9 将不会更改任何设备状态。因此,如果 D3D 设备被初始化为多线程,则您可以在 VMR9 使用相同的设备时自由使用 D3D 设备。

此外,使用 VMR9 时根本无法在另一个 DirectShow 滤镜中使用 D3D 设备。D3D 设备管理器改进了这一点,使滤镜和您自己的应用程序代码能够使用 D3D 设备 - 包括更改状态。但是,如果您自己实现将使用 D3D 设备的每个组件,则使用 D3D 设备管理器没有什么意义。即使您使用需要 D3D 设备的第三方组件,只有在这些组件支持 D3D 设备管理器时,您才能使用 D3D 设备管理器。除非这些组件碰巧是 DirectShow 或 MediaFoundation 滤镜/组件,否则可能不是这种情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接