基于DirectShow的流媒体解码和回放(2)
来源:互联网 发布:中文版vk软件下载 编辑:程序博客网 时间:2024/05/03 11:57
四、DirectShow程序开发
DirectShow建立在COM组件技术基础上,所以开发DirectShow程序必须要掌握COM组件技术。DirectShow与COM紧密相连,它所有的部件和功能都由COM接口来构造和实现,其开发方式相当灵活,没有固定的模式,通常随不同的需要使用不同的COM接口。但是其中几个重要的接口确实经常需要用到的:IGraphBuilder接口,这是最为重用的COM接口,用来创建Filter Graph Manager;IMediaControl接口,用来控制流媒体在滤波器图表(Filter Graph)中的流动,例如流媒体的启动和停止;IMediaEvent接口,该接口在Filter Graph发生一些事件时用来创建事件的标志信息并传送给应用程序。
一个典型的DirectShow应用程序的开发通常遵循的步骤为:
1)通过API函数CoCreateInstance()创建一个Filter Graph Manager 实例;
2)通过调用QueryInterface ( )函数来获取Filter Graph 和IMediaEvent组件的指针;
3)对Filter Graph进行控制和对事件作出响应。
下面举一个简单的例子来说明如何利用DirectShow技术对多媒体流进行解码回放的。首先生成一个名为MediaPlay的单文档应用程序,定义一个名字为MediaPlay的函数,该函数的具体实现代码为:
void PlayMovie(LPTSTR lpszMovie)
{
IMediaControl *pMC = NULL;
IGraphBuilder *pGB = NULL;
IMediaEventEx *pME = NULL;
long evCode; // something to hold a returned event code
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IMediaControl, (void **)&pMC);
hr = pMC->QueryInterface(IID_IGraphBuilder, (void **)&pGB);
hr = pMC->QueryInterface(IID_IMediaEventEx, (void **)&pME);
hr = pGB->RenderFile(lpszMovie, NULL);
hr = pMC->Run();
hr = pME->WaitForCompletion(INFINITE, &evCode);
if(pMC)pMC->Release();
if(pGB)pGB->Release();
if(pME)pME->Release();
}
上述代码中,CoCreateInstance()函数创建了一个过滤器图表(Filter Graph)对象,并返回一个媒体控制(ImediaControl)接口,这个接口通过过滤器来实现播放、暂停、停止等媒体放映功能,但是这时候图表对象并不包含具体的过滤器,因为此时DirectX并不清楚需要播放何种类型的媒体;接下来创建一个图表构建接口,该接口可以实现创建过滤器图表、向图表对象添加、删除各种过滤器、列举当前过滤器图表中所有的过滤器、连接图表对象中的各个过滤器等功能;本例中使用了IGraphBuilder 接口的RenderFile()函数,告诉DirectX需要播放的媒体文件名,此时IgraphBuilder对象接口根据多媒体文件的类型,自动向过滤器图表添加播放该类型媒体所需的的各种过滤器,并实现其连接。
最后,函数调用ImediaControl接口对象的Run()函数,就可以开始播放媒体文件了。为了实现从头至尾的顺序播放完多媒体文件,需要调用IMediaEventEx 对象接口的WaitForCompletion()阻塞函数的运行,直到媒体文件结束后才可以释放对象、结束函数的运行。
DirectShow建立在COM组件技术基础上,所以开发DirectShow程序必须要掌握COM组件技术。DirectShow与COM紧密相连,它所有的部件和功能都由COM接口来构造和实现,其开发方式相当灵活,没有固定的模式,通常随不同的需要使用不同的COM接口。但是其中几个重要的接口确实经常需要用到的:IGraphBuilder接口,这是最为重用的COM接口,用来创建Filter Graph Manager;IMediaControl接口,用来控制流媒体在滤波器图表(Filter Graph)中的流动,例如流媒体的启动和停止;IMediaEvent接口,该接口在Filter Graph发生一些事件时用来创建事件的标志信息并传送给应用程序。
一个典型的DirectShow应用程序的开发通常遵循的步骤为:
1)通过API函数CoCreateInstance()创建一个Filter Graph Manager 实例;
2)通过调用QueryInterface ( )函数来获取Filter Graph 和IMediaEvent组件的指针;
3)对Filter Graph进行控制和对事件作出响应。
下面举一个简单的例子来说明如何利用DirectShow技术对多媒体流进行解码回放的。首先生成一个名为MediaPlay的单文档应用程序,定义一个名字为MediaPlay的函数,该函数的具体实现代码为:
void PlayMovie(LPTSTR lpszMovie)
{
IMediaControl *pMC = NULL;
IGraphBuilder *pGB = NULL;
IMediaEventEx *pME = NULL;
long evCode; // something to hold a returned event code
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IMediaControl, (void **)&pMC);
hr = pMC->QueryInterface(IID_IGraphBuilder, (void **)&pGB);
hr = pMC->QueryInterface(IID_IMediaEventEx, (void **)&pME);
hr = pGB->RenderFile(lpszMovie, NULL);
hr = pMC->Run();
hr = pME->WaitForCompletion(INFINITE, &evCode);
if(pMC)pMC->Release();
if(pGB)pGB->Release();
if(pME)pME->Release();
}
上述代码中,CoCreateInstance()函数创建了一个过滤器图表(Filter Graph)对象,并返回一个媒体控制(ImediaControl)接口,这个接口通过过滤器来实现播放、暂停、停止等媒体放映功能,但是这时候图表对象并不包含具体的过滤器,因为此时DirectX并不清楚需要播放何种类型的媒体;接下来创建一个图表构建接口,该接口可以实现创建过滤器图表、向图表对象添加、删除各种过滤器、列举当前过滤器图表中所有的过滤器、连接图表对象中的各个过滤器等功能;本例中使用了IGraphBuilder 接口的RenderFile()函数,告诉DirectX需要播放的媒体文件名,此时IgraphBuilder对象接口根据多媒体文件的类型,自动向过滤器图表添加播放该类型媒体所需的的各种过滤器,并实现其连接。
最后,函数调用ImediaControl接口对象的Run()函数,就可以开始播放媒体文件了。为了实现从头至尾的顺序播放完多媒体文件,需要调用IMediaEventEx 对象接口的WaitForCompletion()阻塞函数的运行,直到媒体文件结束后才可以释放对象、结束函数的运行。
- 基于DirectShow的流媒体解码和回放(2)
- 基于DirectShow的流媒体解码和回放
- 基于DirectShow的流媒体解码和回放
- 基于DirectShow的流媒体解码和回放
- 基于DirectShow的流媒体解码和回放
- 基于DirectShow的流媒体解码和回放
- 基于DirectShow的流媒体解码和回放
- 基于DirectShow的流媒体解码和回放
- 基于DirectShow的流媒体解码和回放
- 基于DirectShow的流媒体解码和回放
- 基于DirectShow的流媒体解码和回放
- 基于DirectShow的流媒体解码和回放(1)
- 基于DirectShow的流媒体解码和回放(转载)
- 基于DirectShow的流媒体解码和回放 (转载 作者 :刘 涛 ,天极网)
- DirectShow多媒体解码和回放
- Directshow的音频捕获和回放测试(2)
- 编写基于DirectShow流媒体播放器程序可以值得参考的资料和源码例子
- Directshow的音频捕获和回放测试1
- 我
- 今天写的ping 255个主机的程序
- js小结
- ASP中调用存储过程
- Eclipse Tips
- 基于DirectShow的流媒体解码和回放(2)
- 你的成功在于你每天养成的习惯
- 从优秀IT项目经理到千万富翁的距离只有1m——如何当好项目经理
- xp下净网先锋的清除 (http://www.dsdz.net/game/bbs/dispbbs.asp?boardid=10&id=702)
- 企业CIS设计
- 请问如何在扩展 DLL 中创建应用程序框架?如何在DLL中创建窗体(SDI/MDI)?非常急!!!!!!!
- 优秀得JAVA网站
- spring学习笔记(1)
- ACE笔记(2)-用ACE_Reactor实现类似计时器的装置