DirectShow技术是建立在DirectDraw和DirectSound组件基础之上的,
它通过DirectDraw对显卡进行控制以显示视频,
通过DirectSound对声卡进行控制以播放声音。
DirectShow功能实现:
1.可提供高质量的多媒体流的捕获和回放功能;
2.支持多种媒体格式,包括ASF(Advanced Systems Format),MPEG(Motion Picture Experts Group),AVI(Audio-Video Interleaved),MP3(MPEG Audio Layer-3)和WAV声音文件;
3.可从硬件上捕获媒体数据流;
4.可自动检测并使用视频和音频加速硬件。
故,DirectShow是用于多媒体应用开发。(其实就是一个软编码(or解码))
它充分发挥媒体的性能,提高运行速度,可以简化媒体播放、媒体间的格式转换
和媒体捕获等工作。同时,它还具有极大的可扩展性和灵活性,可以由用户自己
创建组件,并将这个组件加入DirectShow结构中以支持新的格式或特殊的效果。
应用程序与DirectShow组件以及DirectShow所支持的软硬件之间的关系
如图1
二。概念
1.过滤器
过滤器分为以下几种类型:
a 源过滤器(source filter):
源过滤器引入数据到过滤器图表中,数据来源可以是文件、网络、照相机等。
不同的源过滤器处理不同类型的数据源。
b 变换过滤器(transform filter):
变换过滤器的工作是获取输入流,处理数据,并生成输出流。
变换过滤器对数据的处理包括编解码、格式转换、压缩解压缩等。
c 提交过滤器(renderer filter):
接收数据并把数据提交给外设。
d 分割过滤器(splitter filter):
把输入流分割成多个输出。
如,AVI分割过滤器把一个AVI格式的字节流分割成视频流和音频流。
e 混合过滤器(mux filter):
把多个输入组合成一个单独的数据流。
如,AVI混合过滤器把视频流和音频流合成一个AVI格式的字节流。
过滤器的这些分类并不是绝对的,如一个ASF读过滤器(ASF Reader filter)
既是一个源过滤器又是一个分割过滤器。
2 filter graph
过滤器图表用来连接过滤器以控制媒体流,它也可以将数据返回给应用程序,
并搜索所支持的过滤器。
过滤器有三种可能的状态:运行、停止和暂停。
暂停是一种中间状态,停止状态到运行状态必定经过暂停状态。
暂停可以理解为数据就绪状态,是为了快速切换到运行状态而设计的。
在暂停状态下,数据线程是启动的,但被提交过滤器阻塞了。
通常情况下,过滤器图表中所有过滤器的状态是一致的。
3. 引脚(pin)
过滤器可以和一个或多个过滤器相连,
连接的接口也是COM形式的,称为引脚。
过滤器利用引脚在各个过滤器间传输数据。
每个引脚都从Ipin这个COM对象派生出来的。
每个引脚都是过滤器的私有对象,过滤器可以动态的创建引脚,销毁引脚,自由控制引脚的生存时间。
引脚分输入引脚(Input pin)和输出引脚(Output pin)两种类型,
两个相连的引脚必须是不同种类的,即输入引脚只能和输出引脚相连
过滤器之间的连接(也就是引脚之间的连接),实际上是连接双方媒体类型(Media Type)协商的过程。(媒体类型,不完全媒体类型 再下一节有讲解)
连接的大致过程为:
如果调用连接函数时已经指定了完整的媒体类型,则用这个媒体类型进行连接,
成功与否都结束连接过程;
如果没有指定或不完全指定了媒体类型,
则枚举过程见后面.其两个filter的连接设定如下.
Filter A ------------------> Filter B
------------------------------------------------------------- ------------------
说明:
媒体类型(Media Type)
两个过滤器相连时,必须使用一致的媒体类型,否则这两个过滤器就不能相连。
媒体类型能识别上一级过滤器传送给下一级过滤器的数据类型,并对数据进行分类。
媒体类型的结构 AM_MEDIA_TYPE
AM_MEDIA_TYPE由三部分组成:
Major type
Subtype
Format type
都使用GUID 来唯一标示
Major type主要定性描述一种媒体类型,这种媒体类型可以是视频、音频、比特数据流或MIDI数据等;
Subtype 进一步细化媒体类型,
拿视频的说就是进一步指定是RGB-24,还是RGB-32,或是UYVY等;
Format type则用一个结构更进一步细化媒体类型。
媒体类型的三个部分都指定了某个具体的GUID值,则称这个媒体类型是完全指定的;
媒体类型的三个部分中有任何一个值是GUID_NULL,则称这个媒体类型是不完全指定的。
GUID_NULL起通配符作用
pinout和pinin的连接过程可以用下面逻辑语言表达.
1.如调用连接函数时已经指定了完整的Media type,则用这个Media type进行连接,
成功与否都结束连接过程;
2.如没有指定或不完全指定了Media type,
则如下:
BOOL CheckFilterB_PinIn()
{
for(i = 0 ; i < FilterB.FPinIn.MediaTypeCount ; i++)
{
if (IsSameMediaType(FilterA.FPinOut,FilterB.FPinIn.MediaType[i]) = True)
{
return TRUE; //Pin之间的连接成功;
}
}
return FALSE; //在Input pin不支持该媒体类型,失败.
}
返回FALSE再枚举Output pin上的所有Media type,并逐一用这些Media type与Input pin进行连接。
for(i = 0 ; i < FilterA.FPinOut.MediaTypeCount; i++)
{
if (CheckFilteB_PinIn(FilterA.FPinOut.MediaType[i]) = True )
{
return TRUE;
}
}
return FALSE; //filterA和filterB的连接失败.