最简单的基于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

?