使用VMR9采集n个视频的一帧到一张位图
2008-01-31 11:54
148 查看
近来看DirectX 9.0文档,越来越觉得它功能的强大。结合目前解决的一个问题: 即采集多个视频源的一帧到一张位图。它需要用到DirectX中的VMR。
VMR是新一代的video renderer,全称为Video Mixing Renderer,它分为VMR7和VMR9,VMR7基于DirectDraw7,只限于Windows XP;VMR9基于Direct3D9。因为我的例子可能会用于Windows 2000,所以我采用了可用于所有支持DirectX平台的VMR9。
VMR9可以使用3种工作模式,分别为windowed,windowless,renderless模式。后两种模式多用于游戏中。测试例子中用的是windowless模式。
先看下程序实现的截图和graph图:
下面开始具体的程序实现:
视频设备的枚举在我的简化MFC版amcp中有过描述,这里主要是VMR9的创建与设定。
另外生成graph的方法如连接PINs也是采用简化MFC版amcp中描述的Capture Graph Builder中的方法。
程序中需要的成员变量:
IVMRWindowlessControl9 *m_pWCVMR9; // VMR9的WINDOWLESS模式控制
IVMRMixerControl9 *m_pMCVMR9; // VMR9的Mix控制
IBaseFilter * m_pBFVMR9;// 用于创建VMR9
创建和配置VMR9:
HRESULT CMultiImageDlg::AddVideoMixingRendererToFG()
{
// create VMR9
HRESULT hRes = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC, IID_IBaseFilter, (LPVOID *)&m_pBFVMR9);
if(SUCCEEDED(hRes))
{
// add to filter graph
hRes = m_pGraphBuilder->AddFilter(m_pBFVMR9, L"Video Mixing Renderer 9");
if(SUCCEEDED(hRes))
{
// Test VMRConfig, VMRMonitorConfig
IVMRFilterConfig9* pConfig;
HRESULT hRes2 = m_pBFVMR9->QueryInterface(IID_IVMRFilterConfig9, (LPVOID *)&pConfig);
if(SUCCEEDED(hRes2))
{
// VMR9 already default to 4 input pins
hRes2 = pConfig->SetNumberOfStreams(4);
// windowless mode
hRes2 = pConfig->SetRenderingMode(VMR9Mode_Windowless);
// use overlays if available
hRes2 = pConfig->SetRenderingPrefs(RenderPrefs_AllowOverlays);
pConfig->Release();
}
// query control
hRes = m_pBFVMR9->QueryInterface(IID_IVMRWindowlessControl9, (LPVOID *)&m_pWCVMR9);
}
}
if(m_pBFVMR9)
{
m_pBFVMR9->Release();
}
if(SUCCEEDED(hRes))
{
// set owner window
HRESULT hr = m_pWCVMR9->SetVideoClippingWindow(m_hWnd);
// to preserve the aspect ratioof the source
hr = m_pWCVMR9->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX);
}
else
{
if(m_pWCVMR9)
{
m_pWCVMR9->Release();
m_pWCVMR9 = NULL;
}
}
return hRes;
}
另外可以在WM_PAINT中设置视频显示的重绘、WM_DISPLAYCHANGE中设置显示模式的改变、和在WM_SIZE中再次设置视频的位置。
对于视频输出矩形的设置:
对于多个输出流,VMR9通过一个”composition space”来设置它们的位置。在这个”composition space”中,可视视频矩形的坐标设置为(0.0, 0.0)到(1.0, 1.0)。所以如果有多个视频要布局,如本例程序中显示的那样,可以设置为:{0.0F, 0.0F, 0.5F, 0.5F, 1.0F}, {0.5F, 0.5F, 1.0F, 1.0F, 1.0F},数组中的最后一个为alpha值。通过数组中的参数可以看出,各个输出矩形可以设置输出比例和透明度。
最后,因为VMR9的input pins是连接多个视频源,所以通过它的接口GetCurrentImage得到输出视频的当前帧。
水平有限,不理解处可以参看DX文档。
VMR是新一代的video renderer,全称为Video Mixing Renderer,它分为VMR7和VMR9,VMR7基于DirectDraw7,只限于Windows XP;VMR9基于Direct3D9。因为我的例子可能会用于Windows 2000,所以我采用了可用于所有支持DirectX平台的VMR9。
VMR9可以使用3种工作模式,分别为windowed,windowless,renderless模式。后两种模式多用于游戏中。测试例子中用的是windowless模式。
先看下程序实现的截图和graph图:
下面开始具体的程序实现:
视频设备的枚举在我的简化MFC版amcp中有过描述,这里主要是VMR9的创建与设定。
另外生成graph的方法如连接PINs也是采用简化MFC版amcp中描述的Capture Graph Builder中的方法。
程序中需要的成员变量:
IVMRWindowlessControl9 *m_pWCVMR9; // VMR9的WINDOWLESS模式控制
IVMRMixerControl9 *m_pMCVMR9; // VMR9的Mix控制
IBaseFilter * m_pBFVMR9;// 用于创建VMR9
创建和配置VMR9:
HRESULT CMultiImageDlg::AddVideoMixingRendererToFG()
{
// create VMR9
HRESULT hRes = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC, IID_IBaseFilter, (LPVOID *)&m_pBFVMR9);
if(SUCCEEDED(hRes))
{
// add to filter graph
hRes = m_pGraphBuilder->AddFilter(m_pBFVMR9, L"Video Mixing Renderer 9");
if(SUCCEEDED(hRes))
{
// Test VMRConfig, VMRMonitorConfig
IVMRFilterConfig9* pConfig;
HRESULT hRes2 = m_pBFVMR9->QueryInterface(IID_IVMRFilterConfig9, (LPVOID *)&pConfig);
if(SUCCEEDED(hRes2))
{
// VMR9 already default to 4 input pins
hRes2 = pConfig->SetNumberOfStreams(4);
// windowless mode
hRes2 = pConfig->SetRenderingMode(VMR9Mode_Windowless);
// use overlays if available
hRes2 = pConfig->SetRenderingPrefs(RenderPrefs_AllowOverlays);
pConfig->Release();
}
// query control
hRes = m_pBFVMR9->QueryInterface(IID_IVMRWindowlessControl9, (LPVOID *)&m_pWCVMR9);
}
}
if(m_pBFVMR9)
{
m_pBFVMR9->Release();
}
if(SUCCEEDED(hRes))
{
// set owner window
HRESULT hr = m_pWCVMR9->SetVideoClippingWindow(m_hWnd);
// to preserve the aspect ratioof the source
hr = m_pWCVMR9->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX);
}
else
{
if(m_pWCVMR9)
{
m_pWCVMR9->Release();
m_pWCVMR9 = NULL;
}
}
return hRes;
}
另外可以在WM_PAINT中设置视频显示的重绘、WM_DISPLAYCHANGE中设置显示模式的改变、和在WM_SIZE中再次设置视频的位置。
对于视频输出矩形的设置:
对于多个输出流,VMR9通过一个”composition space”来设置它们的位置。在这个”composition space”中,可视视频矩形的坐标设置为(0.0, 0.0)到(1.0, 1.0)。所以如果有多个视频要布局,如本例程序中显示的那样,可以设置为:{0.0F, 0.0F, 0.5F, 0.5F, 1.0F}, {0.5F, 0.5F, 1.0F, 1.0F, 1.0F},数组中的最后一个为alpha值。通过数组中的参数可以看出,各个输出矩形可以设置输出比例和透明度。
最后,因为VMR9的input pins是连接多个视频源,所以通过它的接口GetCurrentImage得到输出视频的当前帧。
水平有限,不理解处可以参看DX文档。
相关文章推荐
- asp.net中使用ffmpeg (上传的视频转换成flv格式,并接一张图片)
- 使用JMF进行视频、音频的采集与实时传送
- Aforge视频采集,抓取图片,录制视频,WPF下使用Image控件显示视频
- <车载物联网项目,视频采集传输部分,第三天> 使用ffserver输出视频文件流,并且使用使用命令行终端播放视频文件
- 使用ffmpeg视频格式转换、视频截图、视频采集、屏幕录制
- D3D下使用VMR9播放视频文件
- Android 音视频开发(四):使用 Camera API 采集视频数据
- Linux下MIPS平台交叉编译FFMpeg库 及使用库截取视频中的某一帧
- 使用JMF进行视频、音频的采集与实时传送
- 基于FPGA的LCD+CMOS视频采集显示使用小结
- 如何使用matlab从视频中提取出一帧帧图像
- windows mobile中使用DirectShow开发视频流之从摄像头流中捕捉一张图片
- VC使用Halcon打开图片以及视频采集显示
- 使用opencv:从视频中获取每一帧图片
- [转载] ffmpeg摄像头视频采集-采集步骤概述并采集一帧视频
- 利用DSHOW中的VMR9 filter 将视频渲染成纹理 供D3D使用
- V4L2视频采集接口使用说明
- MediaMetadataRetriever 的使用,视频截取一帧
- <车载物联网项目,视频采集传输部分,第二天> 使用ffserver输出视频文件流,并且使用使用命令行终端播放视频文件
- V4L2视频采集以及使用libjpeg 用yuv转JPEG