一、硬加速的启动
对于能够启动硬加速的功能的实现,在decoder filter 和 后面的render filter都是有一定的要求的
在decoder能够启动硬加速之前,必须做以下这几个事情
1.Negotiate a media type.
2.Find a DXVA decoder configuration.
这一步又可以分成下面几个小的步骤:
1.Query the renderer's input pin for the IMFGetService interface.
2.Call IMFGetService::GetService to get a pointer to the IDirect3DDeviceManager9 interface. The service GUID is MR_VIDEO_ACCELERATION_SERVICE.
3.Call IDirect3DDeviceManager9::OpenDeviceHandle to get a handle to the renderer's Direct3D device.
4.Call IDirect3DDeviceManager9::GetVideoService and pass in the device handle. This method returns a pointer to the IDirectXVideoDecoderService interface.
5.Call IDirectXVideoDecoderService::GetDecoderDeviceGuids. This method returns an array of decoder device GUIDs.
6.Loop through the array of decoder GUIDs to find the ones that the decoder filter supports. For example, for an MPEG-2 decoder, you would look for DXVA2_ModeMPEG2_MOCOMP, DXVA2_ModeMPEG2_IDCT, or DXVA2_ModeMPEG2_VLD.
7.When you find a candidate decoder device GUID, pass the GUID to the IDirectXVideoDecoderService::GetDecoderRenderTargets method. This method returns an array of render target formats, specified as D3DFORMAT values.
8.Loop through the render target formats and look for one that matches your output format. Typically, a decoder device supports a single render target format. The decoder filter should connect to the renderer using this subtype. In the first call to CompleteConnect, the decoder can determing the render target format and then return this format as a preferred output type.
9.Call IDirectXVideoDecoderService::GetDecoderConfigurations. Pass in the same decoder device GUID, along with a DXVA2_VideoDesc structure that describes the proposed format. The method returns an array of DXVA2_ConfigPictureDecode structures. Each structure describes one possible configuration for the decoder device.
10.Assuming that the previous steps are successful, store the Direct3D device handle, the decoder device GUID, and the configuration structure. The filter will use this information to create the decoder device.
从以上步骤可以看出,对于DX提供的render来看的话,EVR支持DXVA2.0,VMR7和VMR9支持DXVA1.0。假设我们的decoder已经启动硬加速的设置操作已经完成,我们要创建一个自己的Filter,使它能够和deocoder配合起来启动硬加速,那么这个filter必须实现IMFGetService::GetService方法来得到IDirect3DDeviceManager9 接口。
3.Notify the video renderer that the decoder is using DXVA decoding.
这一步又可以分成下面几个小的步骤:
1.Query the renderer's input pin for the IMFGetService interface.
2.Call IMFGetService::GetService to get a pointer to the IDirectXVideoMemoryConfiguration interface. The service GUID is MR_VIDEO_ACCELERATION_SERVICE.
3.Call IDirectXVideoMemoryConfiguration::GetAvailableSurfaceTypeByIndex in a loop, incrementing the dwTypeIndex variable from zero. Stop when the method returns the value DXVA2_SurfaceType_DecoderRenderTarget in the pdwType parameter. This step ensures that the video renderer supports hardware-accelerated decoding. This step will always succeed for the EVR filter.
4.If the previous step succeeded, call IDirectXVideoMemoryConfiguration::SetSurfaceType with the value DXVA2_SurfaceType_DecoderRenderTarget. Calling SetSurfaceType with this value puts the video renderer into DXVA mode. When the video renderer is in this mode, the decoder must provide its own allocator.
同理,对于我们自己设计的和decoder连接的Filter要实现 IMFGetService::GetService方法来得到IDirectXVideoMemoryConfiguration。并且要重写IDirectXVideoMemoryConfiguration接口的GetAvailableSurfaceTypeByIndex方法和SetSurfaceType 方法。
4.Provide a custom allocator that allocates Direct3D surfaces.