2008年1月4日 星期五

[DirectShow] Enhanced Video Render

著 Vista 的發表,  微軟為多媒體提供了新的 Render 技術 稱之為 EVR (abbreviation of Enhanced Video Render)

 

基本上,  EVR 就一個幫你把 video 顯示到使用者螢幕上的軟體元件. 對於新的 Media Foundation 應用程式, 使用的 EVR Media Sink, 而 對於舊的 DirectShow 應用程式, 則使用的是 EVR filters.

雖然你在 MSDN 看到的相關資料都與 Vista  相關, 但是 Enhanced Video Render 確定可以在你的 XP 上安全的執行並且編譯.

(只要你安裝 .Net Framework 3+, 則可以讓你的 XP 使用 EVR.)

 

基本性能

EVR 可以混和 16 個 video 串流到使用者螢幕上, 其中的一個 輸入串流當作基底的 reference stream. 其他的串流稱為 substreams 而被混和到 reference stream  上面.

所有 substreams 都可以為每一個 bit 設定透明資訊 ( per-pixel transparency), 而  reference stream 不行. [1]

基本上, EVR 使用了一個混合器 mixer 將所有的串流混合到一個顯示表面, 而 mixer 的混合輸出就是最後的 輸出 frame.

接著, 由一個稱為 presenter 的物件接手, 把最後的 frame 顯示出來.

 

EVR 與 VMR 的差異

1. EVR 不支援 windowed mode. 所以程式中不用設定一律 windowless

2. EVR 沒有 renderless mode, 要寫自己的 presenter, 請參考 [link]

3. EVR 沒有 mixing mode 的設定, 因為 它永遠會建立 mixer.

 

如果只是想執行, 則使用者只要安裝 .Net Framework 3.0 以上的版本, 若你想開發 EVR 程式, 那麼你將需要 Windows SDK for Windows Vista (下載) (請放心, XP 的使用者也能編譯)

WindowsSDK 

程式設計: 最簡單使用 Enhanced Video Render 範例

------------------------------------- code ----------------------------------

//  加入新建立 Enhanced Video Render 到你的 Graph 中
hr=AddFilterByCLSID(pBuilder,CLSID_EnhancedVideoRenderer,_T("Enhanced Video Render"),&m_pVR);
if(FAILED(hr)){
    MessageBox(NULL,_T("EVR fail"),_T("info"),MB_OK);
}

// Step 2: 設定顯示方式
//   a. 取得 GetService 工具物件

CComPtr<IMFGetService> pGetService = NULL; // include mfidl.h
hr = m_pVR->QueryInterface(__uuidof(IMFGetService), (void**)&pGetService);
if(FAILED(hr)){
    MessageBox(NULL,_T("IMFGetService fail"),_T("info"),MB_OK);
    return hr;
}
//   b. 利用工具物件取得 Video Display Control
CComPtr<IMFVideoDisplayControl> m_pVDC=NULL;   // include evr.h
hr=pGetService->GetService(MR_VIDEO_RENDER_SERVICE,__uuidof(IMFVideoDisplayControl),(void**)&m_pVDC);
if(FAILED(hr)){
    MessageBox(NULL,_T("GetService fail::The object does not support the service."),_T("info"),MB_OK);
    return hr;
}
//    c.  指定顯示的視窗
hr=m_pVDC->SetVideoWindow(hWnd);
if(FAILED(hr)){
    MessageBox(NULL,_T("SetVideoWindow fail::EVR"),_T("info"),MB_OK);
    return hr;
}

//     d. 指定串流顯示模式
hr=m_pVDC->SetAspectRatioMode(MFVideoARMode_None);
if(FAILED(hr)){
    MessageBox(NULL,_T("SetAspectRatioMode fail::EVR"),_T("info"),MB_OK);
    return hr;
}

------------------------------------- end of code ----------------------------------

設定串流顯示位置

RECT recDec=...
hr=m_pVDC->SetVideoPosition(NULL,&recDec);// 設定顯示位置

 

取得目前正在播放的影像

   BITMAPINFOHEADER hdr; // 回傳的 BMP 資訊
    DWORD               dwSize; // 資料長度
    LONGLONG TimeStamp;

    hdr.biSize=sizeof(BITMAPINFOHEADER);
    hr=m_pVDC->GetCurrentImage(&hdr,&lpDib,&dwSize,&TimeStamp);

 

 

 

相關下載

Reference

[1] 如何使用 DirectShow EVR filter ? [link]

by Jing

1 則留言:

  1. 8年前參考了這文章,implement程式,現在要重構程式,又來回顧一下這些細節。

    回覆刪除