2、使用篩選器表管理器生成一個篩選器表
3、運行表,使數據在篩選器中流動。
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
// 在這裏添加錯誤處理代碼(Omitted for clarity.)
}
爲了簡單化,此例子忽略了返回值,但是您最好在方法調用中檢查HRESULT的值。
IGraphBuilder *pGraph;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
如上所示,類標識(CLSID)爲CLSID_FilterGraph。篩選器表管理器由一個進程內的DLL提供,所以執行上下文是 CLSCTX_INPROC_SERVER。DirectShow支持自由自由線程處理模式,因此您也可以使用COINIT_MULTITHREADED 標誌調用CoInitializeEx。
- IMediaControl,作用是控制流。它包含了停止和啓動表的方法
- IMediaEvent,它包含的方法是從篩選器表管理器中得到事件。在此例中,此接口用來等待播放的結束。
這兩個接口都是出現在篩選器表管理器中。可以使用返回的IGraphBuilder指針來查詢。
IMediaControl *pControl;
IMediaEvent *pEvent;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
如果指定的文件不存在,或文件格式無法,此方法將失敗。如果方法調用成功,篩選器還原器就做好播放的準備了。要運行表,調用IMediaControl::Run方法。
hr = pControl->Run();
當篩選器運行時,數據從篩選器中移出,並以視頻和音頻的方式還原出來。播放會啓動另一個線程。您可以調用IMediaEvent::WaitForCompletion方法。
long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);
當應用程序結束時,將釋放接口指針並關閉COM庫。
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
這裏列出了本文介紹的例子的完整代碼:
void main(void)
{
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
printf("ERROR - Could not initialize COM library");
return;
}
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph);
if (FAILED(hr))
{
printf("ERROR - Could not create the Filter Graph Manager.");
return;
}
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
hr = pGraph->RenderFile(L"C://Example.avi", NULL);
if (SUCCEEDED(hr))
{
// 運行表
hr = pControl->Run();
if (SUCCEEDED(hr))
{
// 等待結束
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
// 因爲它對應用程序的阻塞很不確定
}
}
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
}