来源:http://www.cnblogs.com/qiufa/archive/2006/12/19/596949.html
摘要:DirectShow技术是DirectX推出的建立在DirectDraw和DirectSound组件基础之上的多媒体应用程序开发工具包,它提供对多媒体数据流的高质量捕获和回放,代表着未来多媒体应用程序开发的方向。详细介绍了DirectShow的系统组成,并讨论了利用DirectShow在Visual C++ 6.0平台上开发简单媒体播放器的关键步骤。
关键字:DirectShow;COM;过滤器;引脚;过滤器图表管理器
DirectX简介
DirectX是Microsoft公司为游戏和其他高性能多媒体应用所提供的一套底层应用程序编程接口。这些接口包括对二维和三维图形,声效和音乐,输入设备以及多玩家网络游戏等的支持。目前DirectX的最高版本是DirectX 9.0。
1 DirectX的组成
DirectX 9.0由下列组件构成:
(1)DirectX Graphics:该组件组合DirectX旧版本中的DirectDraw和Direct3D两个组件,使其成为一个适用于所有图形程序的单独的应用程序接口。其中的Direct3D扩展(D3DX)应用程序库简化了多数图形程序的工作。
(2)DirectInput:支持各种输入设备,完全支持力反馈技术。
(3)DirectPlay:支持多玩家网络游戏。
(4)DirectSound:支持用于播放和捕获音频波形的高性能音频应用软件的开发。
(5)DirectMusic:为音乐音轨以及基于波表、MIDI(Musical Instrument Devices Interface)或其他由DirectMusic Producer创作的非音乐音轨,提供了一套完整的解决方案。
(6)DirectShow:提供对多媒体数据流的高质量捕获和回放。
(7)DirectSetup:一个简单的应用程序接口,提供DirectX组件的自动安装。
(8)DirectX Media Objects:提供对数据流对象的读写支持,包括视频和音频的编解码器及其效果。
2 COM简介
DirectX的功能都是以COM组件的形式提供的。COM是组件对象模型(Component Object Model)的简写,它是一种协议,是对象连接和嵌入(Object Linking and Embedding)的基础。COM通常以动态链接库(DLL)的形式存在,它是建立在二进制规范上的对象。COM定义并实现了软部件(如应用程序、数据对象、控件及服务)机制,并把他们统称为“对象”。每个软部件对象由数据以及访问数据的函数组成,访问软部件对象数据的函数集合称为“接口”。在应用程序看来COM是一个黑箱,可调用COM提供的方法但不知道它的具体实现。在使用DirectShow编程时,用户创建的自定义组件必须以COM形式实现,所以必须知道如何实现COM,而一般的应用程序只需要了解COM的接口和用法就可以了。
DirectShow的系统组成
DirectShow技术是建立在DirectDraw和DirectSound组件基础之上的,它通过DirectDraw对显卡进行控制以显示视频,通过DirectSound对声卡进行控制以播放声音。 DirectShow可提供高质量的多媒体流的捕获和回放功能;支持多种媒体格式,包括ASF(Advanced Systems Format),MPEG(Motion Picture Experts Group),AVI(Audio-Video Interleaved),MP3(MPEG Audio Layer-3)和WAV声音文件;可以从硬件上捕获媒体数据流;可以自动检测并使用视频和音频加速硬件。因此,DirectShow可以充分发挥媒体的性能,提高运行速度,可以简化媒体播放、媒体间的格式转换和媒体捕获等工作。同时,它还具有极大的可扩展性和灵活性,可以由用户自己创建组件,并将这个组件加入DirectShow结构中以支持新的格式或特殊的效果。
应用程序与DirectShow组件以及DirectShow所支持的软硬件之间的关系如图1所示。
![]() 图1 DirectShow系统框图 |
![]() 图2 过滤器和引脚连接示意图 |
3、媒体类型(Media Type)
媒体类型是描述数字媒体格式的一种通用的可扩展方式。两个过滤器相连时,必须使用一致的媒体类型,否则这两个过滤器就不能相连。媒体类型能识别上一级过滤器传送给下一级过滤器的数据类型,并对数据进行分类。
实际在很多应用程序中,用户根本不需要担心媒体类型的问题,DirectShow会处理好所有的细节。但有些应用程序需要对媒体类型进行操作。媒体类型一般可以有两种表示:AM_MEDIA_TYPE和CMediaType。前者是一个结构,后者是从这个结构继承过来的类。
每个AM_MEDIA_TYPE由三部分组成:Major type、Subtype和Format type。这三个部分都使用GUID(全局唯一标识符)来唯一标示。Major type主要定性描述一种媒体类型,这种媒体类型可以是视频、音频、比特数据流或MIDI数据等等;Subtype进一步细化媒体类型,如果是视频的话可以进一步指定是RGB-24,还是RGB-32,或是UYVY等等;Format type则用一个结构更进一步细化媒体类型。
如果媒体类型的三个部分都指定了某个具体的GUID值,则称这个媒体类型是完全指定的;如果媒体类型的三个部分中有任何一个值是GUID_NULL,则称这个媒体类型是不完全指定的。GUID_NULL具有通配符的作用。
4、过滤器图表管理器(Filter Graph Manager)
DirectShow通过过滤器图表管理器来控制过滤器图表中的过滤器。过滤器图表管理器是COM 形式的,它的功能有:协调过滤器间的状态转变;建立参考时钟;把事件(event)传送给应用程序;为应用程序提供建立过滤器图表的方法。
一些常用的过滤器图表管理器接口如下:
IGraphBuilder:为应用程序提供创建过滤器图表的方法。
IMediaControl:提供控制过滤器图表中多媒体数据流的方法,包括运行、暂停和停止。
IMediaEventEx:继承自IMediaEvent接口,处理过滤器图表的事件。
IVideoWindow:用于设置多媒体播放器窗口的属性,应用程序可以用它来设置窗口的所有者、位置和尺寸等属性。
IBasicAudio:用于控制音频流的音量和平衡。
IBasicVideo:用于设置视频特性,如视频显示的目的区域和源区域。
IMediaSeeking:提供搜索数据流位置和设置播放速率的方法。
IMediaPosition:用于寻找数据流的位置。
IVideoFrameStep:用于步进播放视频流,可使DirectShow应用程序,包括DVD播放器一次只播放一帧视频。
5、过滤器图表中的数据流动
当用户要创建自定义的过滤器时,就需要了解媒体数据是如何在过滤器图表中传输的。为了在过滤器图表中传送媒体数据,DirectShow过滤器需要支持一些协议,称之为传输协议(transport)。相连的过滤器必须支持同样的传输协议,否则不能交换媒体数据。
大多数的DirectShow过滤器把媒体数据保存在主存储器中,并通过引脚把数据提交给其它的过滤器,这种传输称为局部存储器传输(local memory transport)。虽然局部存储器传输在DirectShow中最常用,但并不是所有的过滤器都使用它。例如,有些过滤器通过硬件传送媒体数据,引脚只是用来提交控制信息,如IOverlay接口。
DirectShow为局部存储器传输定义了两种机制:推模式(push model)和拉模式(pull model)。在推模式中,源过滤器生成数据并提交给下一级过滤器。下一级过滤器被动的接收数据,完成处理后再传送给再下一级过滤器。在拉模式中,源过滤器与一个分析过滤器相连。分析过滤器向源过滤器请求数据后,源过滤器才传送数据以响应请求。推模式使用的是IMemInputPin接口,拉模式使用IAsyncReader接口,推模式比拉模式要更常用。
本节介绍基于DirectShow开发简单媒体播放器的关键步骤。
1、初始化DirectShow
由于DirectShow的组件都是以COM形式存在的,因此首先要调用CoInitializeEx函数来初始化COM库,嵌入所有的动态链接库和资源。否则,所有对QueryInterface的调用都会失败。
2、创建过滤器图表管理器接口
首先申明并初始化所需的接口:
| // DirectShow interfaces IGraphBuilder *pGB = NULL; IMediaControl *pMC = NULL; IMediaEventEx *pME = NULL; IVideoWindow *pVW = NULL; IBasicAudio *pBA = NULL; IBasicVideo *pBV = NULL; IMediaSeeking *pMS = NULL; IMediaPosition *pMP = NULL; IVideoFrameStep *pFS = NULL; 然后实例化一个过滤器图表管理器,并查询各接口: // Get the interface for DirectShow's GraphBuilder CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGB); // QueryInterface for DirectShow interfaces pGB->QueryInterface(IID_IMediaControl, (void **)&pMC); pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME); pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS); pGB->QueryInterface(IID_IMediaPosition, (void **)&pMP); // Query for video interfaces, which may not be relevant for audio files pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW); pGB->QueryInterface(IID_IBasicVideo, (void **)&pBV); // Query for audio interfaces, which may not be relevant for video-only files pGB->QueryInterface(IID_IBasicAudio, (void **)&pBA); |
| // Have the graph builder construct its the appropriate graph automatically pGB->RenderFile(wFile, NULL); |
| // Run the graph to play the media file pMC->Run(); |
发表于 @ 2007年05月12日 23:17:00 | 评论( loading... ) | 举报| 收藏