我这里所说的“直接播放”是指不借助任何其它应用程序(比如Windows Media Player)或第三方插件,而直接利用PPC2005内置的解码器和Filter进行播放。
首先我在PC上(Windows2000系统)做实验,通过RenderFile接口,比如:
pGraphBuilder-> RenderFile(L "c:\\1.mp3 ", NULL);
可以正常播放。然后枚举该Graph中的所有Filter,发现系统自动帮我加载了3个Filter:
第1个是MPEG1 Stream Splitter;
第2个是MPEG1 Layer-3 Decoder;(我不知道这个mp3解码器是系统内置的还是由于我装了mp3播放器)
第3个是Default DirectSound;
或者通过Render接口半自动构建Graph,比如:
IBaseFilter *pSourceFilter;
pGraphBuilder-> AddSourceFilter(L "c:\\1.mp3 ", L "Source Filter ", &pSourceFilter);
通过枚举pSourceFilter的Pin,得到它的输出Pin--> poutPin;
然后通过查看注册表中MPEG1 Layer-3 Decoder对应的GUID,自己创建mp3解码器的Filter,并加入Graph中,再Render SourceFilter的输出Pin:
pGraphBuilder-> Render(poutPin);
也可以正常播放。然后枚举该Graph中的所有Filter,发现除了上面提到的3个Filter,又多了一个我加入的Source Filter。
由此我假定在PC上通过DirectShow播放mp3,除了SourceFilter和解码器以外,另外2个Filter也是必须的。
回到PPC2005。首先RenderFile不行,我不知道其确切的原因。因为在PPC2005上mp3解码器是以DMO方式提供的,或许系统无法帮我创建这个IDMOWrapperFilter。这样我就只能自己构建Graph了:
首先还是加入Source Filter:
IBaseFilter *pSourceFilter;
pGraphBuilder-> AddSourceFilter(L "\\1.mp3 ", L "Source Filter ", &pSourceFilter);
通过枚举pSourceFilter的Pin,得到它的输出Pin--> poutPin;
然后创建mp3解码器的DMO Filter,并把它加进Graph:
IBaseFilter *pFilter;
CoCreateInstance(CLSID_DMOWrapperFilter, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void **)&pFilter);
IDMOWrapperFilter *pWrap;
pFilter-> QueryInterface(IID_IDMOWrapperFilter, (void **)&pWrap);
DEFINE_GUID(CLSID_MP3DECODERDMO, 0x6b928210, 0x84e7, 0x4930, 0x9b, 0x33, 0x1e, 0xb6, 0xf0, 0x2b, 0x52, 0x6e);
pWrap-> Init(CLSID_MP3DECODERDMO, DMOCATEGORY_AUDIO_DECODER); // CLSID_MP3DECODERDMO的GUID值是在注册表中找到的
pGraphBuilder-> AddFilter(pFilter, L "My MPEG-1 Layer 3 Decoder DMO ");
最后调用pGraphBuilder-> Render(poutPin);
得到的返回值是VFW_E_CANNOT_CONNECT,也就是缺少中间的Filter,无法连接。
我查了一下,在前面Windows2000上系统自动帮我加载的那2个Filter:MPEG1 Splitter和Default DirectSound,在PPC2005上都没有实现甚至没有注册,尽管在WM500自带的uuids.h中能找到这两个Filter的GUID定义:
OUR_GUID_ENTRY(CLSID_MPEG1Splitter,
0x336475d0, 0x942a, 0x11ce, 0xa8, 0x70, 0x00, 0xaa, 0x00, 0x2f, 0xea, 0xb5)
OUR_GUID_ENTRY(CLSID_DSoundRender,
0x79376820, 0x07D0, 0x11CF, 0xA2, 0x4D, 0x0, 0x20, 0xAF, 0xD7, 0x97, 0x67)
所以我想请教的是:在PPC2005上除了Source Filter和mp3解码器的DMO Filter外,还有哪些中间Filter需要加入到Graph?或者不再需要额外的Filter了,只需要一些特殊处理就可以了?
对于能够帮忙彻底解决问题的朋友,将另外开贴再额外送上500分!!!
------解决方案--------------------
我想关键应该是SourceFilter和mp3 decoder DMO之间需要什么样的Filter或者其它特殊处理。继续等待高手。
------------------------------------------------
你上边说过还有一个MPEG1 Stream Splitter的,据我的理解,这是个文件流转换成媒体流的转换器,也就是一个解释媒体文件的FILTER,如果系统没有提供的自己找个开源的库封装一个FILTER不行吗?不过如果你真的用其它开源库来做的话用DIRECT SHOW 的意义也就不大了。架构会变得更清晰、更简单。有一个开源的功能强大的播放器TCPMP,你DOWN来看看。
------解决方案--------------------
首先找到MPEG1 Layer-3 Decoder的CLSID,这里我假定已经找到,称为CLSID_MP3Filter.
IBaseFilter* pFilter = NULL;
hr = CoCreateInstance( CLSID_MP3Filter,
NULL,
CLSCTX_INPROC,
IID_IBaseFilter,
reinterpret_cast <VOID **> (&pFilter)
);
if(SUCCEEDED(hr))
{
IFileSourceFilter* pFileSource = NULL;