当前位置: 代码迷 >> 多媒体/流媒体开发 >> DirectShow IGraphBuilder:RenderFile有关问题
  详细解决方案

DirectShow IGraphBuilder:RenderFile有关问题

热度:7587   发布时间:2013-02-26 00:00:00.0
DirectShow IGraphBuilder::RenderFile问题
我是DShow新手,请教下高手,IGraphBuilder::RenderFile方法运行后,DirectShow会只能创建一个FilterGraph图吗?我研究了SDK的示例的代码并没有发现那里有选择Filter进行手动连接的地方,所以这里很疑惑,请高手指点一下,最好能带点示例代码附加指点。谢谢了!

------解决方案--------------------------------------------------------
如果系统中有相应注册的FILTER,RenderFile就会创建一个FilterGraph图,如果没有就会失败。
选择Filter进行手动连接,需要现创建fitler实例,软和取得PIN借口,在使用Connect函数和两外一个filter的PIN连接,这样一步一步构成一个FilterGraph
------解决方案--------------------------------------------------------
如果只需要播放单个媒体文件,可以使用IGraphBuilder::RenderFile方法渲染媒体文件。
如果针对应用需要,使用特定的Source Filter后,可以使用IGraphBuilder::Render方法实现对GraphBuilder中输出Pin进行渲染。
如果需要对渲染流程进行高级控的话,那就需要手动添加Filter并进行手动连接。
注意要实现播放,一个GraphBuilder中到少要有一个Source filter和一个Renderer。

下面是具体方法简单介绍:
1、创建GraphBuilder和Filter
IGraphBuilder *pBuilter;
IBaseFilter *pFilter;
hr = CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
IID_IGraphBuilder, (void **)&m_pGraph );
hr = CoCreateInstance( IID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, 
IID_IBaseFilter, (void **)&pFilter );
2、将Filter添加到GraphBuilder
pBuilder->AddFilter(pFilter);
3、取得两个Filter的输入输出Pin
HRESULT GetUnconnectedPin( IBaseFilter *pFilter, // Pointer to the filter.
PIN_DIRECTION PinDir, // Direction of the pin to find.
IPin **ppPin ) // Receives a pointer to the pin.
{
*ppPin = 0;

IPin *pPin = 0;
IEnumPins *pEnum = 0;
HRESULT hr = pFilter->EnumPins(&pEnum);
if (FAILED(hr))
{
return hr;
}
hr = pEnum->Reset();
while ( ( hr = pEnum->Next(1, &pPin, NULL) ) == S_OK)
{
PIN_DIRECTION ThisPinDir;
pPin->QueryDirection(&ThisPinDir);
if (ThisPinDir == PinDir)
{
IPin *pTmp = 0;
hr = pPin->ConnectedTo(&pTmp);
if (SUCCEEDED(hr)) // Already connected, not the pin we want.
{
pTmp->Release();
}
else // Unconnected, this is the pin we want.
{
pEnum->Release();
*ppPin = pPin;
return S_OK;
}
}
pPin->Release();
}
pEnum->Release();
// Did not find a matching pin.
return E_FAIL;
}
4、连接两个Filter
pBuilder->Connect(ppinIn, ppinOut);
------解决方案--------------------------------------------------------
简单的文件播放RenderFile就可以了。
如果需要在GRAPH链路中使用特定的FILTER,需要手动链接。
------解决方案--------------------------------------------------------
探讨
请问,如果我要在IGraphBuilder:Connect方法连接图中的两个Filter,我如何在SplitterFilter后面连接视频Filter或音频Filter呢,我枚举出来SplitterFilter两个Pin,如何确定哪一个是音频Pin哪一个是视频Pin呢?

------解决方案--------------------------------------------------------
参考http://topic.csdn.net/u/20081128/16/12bf6796-28b7-4eaa-9521-9b7050d8f79a
------解决方案--------------------------------------------------------
枚举到PIN的major type即可。
------解决方案--------------------------------------------------------
根据文件格式不同,需要用不同的SourceFilter,常用的格式可以用CLSID_AsyncReader或CLSID_WMAsfReader打开,特殊格式情况就比较复杂。
添加SourceFilter后,还需要用以下代码打开文件:
IFileSourceFilter *pFileSource = NULL;
hr = m_pSource->QueryInterface( IID_IFileSourceFilter, (void**)&pFileSource );
hr = pFileSource->Load(FileName, NULL);
打开文件后,直接将SourceFilter与你需要的RenderFilter连接就可以播放文件了。
  相关解决方案