VMR-9是DirectShow的渲染filter,可以修改它的allocator-presenter实现获取解码数据并自己渲染
使用DirectShow前需要安装解码器,否则只能解码avi、wmv等少数格式,推荐LVAFilters,这是基于FFMPEG的解码器
参考微软的文档:Supplying a Custom Allocator-Presenter for VMR-9和Direct3D 环境中的 DirectShow 电影
实现步骤:
- 自己写个类实现IVMRSurfaceAllocator9和IVMRImagePresenter9
- 调用IVMRFilterConfig9::SetRenderingMode设置VMR9Mode_Renderless
- 调用IVMRSurfaceAllocatorNotify9::AdviseSurfaceAllocator设置自己实现的allocator-presenter
- 调用IVMRSurfaceAllocatorNotify9::SetD3DDevice设置D3D设备
- 在IVMRSurfaceAllocator9::InitializeDevice里实现分配D3D表面,可以使用IVMRSurfaceAllocatorNotify9::AllocateSurfaceHelper
- 在IVMRImagePresenter9::PresentImage里实现渲染表面
Decoder.h:
#pragma once
#include <dshow.h>
#include <d3d9.h>
#include <vmr9.h>
#include <vector>
#include <functional>
class CDecoder : private IVMRSurfaceAllocator9, private IVMRImagePresenter9
{
public:
CDecoder(LPCWSTR fileName, HWND d3dHwnd, IDirect3DDevice9* device);
virtual ~CDecoder() = default;
virtual void Run();
virtual void Pause();
virtual void Stop();
virtual void GetVideoSize(SIZE& size);
// 设置需要呈现时的回调函数
virtual void SetOnPresent(std::function<void(VMR9Pre