您的位置:首页 > 编程语言 > C语言/C++

DirectShow的中文资料之综述与配置篇

2004-07-09 10:19 232 查看
综述篇
DirectShow的出现,给windows下的多媒体编程提供了强大的支持.他提供了多媒体应用程序的最新技术和工具.为广大的程序员提供了一整套的应用程序接口API,使程序员能够设计高性能实时的应用程序。
最新的DirectMedia SDK,提供于DirectX8.0中.其中DirectShow加入了许多新的特性.DirectShow就是原来的Microsoft ActiveMovie SDK.新的特性包括:音视频的捕捉和压缩,设备的列举,DVD的支持,设备的控制和多媒体流格式等的支持.
Microsoft DirectShow SDK 提供从本地文件和Internet上回放和捕捉媒体流的能力。他支持的文件格式非常的多样,包括MPEG,Apple QuickTime,AVI,WAV,MIDI,Advanced Streaming Format (ASF), and Windows Media Audio (WMA).
再你开始之前,你需要的背景知识:
1.你应该熟悉C/C++或是VB.
2.另外让人头痛的是部件对象模型COM技术.下面我先简单的介绍一下COM的技术.
一、DirectX和部件对象模型COM
1.1、 部件对象模型COM(Component Object Model)
  DirectShow中的大部分API都由基于COM的对象和接口组成。COM是接口重利用的基于对象的系统的基础,是COM编程的核心模型,它也是一种接口规范。在操作系统级别上,它又是一个对象模型。 许多DirectShow API都创建为COM对象的实例。你可以将一个对象看做一个黑盒子,对象通过接口与对象通信,通过COM接口发送给对象或从对象接收的命令称为方法。例如
IVideoWindow->SetWindowPosition(grc.left, grc.top, grc.right, grc.bottom);
就是通过IVideoWindow的接口的方法设置显示窗口的位置.对象在运行时可以同其他对象捆绑在一起,并且能够使用这些对象的接口。如果你已知道某个对象是COM对象,并且知道该对象支持的接口,你的应用程序或其他对象就能够确定第一个对象所能执行的服务。所有COM对象都继承的一个方法是Query接口方法,它让你确定一个对象支持的接口和创建这些接口的指针。
1.2、IUnknown 接口
  所有的COM 接口都由一个称为Iunknown的接口衍生而来,该接口为DirectShow提供了对象生存期的控制和操作多接口发能力。Iunknown含有三个方法:
 .AddRef  当一个接口或另一个应用捆绑到一个对象上时,就使用AddRef方法将该对象的索引值加1。
 .QueryInterface   通过指向特定接口的指针查询对象所支持的特性。
 .Release    将对象的索引值减1,当索引值变为0时,该对象就从内存中释放。
  其中AddRef和Release方法负责维护对象的索引值。例如,如果创建一个IGraphBuilder 对象,该对象的索引值就被设定为1,每次当有一个函数返回该对象的指针时,该函数必须通过返回发指针调用AddRef方法将该对象的索引值加1。每一个AddRef的调用都必须有一个Release的调用与其对应。当对象的索引值达到0时,该对象就被撤消,该对象的所有接口都不可再用。
  QueryInterface方法测定一个对象是否支持指定的接口,如果支持,QueryInterface就返回指向该接口的指针。然后你可以使用该接口包含的方法同对象通信。如果QueryInterface成功地返回接口的指针,它会自动调用AddRef方法增加对象的索引值。在撤消接口指针之前必须调用Release来减少对象的索引值。
1.3、 DirectShow COM 接口
  DirectShow中的接口是用相当基本的COM编程创建的。对象的每个接口都由IUnknown COM接口派生而来,如IGraphBuilder 、IMediaControl 和IMediaEventEx 都是这样。基本对象的创建工作由动态链接库DLL中的特殊函数来处理。当然还有很多的其他接口,会在以后一一说明。
1.4、 C++和COM 接口
  对C++程序员来说,COM接口就象一个抽象的基类。在C++的基类中,所有的方法都定义为纯虚的,这就意味着没有任何代码同方法关联在一起。纯虚的C++函数和COM接口都使用一种称为虚表(vtable)的设备。一个虚表包含了应用于所给接口的所有函数的声明。如果你想让程序或对象使用这些函数,可以先用QueryInterface方法检查对象存在的接口,获取该接口的指针,调QueryInterface后,应用或对象实际上就从对象中接收到了虚表的指针,通过该指针就可以调用应用于该对象的所有接口方法。
  COM对象和C++的另一个相似之处是方法的第一个参数就是接口或类的名字,C++中称为this参数。因为COM对象和C++对象是完全二进兼容的,编译器就将COM接口同C++抽象类同样处理,并且具有相同的语法,这会使得代码简单一些。
DirectShow基础指南
一.体系结构
   DirectShow的体系结构定义了如何用叫做Filters的控制和处理多媒体数据流。Filters(过滤器)有输入或输出Pins(实在是不好翻译...腿?脚?),或者俩者都有。用一个教Filter Graph的把他们互相连接。应用程序用Filter Graph Manager去装配和移动数据。缺省的,filter graph manager自动为你处理数据的流程。例如,自动插入适当的codec, 自动连接传输filter的输出pin到缺省的渲染filter。如果你不想要缺省的,你可以指定你自己的filter。
  Filter graph manager 提供了COM接口,这样应用程序就能访问filter graph了。应用程序能直接调用filter graph manager的接口去控制媒体流或是返回filter事件,他们也能用ActiveMovie控件去回放媒体文件。
