036 [DirectShow] Enhanced Video Render

Post date: 2015/5/5 上午 06:29:30

隨著 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]

資料來源:http://mqjing.blogspot.com/2008/01/directshow-enhanced-video-render.html