最简单的基于DirectShow的示例:视频播放器自定义版(三)
2015-01-25 11:38:04
·
作者:
·
浏览: 15
, CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void**)(&pF_render));
if (FAILED(hr)){
printf(Failed to create Video Render.
);
return -1;
}
hr = pGraph->AddFilter(pF_render, LLei's Render);
if (FAILED(hr)){
printf(Failed to add Video Render to Filter Graph.
);
return -1;
}
//2. Connect Filters=======================
hr = connect_filters(pGraph, pF_source, pF_demuxer);
if (FAILED(hr)){
printf(Failed to link Source and Demuxer.
);
return -1;
}
hr = connect_filters(pGraph, pF_demuxer, pF_decoder);
if (FAILED(hr)){
printf(Failed to link Demuxer and Decoder.
);
return -1;
}
hr = connect_filters(pGraph, pF_decoder, pF_render);
if (FAILED(hr)){
printf(Failed to link Decoder and Render.
);
return -1;
}
pF_source->Release();
pF_demuxer->Release();
pF_decoder->Release();
pF_render->Release();
#else
IPin* Pin;
ULONG fetched;
// get output pin
IEnumPins* pEnumPins;
hr = pF_source->EnumPins(&pEnumPins);
hr = pEnumPins->Reset();
hr = pEnumPins->Next(1, &Pin, &fetched);
pEnumPins->Release();
// render pin, graph builder automatically complete rest works
hr = pGraph->Render(Pin);
#endif
if (SUCCEEDED(hr)){
// Run
hr = pControl->Run();
if (SUCCEEDED(hr)){
long evCode=0;
pEvent->WaitForCompletion(INFINITE, &evCode);
}
}
//Release
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
return 0;
}
运行结果
程序的运行结果如下图所示。运行后会播放“cuc_ieschool.mpg”文件。需要注意的是,本程序并没有加入音频解码和播放的Filter,所以播放视频的时候是没有声音的。

除了手动一个一个添加Filter之外,也可以在获得“源”Filter的Pin之后,直接调用IFilterGraph的Render()方法“智能”自动构建Filter Graph。注意Render()方法和RenderFile()方法是不一样的。RenderFile()是指定一个文件路径后,自动构建整个Filter Graph,相对来说更加简单些;而Render()方法则是首先要创建一个Source Filter之后,才可以自动构建整个Filter Graph。
可以通过修改源文件首部的宏定义ADD_MANUAL来设定是否手动添加Filter,如下所示。
//'1':Add filters manually
//'0':Add filters automatically
#define ADD_MANUAL 1
?