If you are not processing the video, I see no reason to implement and / or use the IDirect3DDeviceManager9
interface.
Simply implement your own way to control the lifetime of a Direct3D device by making the interface pointer available for your objects / threads and synchronize. A Direct3D device is not some kind of magical thing that can only be used between objects / streams using IDirect3DDeviceManager9
. This is just like any other resource. And if you initialize it correctly, you can even call certain methods simultaneously from different threads (i.e. almost everything that does not depend on the state of the device, which can be changed by another thread).
The availability of an interface pointer can be as simple as having a single element containing a pointer. Or, if your objects / threads are already collaborating somehow, they already have some ways of exchanging information. Therefore, I assume that you should simply expand on what you already have in order to give objects / threads access to the Direct3D device. And synchronization can be easily done using CRITICAL_SECTION
.
If you really want to use IDirect3DDeviceManager9
, then, as I understand it, you should implement the IMFGetService
interface for all objects from which you want to access IDirect3DDeviceManager9
. Implement the GetService
function GetService
that when you query MR_VIDEO_ACCELERATION_SERVICE
/ IDirect3DDeviceManager9
it MR_VIDEO_ACCELERATION_SERVICE
interface pointer to the object that controls your Direct3D device.
EDIT: Regarding the sample code: I hope that the explanation given here is enough. Sharing materials between multiple threads is something I dare not try to explain with a short sample code. If you know how to write multithreaded applications, then using a Direct3D device is no different from how it is done with other resources. And if you don’t know how to write multithreaded applications, then this topic is too complicated for a single answer on stackoverflow.
Regarding the question of why MS recommends using IDirect3DDeviceManager9
... well, I don't know such a general recommendation. It is simply recommended when processing video (using DXVA, EVR, etc.). Or more like a mandate; I'm not sure if you can share a D3D device, for example. Enhanced Video Renderer without using the D3D device manager. This is what the D3D Device Manager was created for. Sharing a VMR9 device with a visualization tool is possible in only two ways:
Documented way: Only ever access a device from a VMR9 “real” callback. This is quite limiting - for example, you are limited by the frame rate of a video.
Undocumented way: do not call IVMRFilterConfig9::SetNumberOfStreams
and only connect one input stream. Thus, VMR9 will not switch to “mixer mode”, and when not in “mixer mode”, VMR9 will not change the state of the device. Therefore, if a D3D device has been initialized with multithreading, you can freely use a D3D device, while VMR9 uses the same device.
Also with VMR9 it was not possible to use the D3D device in another DirectShow filter. The D3D Device Manager improves this by giving filters and your own program code the ability to use a D3D device, including state changes. If, however, you implement each component that will use the D3D device on its own, then there really is no point in controlling the D3D device. And even if you use third-party components that require a D3D device, you can only use the D3D device manager if these components support it. Most likely, this is not the case if these components are not filters / components of DirectShow or MediaFoundation.