智慧的鱼--------DirctShow SDK 学习笔记
1
Directshow 开发笔记(翻译)
个人感觉开发自己的 Filter 还是要对 dshow 的基类要熟悉一些。所以才想起了要翻译这
些东西,希望在 9 月底前完成这些东西。我不想它的句子有多么流畅,语法的错误有多少,
我只希望能看明白就可以了
智慧的鱼(LeeQiang)
2004.8.20
由于某些原因,SDK 中的有些章节我没有翻译,如果哪位兄弟补充以后,可以将补充后的文
档发给我,我也学习学习,互相学习的过程就是提高的过程。
智慧的鱼--------DirctShow SDK 学习笔记
1
1 About Directshow 基础
1.1 设置 dshow 的开发环境
如果你用 VC 开发环境,一定要在 Setting 里设置下面的东西
包含头文件 Dshow.h 所有的 dshow 应用必须包含
包含动态库 Strmiids.lib 导出所有接口的 CLSID 和接口 IID 定义。必须包含
Quartz.lib
智慧的鱼--------DirctShow SDK 学习笔记
1
1.2 先演示一下 dshow 使用的一个例子
这里暂略。
1.3 Direcshow 概述
DirectShow 是微软公司提供的一套在 Windows 平台上进行流媒体处理的开发包,与
DirectX 开发包一起发布。
那么,DirectShow 能够做些什么呢?且看,DirectShow 为多媒体流的捕捉和回放提供了强有
力的支持。运用 DirectShow,我们可以很方便地从支持 WDM 驱动模型的采集卡上捕获数据,
并且进行相应的后期处理乃至存储到文件中。它广泛地支持各种媒体格式,包括 Asf、Mpeg、
Avi、Dv、Mp3、Wave 等等,使得多媒体数据的回放变得轻而易举。另外,DirectShow 还集
成了 DirectX 其它部分(比如 DirectDraw、DirectSound)的技术,直接支持 DVD 的播放,视
频的非线性编辑,以及与数字摄像机的数据交换。更值得一提的是,DirectShow 提供的是一
种开放式的开发环境,我们可以根据自己的需要定制自己的组件。
TDirectShow的系统组成
应用程序与 DirectShow 组件以及 DirectShow 所支持的软硬件之间的关系如图 1 所示。
图 1 DirectShow 系统框图
1.4 Filter Graph 及其组成
这篇文档中我想给讲述 Directshow 的主要组成部分,一个概括性的入门文章,对于应用开发
或者 directshow 的开发者都有所帮助。
1 DirectShow 的 Filter
Directshow 是基于模块化,每个功能模块都采取 COM 组件方式,称为 Filter。Directshow
智慧的鱼--------DirctShow SDK 学习笔记
1
提供了一系列的标准的模块可用于应用开发,开发者也可以开发自己的功能 Filter 来扩展
Directshow 的应用。下面我们用一个例子来说明如何采取 Filter 来播放一个 AV I 的视频文件。
从一个文件读取数据,形成字节流。(这个工作由源 Filter 完成)
检查 AV I 数据流的头格式,然后通过 AV I 分割 Filter 将视频流和音频流分开。
解码视频流,根据压缩格式的不同,选取不同的 decoder filters 。
重画视频图像,通过 Renderer Filter。
将音频流送到声卡进行播放,一般采用缺省的 DirectSound Device Filter。流程见下图。
从上面的图表看,每一个 filter 都一个其他的一个或者两个 filter 相连接,连接点也是 com 对
象,我们称为 Pin。Filter 通过 pin 将数据从一个 filter 传递到另一个 filter 中,从而可以使数据
的 filter 的链表中流动。图中的箭头表示 filter 链表中的数据流的方向。在 Directshow 中,一
个 filter 链表我们称为 filter Graph。
Filter具有三个状态,运行,停止,暂停。当一个filter运行时,它就处理媒体数据流,当停
止时,filter就不在处理数据,暂停状态常用来给运行状态之前cure data。
HTUData Flow in the Filter
GraphUTH一章详细描述了这些概念,可以参考。
除非特别的例外,所有 Filter graph 中的 filter 的状态的改变都是统一的,也就说,filte graph
中的所有的 filter 的状态改变是一致协调的。也就是说,我们也可以用 filter graph 也可以有运
行,停止,暂停三种状态。
Filter 一般分为下面几种类型。
(1)源过滤器(source filter):源过滤器引入数据到过滤器图表中,数据来源可以是文
件、网络、照相机等。不同的源过滤器处理不同类型的数据源。
(2)变换过滤器(transform filter):变换过滤器的工作是获取输入流,处理数据,并生
成输出流。变换过滤器对数据的处理包括编解码、格式转换、压缩解压缩等。
(3)提交过滤器(renderer filter):提交过滤器在过滤器图表里处于最后一级,它们接
收数据并把数据提交给外设。
(4)分割过滤器(splitter filter):分割过滤器把输入流分割成多个输出。例如,AVI 分
割过滤器把一个 AVI 格式的字节流分割成视频流和音频流。
(5)混合过滤器(mux filter):混合过滤器把多个输入组合成一个单独的数据流。例如,
AVI 混合过滤器把视频流和音频流合成一个 AVI 格式的字节流。
过滤器的这些分类并不是绝对的,例如一个 ASF 读过滤器(ASF Reader filter)既是
一个源过滤器又是一个分割过滤器。
2 关于 Filter Graph Manager
HTUFilter Graph ManagerUTH也是一个com对象,用来控制Filter graph中的所有的filter,主要有以下的
功能:
1 用来协调 filter 之间的状态改变,从而使 graph 中的所有的 filter 的状态的改变应该一致。
2 建立一个参考时钟。
3 将 filter 的消息返回给应用程序
4 提供方法用来建立 filter graph。
智慧的鱼--------DirctShow SDK 学习笔记
1
这里只是简单的描述一下,详细地可以参考文档。
状态改变,Graph 中的 filter 的状态改变应该一致,因此,应用程序并将状态改变的命令直接
发给 filter,而是将相应的状态改变的命令发送给 Filter graph Manager,由 manager 将命令分
发给 graph 中每一个 filter。Seeking 也是同样的方式工作,首先由应用程序将 seek 命令发送到
filter graph 管理器,然后由其分发给每个 filter。
参考时钟,graph 中的 filter 都采用的同一个时钟,称为参考时钟(reference clock),参考时钟
可以确保所有的数据流同步,视频桢或者音频桢应该被提交的时间称为
presentation
time
.presentation time 是相对于参考时钟来确定的。Filter graph Manager 应该选择一个参考时
钟,可以选择声卡上的时钟,也可以选择系统时钟
Graph 事件, Graph 管理器采用事件机制将 graph 中发生的事件通知给应用程序,这个机制
类似于 windows 的消息循环机制。
Graph 构建的方法,graph 管理器给应用程序提供了将 filter 添加进 graph 的方法,连接 filter
的方法,断开 filter 连接的方法。
但是,graph 管理器没有提供如何将数据从一个 filter 发送到另一个 filter 的方法,这个工作
是由 filter 在内部通过 pin 来独立完成的,
3 媒体类型
因为 Directshow 是基于 com 组件的,就需要有一种方式来描述 filter graph 每一个点的数据
格式,例如,我们还以播放 AV I 文件为例,数据以 RIFF 块的形式进入 graph 中,然后被分割
成视频和音频流,视频流有一系列的压缩的视频桢组成,解压后,视频流由一系列的无压缩
的位图组成,音频流也要走同样的步骤。
Media Types: How DirectShow Represents Formats
媒体类型是一种很普遍的,可以扩展的用来描述数字媒体格式的方法,当两个 filter 连接的
时候,他们会就采用某一种媒体类型达成一致的协议。媒体类型定义了处于源头的 filter 将要
给下游的 filter 发送什么样的数据,以及数据的 physical layout。如果两个 filter 不能够支持同
一种的媒体类型,那么他们就没法连接起来。
对于大多数的应用来说,也许你不用考虑媒体类型,但是,有些应用程序中,你会直接应
用到媒体类型的。
媒体类型是通过
HTUAM_MEDIA_TYPEUTH结构定义的,看看原始定义吧
typedef struct _MediaType {
GUID majortype;
GUID subtype;
BOOL bFixedSizeSamples;
BOOL bTemporalCompression;
ULONG lSampleSize;
GUID formattype;
IUnknown *pUnk;
ULONG cbFormat;
[size_is(cbFormat)] BYTE *pbFormat;
} AM_MEDIA_TYPE;
Major type:
是一个 GUID,用来定义数据的主类型,包括,音频,视频,unparsed 字节流,MIDI
数据,等等,具体可以参考 msdn。
Subtype:
子类型,也是一个 GUID,用来进一步的细化数据格式,例如,在视频主类型中,还
包括 RGB-24, RGB-32, UYVY 等等一些子类型,在音频主类型中还包括 PCM audio, MPEG-1
payload 等类型,子类型提供了比主类型更详细的信息,但是并没有定义所有的格式,例如,