首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Windows Mobile >

怎么在Pocket PC 2005上通过DirectShow直接播放mp3

2012-02-14 
如何在Pocket PC 2005上通过DirectShow直接播放mp3?我这里所说的“直接播放”是指不借助任何其它应用程序(比

如何在Pocket PC 2005上通过DirectShow直接播放mp3?
我这里所说的“直接播放”是指不借助任何其它应用程序(比如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;


if(SUCCEEDED(pFilter-> QueryInterface(IID_IFileSourceFilter,reinterpret_cast <VOID **> (&pFileSource))))
{
hr = pFileSource-> Load( _T( "\\1.mp3 "), NULL );
IEnumPins* pTest = NULL;
IPin* pPin = NULL;
ULONG ulCount = 0;
if(S_OK == (hr = pGraphBuilder-> AddFilter(pFilter,_T( "MP3 "))))
{
if(S_OK == (hr = pFilter-> EnumPins(&pTest)))
{
if(S_OK == (hr = pTest-> Next(1,&pPin,&ulCount)))
{
hr= pGraphBuilder-> Render(pPin);
pPin-> Release();
hr= S_OK;
}
pTest-> Release();
}
}
if( pFileSource )
pFileSource-> Release();
}
if( pFilter )
pFilter-> Release();
}

只随便连了一个pin,如果有多个的话,都要render
[解决办法]
我也碰到了这个问题,我不知道CLSID_AudioRender这个是不是可以直接当成是Rendering filter,我用这个方式进行的时候,也是提示两个filter不能直接连接,还需要一个中间filter。另外,对于CLSID_MPEG1Splitter在platform build里面是有这个的,不知道怎么使用?大家可以一起交流哦!我的MSN:kongpengsh@hotmail.com

热点排行