DirectShow系统初级指南(5)
关于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<void**>(&pFilter));
if (SUCCEEDED(hr))
{
// Query for IDMOWrapperFilter.
IDMOWrapperFilter *pDmoWrapper;
hr = pFilter->QueryInterface(IID_IDMOWrapperFilter,
reinterpret_cast<void**>(&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的。
- 上一篇:VC++实现GPS全球定位系统定位数据的提取
- 下一篇:WTL自画按钮的实现