使用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圖:
 
下面開始具體的程序實現:
視頻設備的枚舉在我的簡化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文檔。
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章