使用DXVA + EVR 硬解播放高清视频

时间:2023-01-31 19:14:56

最近给Intel做D2700的NVR方案,要求在该CPU上实现DXVA的硬解码,指标是硬解2路1080P30实时H264视频。这是第一次使用DSHOW,有一些心得,记录下来,与大家共享。

中间过程省略,直接写结果。最终方案为 1080p高清相机的实时souce filter + flv splitter + ffdshow  dxva video decoder + evr.

下面是我写的一个播放文件的测试程序,测试为 asyn file source + flv splitter + ffdshow  dxva video decoder + evr或者VMR9.在vista或win7下使用evr,在xp下使用VMR9。


开发环境: VS2008

1、使用DXVA硬解码的前提是你的显卡支持该功能。可以通过DXVA Checker这个工具来检测,例如下图是我的机器的检测结果。

使用DXVA + EVR 硬解播放高清视频


2、安装 Microsoft SDKs v6.0,当然7.0也可以。我用的是6.1.6000.16384.10.WindowsSDK_Vista_Feb2007Update_rtm.DVD.Rel.iso,下载路径为http://www.microsoft.com/download/en/details.aspx?DisplayLang=en&id=14477

安装完毕后,进入C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\Multimedia\DirectShow\BaseClasses,打开baseclasses.sln,将编译选项改为Debug,编译。


3、安装ffdshow,我用的是ffdshow_rev4292_201202_xvidvideo-ru_x86-MSVC2010.exe. 下载路径为http://download.csdn.net/detail/hunterzy38/4136770


安装完毕后,在开始--程序中,找到ffshow,打开DXVA VIDEO Decoder configuration,

使用DXVA + EVR 硬解播放高清视频

打开硬解加速功能,如下

使用DXVA + EVR 硬解播放高清视频


4、下载测试代码,路径为http://download.csdn.net/detail/hunterzy38/4136914 ,下载后得到EVR.rar,解压。


把测试视频1.flv拷贝到c盘的根目录下(因为代码中使用的是绝对路径)


5、运行reg.bat, 注册flv splitter,弹出提示,注册成功。


6、打开evr.sln,编译,运行。如果你电脑的系统是xp或以下,将使用VMR9进行显示,否则将使用EVR进行显示。


        OSVERSIONINFOEX  OSVERSIONINFO;
memset(&OSVERSIONINFO, 0 , sizeof(OSVERSIONINFO));
OSVERSIONINFO.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx((LPOSVERSIONINFOA)&OSVERSIONINFO);
if(OSVERSIONINFO.dwMajorVersion <= 5) //xp
{
//add Video Renderer
CComPtr<IBaseFilter> pVideoRenderer;
hr=pVideoRenderer.CoCreateInstance(CLSID_VideoMixingRenderer);
CHECK_HR(hr, "Can't create Video Renderer");
hr = pGraph->AddFilter(pVideoRenderer, L"Video Renderer");
CHECK_HR(hr, "Can't add Video Renderer to graph");

hr = pGraph->ConnectDirect(GetPin(pffdshowDXVAVideoDocoder, L"Out"), GetPin(pVideoRenderer, L"VMR Input0"),NULL);
CHECK_HR(hr, "Can't connect ffdshow DXVA Video Decoder and Video Renderer");
}
else //vista win7
{
CComPtr<IBaseFilter> pVideoRenderer;
hr = pVideoRenderer.CoCreateInstance(CLSID_EnhancedVideoRenderer);
CHECK_HR(hr, "Can't create enhanced Video Renderer");

hr = pGraph->AddFilter(pVideoRenderer, L"Video Renderer");
CHECK_HR(hr, "Can't add enhanced Video Renderer to graph");

CComPtr<IMFGetService> pGetService = NULL;
hr = pVideoRenderer->QueryInterface((__uuidof(IMFGetService)),(VOID ** )&pGetService);
CHECK_HR(hr, "IMFGetService failedh");


m_spDisplayCtrl = NULL;
hr = pGetService->GetService(MR_VIDEO_RENDER_SERVICE,__uuidof(IMFVideoDisplayControl), (void **)&m_spDisplayCtrl);

RECT Rect;
::GetClientRect (m_hWnd, &Rect);
m_spDisplayCtrl->SetVideoWindow (m_hWnd);
m_spDisplayCtrl->SetAspectRatioMode(MFVideoARMode_None);
m_spDisplayCtrl->SetVideoPosition(NULL, &Rect);


hr = pGraph->ConnectDirect(GetPin(pffdshowDXVAVideoDocoder, L"Out"), GetPin(pVideoRenderer, L"EVR Input0"),NULL);
CHECK_HR(hr, "Can't connect ffdshow DXVA Video Decoder and Enhanced Video Renderer");
}

其中,EVR主要是要自己设定显示的句柄,并设置显示的区域,并且需要响应ONSIZE和ONPAINT这两个消息。

详细可参考http://msdn.microsoft.com/en-us/library/aa965221%28v=vs.85%29.aspx


源码包路径为  http://download.csdn.net/detail/hunterzy38/4136914