Supplying a Custom Allocator-Presenter for VMR-9
[The feature associated with this page, DirectShow, is a legacy feature. It has been superseded by MediaPlayer, IMFMediaEngine, and Audio/Video Capture in Media Foundation. Those features have been optimized for Windows 10 and Windows 11. Microsoft strongly recommends that new code use MediaPlayer, IMFMediaEngine and Audio/Video Capture in Media Foundation instead of DirectShow, when possible. Microsoft suggests that existing code that uses the legacy APIs be rewritten to use the new APIs if possible.]
To use a custom allocator-presenter with the Video Mixing Renderer 9 (VMR-9) filter, perform the following steps:
Implement a class that supports the IVMRSurfaceAllocator9 and IVMRImagePresenter9 interfaces.
Call QueryInterface on the VMR-9 filter for the IVMRFilterConfig9 interface.
Call the IVMRFilterConfig9::SetRenderingMode method and pass in the VMR9Mode_Renderless flag.
QueryInterface on the VMR-9 filter for the IVMRSurfaceAllocatorNotify9 interface.
Call the IVMRSurfaceAllocatorNotify9::AdviseSurfaceAllocator method and pass in a pointer to your allocator-presenter's IVMRSurfaceAllocator9 method.
Call your allocator-presenter's IVMRSurfaceAllocator9::AdviseNotify method and pass in a pointer to the VMR-9 filter's IVMRSurfaceAllocatorNotify9 interface.
In your implementation of IVMRSurfaceAllocator9::AdviseNotify, call IVMRSurfaceAllocatorNotify9::SetD3DDevice Pass in a pointer to the Direct3D device and a handle to the monitor where the video will appear.
In your implementation of the IVMRSurfaceAllocator9::InitializeDevice method, Create Direct3D surfaces that match the parameters given in the InitializeDevice method. Optionally, you can use the VMR-9 filter's IVMRSurfaceAllocatorNotify9::AllocateSurfaceHelper method to allocate these surfaces. Store the surface pointers in an array.
Note
If you want the VMR-9 to draw the video frames onto a texture surface, add the VMR9AllocFlag_TextureSurface flag to the VMR9AllocationInfo structure. If the device does not support textures in the native video format, you might need to create a separate texture surface, and then copy the video frames from the video surface to the texture.
During streaming, the VMR-9 gets surfaces from the allocator-presenter by calling the IVMRSurfaceAllocator9::GetSurface method. The VMR-9 specifies the surface by its index within the surface array (step 8).
Present the image when the VMR-9 calls the IVMRImagePresenter9::PresentImage method. The parameters include a pointer to the Direct3D surface that contains the video image.
If the Direct3D device is lost at any time, the allocator-presenter must restore the device and recreate the surfaces. For example, the device can be lost if the display mode changes or the user moves the window to another monitor. If the Direct3D device changes, call the VMR-9 filter's IVMRSurfaceAllocatorNotify9::ChangeD3DDevice method.
When streaming stops, the VMR-9 calls the IVMRSurfaceAllocator9::TerminateDevice method. The allocator-presenter should release all of its Direct3D resources.
There are some differences between the VMR-7 and the VMR-9 in the way custom allocator-presenters are managed:
- The VMR-9 filter's AllocateSurfaceHelper method is available for the allocator-presenter to use when allocating surfaces. This method makes it unnecessary for a custom allocator-presenter to forward any calls to the default allocator-presenter. For this reason, the CLSID of the VMR-9 filter's default allocator-presenter is not published.
- Unlike the VMR-7, the VMR-9 does not provide a special DirectDraw Exclusive Mode allocator-presenter. The IVMRSurfaceAllocatorNotify9::AllocateSurfaceHelper method makes this object unnecessary.
- For interlaced video, the VMR-9 always de-interlaces the video before it presents the image. The allocator-presenter is no longer responsible for de-interlacing the image before displaying it.
Related topics