複製鏈接
請複製以下鏈接發送給好友

DMO

鎖定
是微軟提供的一種流數據處理COM組件。與DirectShow filter相比,DMO有很多相似之處。對filter原理的熟悉,將會大大幫助你對DMO的學習。另外,DMO也因其結構簡單、易於創建和使用而倍受微軟推崇。關於DMO的使用方式,大概有兩種:一種是應用程序直接使用DMO,另一種就是在DirectShow filter中的應用。後者比較簡單,只是使用了一個DMO wrapper filter。在DirectShow應用程序中,DMO是對用户透明的,所有使用DMO的工作均由DMO wrapper filter來完成。
中文名
DMO
外文名
DirectX Media Objects
屬    性
微軟的一種流數據處理COM組件
特    點
比filter實現的功能要少很多
直通模式
直通模式DMO

目錄

DMO對比

1. DMO比filter實現的功能要少很多,這使得DMO“體積”很小;
2. DMO使用起來比filter更有靈活性。DMO的使用不需要filter graph,應用程序可以直接與DMO交互。而DMO也可以通過一個DMO wrapper filter工作於DirectShow環境;
3. DMO總是同步處理數據,不像filter有獨立的數據傳送線程,需要考慮多線程編程問題;
4. 與傳統的編解碼管理器ACM、VCM相比,用DMO開發的編解碼器是基於COM的,更易於擴展。並且DMO支持多個輸入和多個輸出;
5. DMO不需要像filter一樣分配數據傳送的內存,而有DMO的使用者負責;
6. DMO是一個獨立功能模塊,不需要像filter一樣連接成一條鏈路;
7. DMO不需要像filter一樣將數據“推”下去,數據的輸入輸出都是由DMO的使用者完成的;
所有這些優點,使得DMO成為微軟對於Encoder和Decoder開發的重點推薦模式。DirectX 9.0 SDK中,微軟更是把DMO從DirectShow中分離出來,而對於一些transform filter,微軟也推薦用DMO的方式來替換。

DMO使用方式

關於DMO的使用方式,大概有兩種:一種是應用程序直接使用DMO,另一種就是在DirectShow filter中的應用。後者比較簡單,只是使用了一個DMO wrapper filter。在DirectShow應用程序中,DMO是對用户透明的,所有使用DMO的工作均由DMO wrapper filter來完成。參見下面的代碼。
// Create the DMO Wrapper filter.
IBaseFilter *pFilter;
HRESULT hr = CoCreateInstance(CLSID_DMOWrapperFilter, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
reinterpret_cast(&pFilter));
if (SUCCEEDED(hr))
{
// Query for IDMOWrapperFilter.
IDMOWrapperFilter *pDmoWrapper;
hr = pFilter->QueryInterface(IID_IDMOWrapperFilter,
reinterpret_cast(&pDmoWrapper));
if (SUCCEEDED(hr))
{
// Initialize the filter.
hr = pDmoWrapper->Init(CLSID_MyDMO, DMOCATEGORY_VIDEO_EFFECT);
pDmoWrapper->Release();
if (SUCCEEDED(hr))
{
// Add the filter to the graph.
hr = pGraph->AddFilter(pFilter, L"My DMO");
}
}
pFilter->Release();
}
而對於DMO的直接使用,以下幾點是要特別注意的。
1. 在處理數據之前,必須為每條輸入輸出stream設置media type(Optional stream除外);
2. 從DMO從獲取的media type未必包含format塊,但是在給DMO設置media type時,務必帶上這部分信息(MIDI除外);
3. 應用程序必須自己負責分配數據緩存。緩存的大小可以通過調用DMO的IMediaObject::GetInputSizeInfo或IMediaObject::GetOutputSizeInfo得到。DMO使用的數據緩存也是一個COM對象,支持ImediaBuffer接口,與DirectShow filter的Media Sample類似。
4. 一般的DMO依次調用IMediaObject::ProcessInput和IMediaObject::ProcessOutput處理數據,In-Place的DMO調用IMediaObjectInPlace::Process處理數據。兩套方法不能混用。
5. 在調用ProcessOutput時,如果返回的標記是DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE,説明數據的數據還沒有完全取出,需要再次調用ProcessOutput。
6. 所有輸入數據都已輸入完成,應該調用DMO的IMediaObject::Discontinuity方法。
7. 如果你想中斷數據處理流程,調用DMO的IMediaObject::Flush。
8. 區別兩種不同的可丟棄stream,標記分別為DMO_OUTPUT_STREAMF_OPTIONAL和DMO_OUTPUT_STREAMF_DISCARDABLE。注意,後者是要設置media type的。