3. DirectShow-深入理解filter概念

基本名词: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 可以分为多个大类:

  • filter 将数据引入。 数据可能来自文件、网络、相机或其他任何位置。 每个源filter 处理不同类型的数据源。
  • 转换filter 采用输入流、处理数据并创建输出流。 编码器和解码器是转换filter 的示例。
  • 呈现器 filter 位于链的末尾。 他们接收数据并将其呈现给用户。 例如,视频呈现器在显示器上绘制视频帧、音频呈现器将音频数据发送到声音卡、文件编写器将数据写入文件。
  • 拆分器filter 将输入流拆分为两个或多个输出,通常在此过程中分析输入流。 例如,AVI 拆分器将字节流分析为单独的视频流和音频流。
  • 复用filter 采用多个输入,并将其合并到单个流中。 例如,AVI 复用器执行 AVI 拆分器反运算。 它采用音频和视频流,并生成 AVI 格式的字节流。
    所有 DirectShow filter 都公开 IBaseFilter 接口,所有pin 都公开 IPin 接口。

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用于计划呈现的呈现时间。
    标志指示自上一个示例以来数据中是否存在中断之类的情况。
    媒体类型为filter提供了一种在流中更改格式的方法。 通常,该示例没有媒体类型,这表示格式自上一个示例以来没有更改。
    filter使用缓冲区时,它会保留样本的引用计数。 分配器使用引用计数来确定何时可以重复使用缓冲区。 这可以防止filter覆盖另一个filter仍在使用的缓冲区。 样本不会返回到分配器的可用样本池,直到每个filter释放它。

filter Graph

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

  • 协调filter 之间的状态更改。
  • 建立引用时钟。
  • 将事件传达回应用程序。
  • 为应用程序提供生成filter Graph 的方法。
    此处简要介绍了其中每个函数。 可在文档的其他地方找到详细信息。
    状态更改。 filter 中的状态更改必须按特定顺序发生。 因此,应用程序不会直接向filter 发出状态更改命令。 相反,它会向 Filter Graph 管理器提供单个命令,后者将命令分发给每个filter 。 查找的工作方式与此类似:应用程序向 Filter Graph 管理器提供一个 seek 命令,后者将其分发到filter
    参考时钟。 图中的所有filter 都使用相同的时钟,称为 引用时钟。 引用时钟可确保同步所有流。 应呈现视频帧或音频示例的时间称为 演示时间。 表示时间相对于参考时钟进行测量。 Filter Graph 管理器选择引用时钟,通常是声音卡上的时钟或系统时钟。
    图形事件。 Filter Graph 管理器使用事件队列通知应用程序filter Graph 中发生的事件。 此机制类似于 Windows 消息循环。
    图形生成方法。 Filter Graph 管理器为应用程序提供了向图形添加filter 、将filter 连接到其他filter 以及断开filter 连接的方法。
    Filter Graph 管理器不处理的一个函数是将数据从一个filter 移动到下一个filter 。 这由filter 本身通过其pin 连接完成。 处理始终在单独的线程上进行。

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。 实际上,数据可能根本不会进入用户模式,而是可以直接从一个内核模式设备流式传输到另一个内核模式设备,直到在视频图形上呈现卡。 某些方案(如捕获到文件)要求数据在某个时间点从内核模式传递到用户模式。 但是,此开关不一定要求将数据复制到内存中的新位置。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容