下面,我们举个例子来看一下DES能够给我们带来些什么。假如我们现在有三个文件A、B和C,使用这三个文件做成一个合成的文件。我们想取A的4秒钟的内容,紧接着取B的10秒钟的内容,再紧接着C的5秒钟的内容。如果仅仅是这样,我们直接使用DirectShow Filter是不难实现的。(一般情况下,应用程序级会维持各个文件的编辑信息,由应用程序根据这些信息动态创建/控制功能单一的Filter Graph,以顺序对各个文件进行处理。)但是,如果我们的“创意”是随时改变的,我们现在想让C在B之前出现,或者我们想取A的不同位置的10秒钟内容,或者我们想给整个合成的文件加上一段美妙的背景音乐。如果我们仍然直接使用DirectShow Filter去实现,情况就变得很复杂了。然而,对于DES,这真的是小Case!(将所有的编辑信息以DES提供的接口告诉DES,其它的如Filter Graph的创建/控制输出,就完全交给DES来负责吧!这时候,DES创建的Filter Graph带有各个Source输出的控制功能,一般比较复杂。)
如果我们使用DES,我们还可以得到如下的便利:
1. 基于时间线(Timeline)的结构以及Track的概念,使得多媒体文件的组织、编辑变得直观而高效;
2. 支持即时的预览;
3. 视频编辑项目支持XML文档的形式保存;
4. 支持对视频/音频的效果处理,以及视频之间切换的过渡处理;
5. 可以直接使用DES提供的100多种SMPTE过渡效果,以及MS IE自带的各种Transform、Transition组件;
6. 支持通过色调、亮度、RGB值或者alpha值进行图像的合成;
7. 自动对源文件输出的视频帧率、音频的采样率进行调整,直接支持视频的缩放。
接下去,我们来看一下DES的结构(Timeline模型),如下图所示:
这是一个树形结构。在这棵树中,音视频文件是叶结点,称作为Source;一个或多个Source组成一个Track,每个Track都有统一的媒体格式输出;Track的集合称作为Composition,每个Composition可以对其所有的Composition或Track进行各种复杂的编辑;顶级的Composition或Track就组成了Group;每个Group输出单一格式的媒体流,所有的Group组成一个Timeline, Timeline表示一个视频编辑的项目,它是这棵树的根节点。一个Timeline项目必须至少包含一个Group,最典型的情况一般包含两个Group:Audio Group和Video Group。
下面,我们来看一个典型的基于Timeline的Source Track编排。如下图:
图中,箭头方向即是Timeline的方向。这个Timeline由两个Group组成,每个Group中包含两个Source Track。在Group中,Track是有优先级的(Track 0具有最低的优先级,依次类推)。运行时,总是输出高优先级的Track中的Source内容。如果此时高优先级的Track中没有Source输出,则让低优先级的Track中的Source输出。如上图中Video Group的输出顺序为Source A->Source C->Source B。而对于Audio Group,它的所有Track的输出只是简单的合成。
我们再看一个典型的Track之间加入了Transition的Timeline结构。如下图:
图中,Video Group中是两个Track以及Track上几个Source的编排;Rendered video中表示这个Group最终输出的效果。我们可以看到,在Track 1上有一个Transition,表示这个时间段上从Track 0过渡到Track1的效果。一般,Transition位于高优先级的Track上。Transition也是有方向的,默认是从低优先级的Track过渡到高优先级的Track。当然,我们也可以改变Transition的方向。如下图所示,第一个Transition是从Track 0到Track 1,第二个Transition是从Track 1到Track 0。
值得注意的是,DES使用的Transition采用了叫做DirectX Transform Object的技术。任何两输入一输出的DirectX Transform Object都可以用作Transition。遗憾的是,微软现在的DirectX SDK不再支持这种组件的开发。我们能够使用的,只有DES本身提供的几种效果,还有就是Microsoft Internet Explorer自带的效果。DES使用的Effect情况类似,只不过DES Effect是单输入单输出的DirectX Transform Object。
讲到这里,我们已经对DES结构有了一个初步的了解。我们需要回过去再看一看这个Timeline树结构。我们会发现,Group下面一般都有一个Composition,而随后的图例中,我们看到一般Group下直接嵌入的是Track。那么,Composition有什么用呢?熟悉《设计模式》的人很容易就明白了,微软采用的就是对象结构型模式的其中一种叫Composite(组合)的模式。Composition可以包装几个Track(这几个Track之间可能是包含Transition的),组成一个Virtual Track,并且与其他普通的Track接口保持一致。我们完全可以把这个Virtual Track与普通的Track一样操作,进而很方便地进行更加复杂、丰富的效果编辑。我们知道,DES是在Filter之上做了一层封装。为了更进一步地理解DES,我们就必须从Filter Graph这个层次对DES进行剖析。
下面,我们看一个典型的DES Filter Graph图:
上图中,有两个Filter外形很大:一个含有20个Input pin和20个Output pin,另一个含有15个Input pin和10个Output pin。前者是DES的Video控制Filter,后者是DES的Audio控制Filter。这两个Filter也就是DES的核心所在。他们知道用户编辑的Timeline结构,并且它们能够在Filter Graph运行的时候创建各个Source的解码链路。
下面我们再看一下当一个Timeline结构“翻译”成Filter Graph时是什么样子。先看Video部分:
从上图可以看出,我们加入了一个Mpeg1的File source。DES 会自动给这个File source进行解码。首先经过Splitter。因为这个File source是加在Video group的,所以DES只取Splitter出来的Video部分。然后经过Resizer。这个Filter调整Video输出的Size。然后经过Frame Rate Converter。这个Filter调整Video输出的帧率。最后,连接到DES Video控制Filter的某个Input pin上。DES的“自动对源文件输出的视频帧率、音频的采样率进行调整,直接支持视频的缩放”的奥妙也就在此。
值得注意的是,这条解码链路是通过微软的“智能连接”来创建的。采用这种方法,DES可以最大限度地使用本地系统中已经安装的Filter。但同时,也给基于DES的应用程序带来了麻烦。因为应用程序运行的系统环境是不可预见的,DES对Source的解码链路构建也就不稳定,相应地,应用程序的稳健性受运行环境的影响也会比较大。
下面我们再来看一下Audio部分:
可以看出,Audio解码链路与Video部分是相似的。需要说明一下的是,Audio Repackager这个Filter负责将Audio数据按设定的每秒钟输出多少个Sample重新进行打包,类似于Video部分的Frame Rate Converter。
理论上说,DES支持任何格式的媒体文件,只要系统中注册了对这种格式文件的解码Filter。我们看一下下图,DES对静态图片的支持:
接下去,我们再来看一下DES对Effect/Transition的实现情况。我们知道,DES并没有直接实现Effect/Transition。DES只是在Timeline中建立了一个包装,而具体的工作交给了所谓的”Subobject”去做。这个”Subobject”就是DirectX Transform Object,它是一种COM组件,而且遗憾的是,这种组件的开发技术在微软新的DirectX SDK中已经找不到了。也就是说,如果我们开发基于DES的应用程序的话,我们只能使用DES提供的,以及微软IE自带的Effect/Transition。这种限制同样是令人头疼的!下面看一下两个图例:
从图中可以看出,Effect/Transition都使用了Wrapper filter(这两个Filter的CLSID是相同的),不同的是Effect是一进一出,而Transition是两进一出。我们还可以看到,Video控制Filter的Output pin经过Effect/ Transition后重新作为Video控制Filter的一个输入。
接下去,我们再来看一下DES对Audio Mixing的实现。典型的Timeline会有一个Video Group和一个Audio Group。如果整个Audio Group没有一个Audio source,或者一个10s的Timeline,Audio file仅有0-5s的输出,DES是如何处理的呢?我们看下图:
DES会自动创建一个Source,这个Source产生Mute PCM Audio。这样,就保证了Audio Group在整个Timeline过程中肯定是有输出的。下图是Audio Mixing的一个例子,DES的Audio控制Filter将所有输入的PCM Audio做简单的混合后输出。
最后,我们来看一下DES Filter Graph的创建过程。我们可以看到,最开始创建的,只有那两个控制Filter,还有Effect/Transition的包装Filter以及Audio/Video各自的Renderer filter。当Filter Graph开始运行,控制Filter就开始创建Timeline上第一个Source的解码链路;而当Filter Graph运行到最后的时候,整个Filter结构可能看起来非常复杂。DES能够根据Timeline上的各个Object的Timeline Time进行动态的创建、动态的连接。
对于编写基于DES的应用程序开发者来说,了解这些DES的Filter Graph结构不是十分必要的。另一方面,因为DES的局限性(而且或许对于某些大型的商业应用软件来说是致命的),我们直接使用DES的可能性很小。我们研究的目的,在于汲取DES设计的精华,以开发一套适合于我们自己的使用的、提供强大编辑功能的DirectShow Filter应用架构。