大家知道,微软定义了自己的一种媒体文件类型,叫做ASF(Advanced Systems Format)。ASF其实是一个文件“容器”,它本身并没有规定音视频的压缩格式;在ASF文件中,我们可以包含任何格式的压缩的(包括MPEG-4)、或非压缩的数据。另外,微软提供了独立于DirectX开发环境以外的Windows Media Format SDK(以下简称WMFS) ,专门用于支持客户开发ASF相关的应用。那么,我们能不能在DirectShow中开发ASF的应用呢?
答案是肯定的。因为ASF是微软自己的媒体格式,它当然会得到特别的关照。微软提供了一系列的Filter。只是这些Filter的版本关系比较复杂,我们下面先来整理一下。
最早从Windows Media Player (微软的媒体播放器,以下简称WMP)6.4,微软使用了一个叫Windows Media Source的Filter,来支持ASF文件的播放。这个Source Filter默认与.asf、.wmv、.wma扩展名文件关联(即在调用IGraphBuilder::RenderFile或IGraphBuilder::AddSourceFilter来播放上述扩展名的文件时,Filter Graph Manager会自动使用Windows Media Source Filter)。下面是典型的使用Windows Media Source Filter来播放ASF文件的Filter Graph参考图:
从DirectShow 8.0开始,微软提供了另外两个Filter:WM ASF Reader和WM ASF Writer。并且随着DirectShow版本的更新,这两个Filter的版本也在不断更新。(DirectShow 8.1中的这两个Filter使用了WMFS 7.0,DirectShow 9.0中的使用了WMFS 7.1。)但是,尽管如此,为了保持向后兼容性,微软还是让Windows Media Source Filter作为播放.asf、.wmv、.wma文件的默认Source Filter。直到WMFS 9.0(包含有最新版本的WM ASF Reader和WM ASF Writer)的发布,WM ASF Reader才真正完全取代了Windows Media Source Filter。下面是典型的使用WM ASF Reader来播放ASF文件的Filter Graph参考图:
理清了上述的版本关系,编写一个播放一般的ASF文件的应用程序,应该没有什么问题了。而播放另外一些特殊的ASF文件,比如经过了DRM (Digital Rights Management)保护的文件,我们还需要提供一些特殊的处理。(更多技术细节请参考SDK中的PlayWndASF例子,这里就不再赘述。)下面,我们要来看一下如何生成我们想要的ASF文件。
上文已经提及,ASF是一个文件“容器”。.asf扩展名是这种格式文件的“统称”,而如果我们生成的Window Media文件只包含音频,我们一般使用.wma扩展名,如果只包含视频、或同时包含音视频,我们一般使用.wmv扩展名。使用WM ASF Writer,有一个重要的概念就是配置(Profile)。通过配置,我们可以设定WM ASF Writer有几个Input pin、生成文件的比特率、压缩质量等等。当WM ASF Writer创建的时候,使用了一个系统默认的配置。如果这个配置不符合我们的具体应用,我们可以通过Filter上的IConfigAsfWriter接口改变配置。有一点需要注意的是,我们在配置WM ASF Writer之前,必须先把它加入到Filter Graph中,而必须等到配置完成后才能进行Pin的连接;运行Filter Graph之前,WM ASF Writer的所有Input pin都要求完成连接,而且各个Input pin上的输入数据要求都是打好时间戳的。还有一个重要的概念需要提醒,WMFS规定,ASF文件必须以音频为基准来播放。所以,一般WM ASF Writer总是需要一个音频的Input pin,即使这个Pin上只是输入一些静音的、低码流的数据。下面是常见的WM ASF Writer三种应用,可供参考:
提示:构建上述Filter Graph,一般有两种切实可行的方法。一种是,一个一个地加入各个Filter,配置WM ASF Writer(如果系统默认配置不符合具体应用时),然后完成整个Filter链路的连接;另一种方法是,使用IGraphBuilder::RenderFile首先构建源文件的播放链路,然后将Renderer Filter从Filter Graph中移除,再加入WM ASF Writer,进行必要的配置后完成最终的连接。
总之,微软提供的WM ASF Reader和WM ASF Writer为ASF在DirectShow中的应用提供了“天然的”支持。我们可以在DirectShow环境下,很方便地开发出ASF的应用程序。