3. DirectShow-深入理解filter概念

2023-08-24  本文已影响0人  天之彼方_d26a

基本名词:filter、pin、filter Graph

DirectShow 使用模块化体系结构,其中每个处理阶段都由名为filter 的 COM 对象完成。 DirectShow 提供了一组标准filter 供应用程序使用,开发人员可以编写自己的自定义filter 来扩展 DirectShow 的功能。每个filter 都连接到一个或多个其他filter 。 连接点也是 COM 对象,称为 pinfilter 使用pin 把数据从一个filter 移动到下一个filter 中。在 DirectShow 中,一组filter 称为 filter Graph

filter的状态

filter 有三种可能的状态:运行、停止和暂停。 filter 运行时,它会处理媒体数据。 停止时,它将停止处理数据。 暂停状态用于在运行前提示数据。
filter关系图管理器按上游顺序执行所有状态转换,从呈现器开始,然后向后工作到源filter。 必须进行此排序,以防止删除MediaSample并防止图形死锁。 最重要的状态转换是在暂停和停止之间转换:
已停止-->暂停:当每个filter暂停时,它便准备好从下一个filter接收MediaSample。 源filter是最后一个暂停的filter。 它创建流式处理线程并开始传送MediaSample。 由于所有下游filter都已暂停,因此没有filter会拒绝任何MediaSamplefilter图形管理器不会完成转换,直到图形中的每个呈现器都收到MediaSample ((实时源除外),如前面) 所述。

暂停-->停止:当filter停止时,它会释放它保存的任何MediaSample,从而取消阻塞在 GetBuffer 中等待的任何上游filter。 如果filter正在等待 Receive 方法中的资源,它将停止等待并从 Receive 返回,这会取消阻塞调用filter。 因此,当 Filter Graph 管理器停止下一个上游filter时,该filter不会在 GetBuffer 或 Receive 中被阻塞,并且可以响应 stop 命令。 上游filter可能会在获取停止命令之前提供一些额外的MediaSample,但下游filter只是拒绝它们,因为它已经停止。

filter的分类

filter 可以分为多个大类:

pin的作用

filterpin连接提供数据。 数据从一个filter的输出pin移动到另一个filter的输入pin。 输出pin传递数据的最常见方法是对输入调用 IMemInputPin::Receive 方法,但也有一些其他机制。

根据filter,媒体数据的内存可以通过各种方式分配:在堆上、在 DirectDraw中、使用共享 GDI 内存或使用某种其他分配机制。 负责分配内存的对象称为 分配器,该分配器是公开 IMemAllocator 接口的 COM 对象。

当两个pin连接时,其中一个pin必须提供分配器。 DirectShow 定义一系列方法调用,用于建立哪个pin提供分配器。 pin还就分配器将创建的缓冲区数和缓冲区大小达成一致。

在流式处理开始之前,分配器会创建缓冲区池。 在流式处理期间,上游filter使用数据填充缓冲区,并将其传递到下游filter。 但是,上游filter不会为下游filter提供指向缓冲区的原始指针。 相反,它使用称为 MediaSample的 COM 对象,分配器创建这些对象来管理缓冲区。 MediaSample公开 IMediaSample 接口。 MediaSample包含:

filter Graph

Filter Graph 管理器是一个 COM 对象,用于控制filter Graph中的一组filter 。 它执行许多功能,包括以下内容:

filter是如何与音频和视频硬件交互的

所有 DirectShow filter都是用户模式软件组件。 为了使内核模式硬件设备(如视频捕获卡)加入 DirectShow filter图,设备必须表示为用户模式filter。 此函数由 DirectShow 提供的专用“包装器”filter执行。 这些filter包括 音频捕获 filter、 VFW 捕获 filter、 电视调谐器 filter、 电视音频 filter和 模拟视频横杠 filter。 DirectShow 还提供名为 KsProxy 的filter,该filter可以表示任何类型的 Windows 驱动程序模型 (WDM) 流式处理设备。 硬件供应商可以通过提供 Ksproxy 插件(由 KsProxy 聚合的 COM 对象)来扩展 KsProxy 以支持自定义功能。

