2012-06-21 61 views
6

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

在我的代码,我做了以下内容:

// 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接口共享设备管理器吗?

回答

4

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

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

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

如果你真的想使用IDirect3DDeviceManager9,然后 - 据我了解它 - 你必须实现从要获得访问IDirect3DDeviceManager9所有对象IMFGetService接口。实现GetService函数,以便当被问及MR_VIDEO_ACCELERATION_SERVICE/IDirect3DDeviceManager9时,它会返回一个指向管理Direct3D设备的对象的接口指针。


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

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

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

无证方式:不叫IVMRFilterConfig9::SetNumberOfStreams只能连接一个输入流。这样VMR9将不会切换到“调音台模式”,而当不处于“调音台模式”时,VMR9不会改变任何设备状态。因此,如果D3D设备初始化为多线程,那么您可以在VMR9使用相同设备时自由使用D3D设备。

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