隨著 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 的使用者也能編譯)
程式設計: 最簡單使用 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);
相關下載
- .Net Framework 3.5 (197 Mbytes) [download]
- Windows SDK for Windows Vista (放心! 如果你是 XP 也可以安裝): http://www.microsoft.com/downloads/details.aspx?FamilyID=c2b1e300-f358-4523-b479-f53d234cdccf&DisplayLang=en
Reference
[1] 如何使用 DirectShow EVR filter ? [link]
by Jing
8年前參考了這文章,implement程式,現在要重構程式,又來回顧一下這些細節。
回覆刪除