积极答复者
DXshow开发 怎么创建自己的filter Graph manager结构

问题
答案
-
你好:
“是不是在调用RenderFile函数的时候系统选择的Filter不正确?”
根据你的陈述“有的视频文件我直接用Renderfile方法,播放的时候视频不流畅,会花屏”,所以我觉得如果是选择的Filter不正确,产生的结果就不是有的视频文件播放不流畅花屏了。我建议你看下下面的这个链接里的内容:http://bbs.csdn.net/topics/350260945
如果只需要播放单个媒体文件,可以使用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的输入输出PinHRESULT 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);
请参照以上代码再次检查下你的代码。如果不是代码的问题的话,我建议你到一般性问题讨论区这个论坛提问。谢谢!
- 已编辑 Anna CcModerator 2014年2月13日 9:38 typo
- 已标记为答案 Anna CcModerator 2014年2月17日 8:52
-
- 已标记为答案 Anna CcModerator 2014年2月17日 8:52
全部回复
-
你好:
“是不是在调用RenderFile函数的时候系统选择的Filter不正确?”
根据你的陈述“有的视频文件我直接用Renderfile方法,播放的时候视频不流畅,会花屏”,所以我觉得如果是选择的Filter不正确,产生的结果就不是有的视频文件播放不流畅花屏了。我建议你看下下面的这个链接里的内容:http://bbs.csdn.net/topics/350260945
如果只需要播放单个媒体文件,可以使用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的输入输出PinHRESULT 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);
请参照以上代码再次检查下你的代码。如果不是代码的问题的话,我建议你到一般性问题讨论区这个论坛提问。谢谢!
- 已编辑 Anna CcModerator 2014年2月13日 9:38 typo
- 已标记为答案 Anna CcModerator 2014年2月17日 8:52
-
- 已标记为答案 Anna CcModerator 2014年2月17日 8:52
-
我查看了你给的链接和代码,收获不少。如你所说:要实现播放,一个GraphBuilder中到少要有一个Source filter和一个Renderer。但是我在向GraphBuilder中添加Source filter的时候遇到了问题:IGraphBuilde::AddFilter和AddSourceFilter的参数都是IbaseFilter类型的,不是IFileSourceFilter类型的啊。我尝试转换也转换不成功。
怎么才能把sourceFilter添加进IGraphBuilder?
如果是只能添加IBaseFilter类型的filter,那这个IBaseFilter怎么指定播放文件的路径?