该文用于介绍 DirectShow 的主要组件。这些组件可用于开发 DirectShow 应用程序或者用于开发自己的过滤器组件。
关于 DirectShow 过滤器(Filters)
DirectShow 使用一个标准的体系结构,它的每个处理进程都是由一个 COM 对象来完成。这个 COM 对象就叫 过滤器 (Filters) 。 DirectShow 提供了一套标准的过滤器用于应用程序使用,并且开发人员可以写自己的过滤器开扩展 DirectShow 功能。为了示例,这里列举了播放一个 AVI 文件需要的步骤以及所需的过滤器:
- 从文件读取原始数据。 (File Source filter)
- 检查 AVI 头,并把数据流解析为音频流和视频流 (AVI Splitter filter)
- 对视频解码 ( 多个解码过滤器 , 依赖与压缩格式 ).
- 显示视频图像 (Video Renderer filter)
- 发送音频数据到声卡 (Default DirectSound Device filter).
下图显示了这些过滤器:
就像图中显示一样,每个过滤器都被链接到一个或多个其他过滤器上。过滤器间的链接也是 COM 对象,被称为针脚 (pins) 。过滤器使用针脚把数据从一个过滤器移动到另一个过滤器。图中箭头显示了数据流动的方向。在 DirectShow 中,这些整个一套过滤器,就称作过滤器图表。
过滤器有三个可能的状态:运行,停止,和暂停。当一个过滤器在运行的时候,它就处理数据。当它停止的时候,它就停止数据处理。暂停状态用于暂停。过滤器图表中所有过滤器的状态都是同步的。因此,整个过滤器图表的状态也被看作是运行,停止,或暂停。
过滤器可以被分为如下几类:
- 源 ( source ) 过滤器。用于把数据引入图表。数据可能来源于一个文件,网络,照相机 … 每个源过滤器处理不同类型的数据源。
- 转换( transform )过滤器,该过滤器对输入数据进行处理,然后创建一个输出数据流。
- 输出( Renderer )过滤器,该过滤器位于整个过滤器链接的最后。它接收输入数据并把数据输出给最终用户。
- 分离( splitter )过滤器,该过滤器将把一个输入数据流分离为两个或多个数据流。
- 混合( mux )过滤器,该过滤器将把多个输入数量流混合成一个单一的数据流。
上面的分类也不是绝对的,比如,一个 ASF Reader 过滤器可以看作是一个源过滤器,又可以当作一个分离过滤器。
所有过滤器都使用 IBaseFilter 接口,所有的针脚都使用 IPin 接口。
关于过滤器图表管理器 (Filter Graph Manager)
过滤器图表其实就是一个 COM 对象,它用于控制过滤器图表中的过滤器。它可以实现功能如下:
状态设置
过滤器的状态改变必须通过一个特殊的命令来触发。所以,应用程序不能直接发送状态改变命令给过滤器。应用程序把要发送的命令发送给过滤器图表管理器,图表管理器会把该命令转发给指定的过滤器。
引用时钟
图表中的过滤器都使用相同的时钟,这被称为引用时钟。引用时钟可以确保所有流同步。输出的音视频显示的时钟,被称为显示时钟。相对于引用时钟,显示时钟就是标准的。过滤器图表管理器通常选择声卡或系统时钟作为应用时钟。
图标事件
过滤器图表管理器使用一个事件队列来通知应用程序,在过滤器图表中发生的事件。这个结构类似于 Windows 的消息循环。
图表方法
过滤器图表管理器提供了一些方法,可以向过滤器图表添加过滤器,实现过滤器间的链接和断开过滤器链接。过滤器图表管理器不对过滤器间数据的移动进行处理。这些工作都是由过滤器通过它们的针脚自己去完成。这些处理通常在一个独立的线程中完成。
在过滤器图表中如何加入硬件设备
这里介绍 Microsoft® DirectShow® 如何加入音视频硬件。
Wrapper Filters
所有 DirectShow 过滤器都是用户模式的软件组件。为了把内核模式下的硬件设备 ( 比如视频捕获卡 ) 加入到 DirectShow 的过滤器图表中,就必须把设备当作一个用户模式过滤器来描述。这个功能就是通过一些 DirectShow 提供的叫“ Wrapper ”的过滤器来实现。这些过滤器包括音频捕获过滤器, VFW 捕获过滤器, TV Tuner 过滤器,电视音频过滤器, Analog Video Crossbar 过滤器。 DirectShow 同样提供了一个叫 KsProxy 的过滤器,它能够描述任何 WDM 的设备。
Wrapper 过滤器通过 COM 接口来描述设备的性能。应用程序通过这些接口把信息发送给过滤器,过滤器把消息翻译转换后调用设备的驱动程序,再把信息传递给硬件设备。同样设备可以把信息反馈给应用程序。 TV Tuner, TV Audio, Analog Video Crossbar, 和 KsProxy 过滤器通过 IksPropertySet 接口支持自定义驱动程序的属性。 VFW 捕获过滤器和音频捕获过滤器不能使用该方法来扩展。
对于应用程序开发人员来讲, wrapper 过滤器允许程序象控制其他 DirectShow 过滤器一样来控制硬件设备。而不需要特别要求的编程来实现。
VFW 设备
VFW 捕获过滤器支持早期的 VFW 捕获卡。
音频捕获和混合设备 ( 声卡 )
新的声卡都有 Mic 和其他设备的输入端口。有些卡还有板载的混音性能。在 DirectShow 中,通过音频捕获过滤器来处理声卡的输入和混音性能。通过使用系统设备调用器可以找到你系统中的每一张声卡。运行 GraphEdit 来浏览你系统中的声卡并从音频捕获设备类中选择你要的声卡。在那里你看到所有的音频捕获过滤器。
WDM 流设备
新的硬件解码器和捕获卡都遵循 WDM 规范。 WDM 视频卡能支持 VFW 不能提供的性能。
DirectShow 提供了一个 KsProxy 过滤器 (ksproxy.ax) 来支持 WDM 流设备。 KsProxy 被称为 ( 瑞士军刀过滤器 ) “ Swiss Army Knife filter ”,因为它可以作许多不同的事情。该过滤器针脚数量和过滤器 COM 接口的数量依赖于设备驱动程序的性能。在过滤器图表中的 KsProxy 过滤器基本上不会用“ KsProxy ”名字出现,它通常使用具体设备的名字 (Friendly Name), 这些名字可以在注册表中找到。运行 GraphEdit 可以浏览你系统中的 WDM 设备,还可以从 WDM 类形设备中,选择你想要的设备。如果你的系统上只有一个 WDM 卡,这个卡上可能会有多个设备。每个设备都被描述为一个独立的过滤器,这些过滤器都是一个真正的 KsProxy 设备。
应用程序使用系统设备查询器( System Device Enumerator )来查到系统中的 WDM 设备名称 (Moniker) 对象。调用 Moniker 对象的 BindToObject 方法来创建 KsProxy 实例。由于 KsProxy 可以描述所有的 WDM 设备,所以它必须查询设备驱动程序来判断该设备支持什么样的功能属性。属性集是一个用于 WDM 驱动程序和一些用户模式过滤器(比如 MPEG-2 软解压器)的数据结构集合。 KsProxy 会自我配置然后通过 COM 接口去匹配设备的属性集。硬件开发商可通过插件模式来扩充 KsProxy ,以实现其特定的功能。这些细节对于应用程序都是隐藏的,你的程序通过 KsProxy 来控制硬件设备,这个时候,硬件设备被当作一个 DirectShow 过滤器来处理。
内核流( Kernel Streaming )
WDM 设备支持内核流,即数据流动在内核模式下进行,而不会进入到用户模式。在内核模式下,数据可以高速流动,而不会占用 CPU 的处理率。基于 WDM 的过滤器可以使用内核流,在硬件设备间去直接移动数据,而不必把数据先拷贝到系统内存,然后再拷贝到目标设备中。
站在应用程序的角度,我们来看数据的流动。数据是从一个过滤器(用户模式过滤器)移动到另一个过滤器(用户模式过滤器),其实数据真实的移动基本上都没有在用户模式下进行,而是在内核模式下进行的。当然也有例外,如果你要捕获一个视频数据并保存在文件中,这样,数据会从内核模式(设备)移动到用户模式下(文件)。即使在这种情况下,也不必为它分配系统内存实现拷贝。
---------------------------------------------------------------------------------
阅读我的相关文章:
《如何列举你系统已经安装的设备(视频压缩设备,视频捕获设备 ... )》
《谈谈使用 VFW 在 Windows 下编程控制摄像头 一》
《谈谈使用 VFW 在 Windows 下编程控制摄像头 二》
《谈谈视频压缩管理器( VCM ) Video Compress Manager 》
---------------------------------------------------------------------------------
欢迎来我的博客 : http://blog.csdn.net/suntaoznz 看更多的文章 !