包装器filter公开表示设备功能的 COM 接口。 应用程序使用这些接口向filter传递和从filter传递信息。 filter将 COM 方法调用转换为设备驱动程序调用,在内核模式下将该信息传递给驱动程序,然后将结果转换回应用程序。 电视调谐器、电视音频、模拟视频交叉栏和 KsProxy filter通过 IKsPropertySet 接口支持自定义驱动程序属性。 VFW 捕获filter和音频捕获filter不是以这种方式扩展的。

对于应用程序开发人员,包装器filter使应用程序能够像控制任何其他 DirectShow filter一样控制设备。 无需特殊编程;与内核模式设备通信的详细信息封装在filter中。

Windows 设备视频

VFW 捕获filter支持 Windows (VfW) 捕获卡的早期视频。 当目标系统上存在 VfW 卡时,可以使用 DirectShow 系统设备枚举器发现它并将其添加到filter图中。 有关详细信息,请参阅 枚举设备和filter

音频捕获和混音设备 (声卡)

较新的声卡具有用于麦克风和其他类型的设备的输入插孔。 通常,这些卡还具有板载混合功能,用于控制每个输入的音量、高音和低音。 在 DirectShow 中,声音卡的输入和混音器由音频捕获filter包装。 可以使用系统设备枚举器发现每个声音卡。 若要查看系统中的声卡,请运行 GraphEdit 并从“音频捕获源”类别中进行选择。 该类别中的每个filter都是音频捕获filter的单独实例。 (请参阅 使用 GraphEdit.)

WDM 流式处理设备

较新的硬件解码器和捕获卡符合 Windows 驱动程序模型 (WDM) 规范。 这些设备比 VfW 设备具有更大的功能。 WDM 视频捕获卡可以支持 VfW 下不可用的功能,包括捕获格式的枚举、视频参数(如色调和亮度)的编程控制、编程输入选择和电视调谐器支持。

为了支持 WDM 流式处理设备,DirectShow 提供了 KsProxy filter(ksproxy.ax) 。 KsProxy被称为“瑞士军刀过滤器”,因为它做许多不同的事情。 filter上的pin数以及filter公开的 COM 接口数取决于基础驱动程序的功能。 KsProxy 不会显示在名称“KsProxy”下的filter图中。它始终采用在注册表中找到的设备的友好名称。 若要查看系统上的 WDM 设备,请运行 GraphEdit 并从 WDM 流式处理类别中进行选择。 即使系统上只有一个 WDM 卡,该卡也可能包含多个设备。 每个设备都表示为单独的filter,其中每个filter实际上都是 KsProxy。

应用程序使用系统设备枚举器查找系统上的 WDM 设备名字对象。 KsProxy 通过在名字对象上调用 BindToObject 来实例化。 由于 KsProxy 可以表示所有类型的 WDM 设备,因此它必须查询驱动程序以确定驱动程序支持的属性集。 属性集是 WDM 驱动程序以及某些用户模式filter(如 MPEG-2 软件解码器)使用的数据结构的集合。 KsProxy 将自身配置为公开与这些属性集对应的 COM 接口。 KsProxy 将 COM 方法调用转换为属性集,并将其发送到驱动程序。 硬件供应商可以通过提供插件来扩展 KsProxy,插件是供应商特定的接口,用于公开设备的特殊功能。 所有这些详细信息都对应用程序隐藏。 应用程序通过 KsProxy 控制设备,其方式与任何其他 DirectShow filter的方式相同。

内核流式处理

WDM 设备支持内核流式处理,其中数据完全在内核模式下流式传输,而无需切换到用户模式。 在内核模式和用户模式之间切换计算成本高昂;内核流式处理允许高比特率,而不会给主机 CPU 带来负担。 基于 WDM 的filter可以使用内核流式处理将多媒体数据从一个硬件设备直接传递到另一个硬件设备,无论是在同一个卡上还是在不同的卡,而无需将数据复制到系统的main内存中。

从应用程序的角度来看,数据似乎从一个用户模式filter移动到下一个用户模式filter。 实际上,数据可能根本不会进入用户模式,而是可以直接从一个内核模式设备流式传输到另一个内核模式设备,直到在视频图形上呈现卡。 某些方案(如捕获到文件)要求数据在某个时间点从内核模式传递到用户模式。 但是,此开关不一定要求将数据复制到内存中的新位置。

上一篇 下一篇

猜你喜欢

热点阅读