DirectShow之流媒体API编程

来源:互联网 发布:tango聊天软件下载 编辑:程序博客网 时间:2024/06/05 09:53

微软做了很多的接口以便和directx兄弟能配合编程,我们再ildasm下面可以看到,只有一个名为FilgraphManagerClass的class,其实仔细看了一下,也没有多少大的函数,DirectX在抽象上分了4层,

  硬件/网络层:放置有多媒体设备,包括图形加速器、声卡、输入设备以及网络通信设备等; 

  DirectX基础层:为图像、声音和设备提供多媒体基本服务; 

  DirectX媒体层: 为动画制作、音频和视频等提供API功能; 

  组件层:包括ActiveX控制和应用,它利用DirectX的API功能的优势为用户提供多媒体服务。

   DirectShow 就是建立在DirectX媒体层之上的技术,其前身是ActiveMovie2.0。它以 一组API函数或ActiveX控件出现,用途是让开发者能够在网络上传递高质量的音频和视频信号。值得一提的是,DirectShow为我们提供了一个 开放式的开发环境,我们可以根据自己的需要定制组件。

   DirectShow 定义了如何利用标准组件来处理流媒体数据,这些组件称为过滤器。过滤器带有输入、输出针角 (pin),或二者兼而有之。在DirectShow技术中处于最核心位置的就是作为"过滤器"的可插入标准组件,它是执行特定任务的COM对象。过滤器 又可被细分为源过滤器(Source filter)、变换过滤器(Transform filter)、表现过滤器(Renderer filter) 等。过滤器通过向文件读写、修改数据和显示数据到输出设备上来操作流媒体。过滤器的针脚通过协商来决定它们将支持何种形式多媒体。由于 DirectShow支持可重构的过滤器图表结构,所以使用相同的软件组件可以播放多种类型的媒体,开发人员可以通过定义自己的过滤器来扩展 DirectShow对媒体的支持功能。

  源过滤器用来从数据源获取数据,并将数据传送到过滤器图表中,这里的数据源可以是摄像机、因特网、磁盘文件等;

  转换过滤器用来获取、处理和传送媒体数据,它包括分离视频和音频的分解变换过滤器(Splitter transform filter)、解压视频 数据的视频转换过滤器(Video transform filter)、解压音频数据的音频转换过滤器 (Audio transform filter)

  表现过滤器用来在硬件上表现媒体数据,如显卡和声卡,或者是任何可以接受媒体数据的地方,如磁盘文件。它包括用来显示图像的视频表现过滤器 (Video renderer filter)、将音频数据送到声卡上去的音频表现过滤器(Audio renderer filter)。 

  简单的说,就是读取信息,利用一种“针”技术,转化变化,然后输出到硬件。

   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进行控制和对事件作出响应。

 

  例如:首先生成一个名为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()阻塞函数的运行,直到媒体文件结束后才可以释放对象、结束函数的运 行。  
  
附录:

  所有的事件通报码: 

   

EC_ACTIVATE 视频窗口被激活或者转为非激活状态
EC_BUFFERING_DATA 过滤图形包含缓冲数据
EC_CLOCK_CHANGED 参考时钟被改变
EC_CLOCK_UNSET 时钟提供者被断开
EC_COMPLETE 所有数据被渲染完毕
EC_DEVICE_LOST 一个即插即用设备被移除或者变为有效.
EC_DISPLAY_CHANGED 显示模式被改变
EC_END_OF_SEGMENT 到达段的末尾.
EC_ERROR_STILLPLAYING 一个异步命令失败
EC_ERRORABORT 一个操作被放弃
EC_EXTDEVICE_MODE_CHANGE 不支持
EC_FULLSCREEN_LOST 一个视频渲染窗口被切换出全屏模式.
EC_GRAPH_CHANGED 过滤器图被改变
EC_LENGTH_CHANGED 源的长度被改变.
EC_NEED_RESTART 过滤器请求过滤图重新开始.
EC_NOTIFY_WINDOW 通报一个视频渲染窗口的过滤器
EC_OLE_EVENT 过滤器传递一个字符串给应用程序。.
EC_OPENING_FILE 过滤图打开一个文件,或者已经完成了打开文件操作
EC_PALETTE_CHANGED 视频调色板被改变.
EC_PAUSED 一个暂停请求被处理.
EC_QUALITY_CHANGE 过滤图为了质量控制丢桢
EC_REPAINT 一个视频渲染器要求重绘.
EC_SEGMENT_STARTED 一个新段开始
EC_SHUTTING_DOWN 过滤器图被关闭
EC_SNDDEV_IN_ERROR 一个音频设备的输入引脚错误.
EC_SNDDEV_OUT_ERROR 一个音频设备的输出引脚错误.
EC_STARVATION 过滤器没有得到足够的数据.
EC_STATE_CHANGE 过滤器图状态改变
EC_STEP_COMPLETE 一个过滤器执行了单桢渐进
EC_STREAM_CONTROL_STARTED 流控制开始命令产生效果.
EC_STREAM_CONTROL_STOPPED 一个流控制的停止命令产生效果
EC_STREAM_ERROR_STILLPLAYING 在流中产生了一个错误,但流还是在运行中.
EC_STREAM_ERROR_STOPPED 一个流因错误而停止
EC_TIMECODE_AVAILABLE 不支持
EC_USERABORT 用户中断回放.
EC_VIDEO_SIZE_CHANGED 本地视频尺寸改变.
EC_WINDOW_DESTROYED 视频渲染器被销毁,或者从过滤器图中移除.
原创粉丝点击