微软做了很多的接口以便和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应用程序的开发通常遵循的步骤为:
2)通过调用QueryInterface ( )函数来获取Filter Graph 和IMediaEvent组件的指针;
3)对Filter Graph进行控制和对事件作出响应。
例如:首先生成一个名为MediaPlay的单文档应用程序,定义一个名字为MediaPlay的函数,该函数的具体实现代码为:
{
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 视频渲染器被销毁,或者从过滤器图中移除.