Supplying a Custom Allocator-Presenter for VMR-9
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.
- Query the VMR-9 for the IVMRFilterConfig9 and IVMRSurfaceAllocatorNotify9 interfaces.
- Call the IVMRFilterConfig9::SetRenderingMode method with the VMR9Mode_Renderless flag.
- Call the IVMRSurfaceAllocatorNotify9::AdviseSurfaceAllocator method with a pointer to your allocator-presenter.
- Call the allocator-presenter's IVMRSurfaceAllocator9::AdviseNotify method with a pointer to the VMR-9 filter's IVMRSurfaceAllocatorNotify9 interface. This step and the previous step establish a communication link between the VMR-9 and the allocator-presenter.
- Allocate surfaces in the IVMRSurfaceAllocator9::InitializeDevice callback method:
- Call the IVMRSurfaceAllocatorNotify9::SetD3DDevice method with a pointer to the Direct3D device and a handle to the monitor.
- Create Direct3D surfaces that match the parameters given in the InitializeDevice method. You can use the VMR-9 filter's IVMRSurfaceAllocatorNotify9::AllocateSurfaceHelper method to allocate the surface.
- Typically you will want the video frames to be drawn onto a texture surface, so that you can render the texture onto a Direct3D primitive. In that case, you may need to add the VMR9AllocFlag_TextureSurface flag to the VMR9AllocationInfo structure (the lpAllocInfo parameter). 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.
- The VMR-9 gets a surface from the allocator-presenter by calling the IVMRSurfaceAllocator9::GetSurface method.
- 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, it is necessary to restore the device and 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 AllocateSurfaceHelper method makes this object unnecessary.
- For interlaced video, the VMR-9 always de-interlaces the video before calling the PresentImage method. The allocator-presenter is no longer responsible for de-interlacing the image before displaying it.