使用VMR9采集n个视频的一帧到一张位图

近来看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图:
使用VMR9采集n个视频的一帧到一张位图_第1张图片
 
下面开始具体的程序实现:
视频设备的枚举在我的简化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文档。
 
 
 
 

你可能感兴趣的:(使用VMR9采集n个视频的一帧到一张位图)