因此,你可以通过COM访问DirectShow,ActiveMovie控件,或是media control interfaces(MCI),如下图:
 
二.下面详细介绍一下Filter Graph Manager and Filter Graphs
A.一个Filter Graphs由很多不同类型的filter组成。大部分的filter可以归为三个类:
1.source filter(源过滤器),获得数据的地方,例如从硬盘,因特网服务器,或是VCR(录像机),把他们引入filter graph。
2.transform filter(传输过滤器),得到数据并处理他,然后向前传递。
3.rendering filter(渲染过滤器),渲染数据;通常是一个设备,能够渲染本地的和接受的媒体输入(象内存或是硬盘文件)。
另外,除了这三种,还有其他的过滤器,举个例子,effect filter,他不改变数据的类型,只是处理他,还有parser filter(解析过滤器),他能够理解源数据的格式,知道如何正确的读数据,执行seek等。
例如,一个filter graph想要回放一个MPEG的视频文件,就要用到下面的filter。
1.source filter,从磁盘读数据。
2.MPEG filter,解析数据流,并且分离出MPEG音视频数据流。
3.transform filter,解压视频数据。
4.transform filter,解压音频数据。
5.video renderer filter,显示视频数据到屏幕中。
6.audio renderer filter,把音频数据送达声卡。

要想一个filter graph工作,filter必须要正确的顺序连接,并且数据流也要以正确的顺序开始和结束。filter graph manager就是起这作用的。他负责连接filter并控制媒体流。他也能为一个特别的媒体文件配置filter去渲染他,并建立filter graph。filter graph也可以重新配置通过filter graph manager。
当配置时,filter graph manager使用filter mapper,首先读注册信息,决定有用的过滤器数据类型。然后企图连接过滤器,直到找到了render 过滤器。每一个过滤器都有一个注册变量。
filter graph manager允许应用程序或ActiveX控件控制媒体流的开始,暂停,停止,和播放特定的时间段,指定特定的播放位置。通过调用适当的过滤器方法。也允许过滤器传递事件给应用程序。因此,一个应用程序能收到一个特别的过滤器的状态信息等。
三.Filters and Pins
在流体系当中,有两个基本的组件,filter和pin。filter是一个COM对象,他至少有一个pin。pin也是COM对象。他通过filter建立。他是各个filter的连接点。
如下图:
 
输入pin接受数据到filter中。输出pin提供数据到其他的filter中。通常的传输过滤器,象压缩,解压(codec)过滤器,提供了一个输入,一个输出pin。
一个过滤器有IBaseFilter接口。这个接口提供的方法允许列举在他上的pin和返回过滤器的信息。
也提供从IMediaFilter继承的方法:这些方法允许控制状态(运行,暂停,停止)和同步。另外,filter可以有其他的几个接口,这依赖他支持的媒体类型。
pin有责任提供接口连接其他的pin并传输数据。pin的接口支持:
1.使用共享内存或别的资源传输数据。
2.在每个pin-to-pin的连接中,商议数据的具体格式。
3.缓冲管理和缓冲分配,达到最小的数据拷贝,最大的数据吞吐量。
pin的接口也有一些细微的差别,分为输入和输出pin。
输出pin通常有下面一些接口:
1.IPin方法的调用运行查询pin,连接,和数据类型信息,当filter graph停止的时候,还可以发送通知给下游。
2.IMediaSeeking 允许传播关于流的开始时间,停止时间等信息给renderer。然后,把媒体位置信息传给上游的过滤器(一般是源过滤器)。
3.IQualityControl 传送quality-control消息给上游。
输入pin通常有下面一些接口:
1.IPin 允许pin连接输出pin,和提供信息给输出pin。
2.IMemInputPin 提供共享内存缓冲传输数据。

配置篇
VC的环境设置
在进行任何DirectShow有关的编程之前,你得先设置VC的环境变量值.主要是方便以后的项目设计.
1. 选择Options.
2. 选择Directories Tab.
3. 在Show directories for框中选择include files
4. 在Directories框中选择一项新项,键入X:/DX90SDK/Include 和 X:/DX90SDK/SAMPLES/C++/DIRECTSHOW/BASECLASSES,此目录将含有所有有关的头文件。
5. 在Show directories for框中选择Library files
6. 在Directories框中选择一项新项,键入X:/DX90SDK/Lib,此目录将含有所有有关的库文件。
7. 选择OK
建立GUID
如果你建立自己的filter(过滤器),你需要建立一个GUID。
你可以:
选择工具菜单,选择Create GUID,GUID默认的是DEFINE_GUID,把得到数据的粘贴到你的头文件中。
如果你的工具菜单中没有,你可以用你的VC目录下的/Common/Tools下的GUIDGEN.EXE。
例如:
// {3FA5D260-AF2F-11d0-AE9C-00A0C91F0841}
 DEFINE_GUID(CLSID_MyFilter,
 0x3fa5d260, 0xaf2f, 0x11d0, 0xae, 0x9c, 0x0, 0xa0, 0xc9, 0x1f, 0x8, 0x41);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息