一般筛选器表的生成

要创建一个筛选器表,您要从创建一个筛选器表管理器的实例开始,如下所示:

IGraphBuilder* pIGB;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
    NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
    (void **)&pIGB);

  筛选器表管理器支持下列表生成方法:

  • IFilterGraph::ConnectDirect方法,尝试在两个插头之间建立直接的连接。如果插头无法连接,方法失败。
  • IGraphaBuilder::Connet方法,也可以连接两个插头。它尽可能进行直接连接。如果无法直接连接,它使用中介筛选器来完成连接。
  • IGraphBuilder::Render方法,由一个输出插头启动,生成整个表。此方法添加需要的筛选器,直到到达一个还原筛选器。
  • IGraphBuilder::RenderFile方法,生成一个完整的文件播放器表。它使用IGraphBuilder::AddSourceFilter方法来根据文件的类型添加一个源筛选器,然后使用IGraphBuilder::Render来生成表中的其它部分。
  • IFilterGraph::AddFilter方法,向表添加一个筛选器。它不会将此筛选器连接到其它的筛选器上。应用程序必须首先创建一个筛选器实例,可以使用CoCreateInstance,或者使用筛选器映像和系统设备列举器对象。

  这些方法为生成表提供了三个基本途径:

  1、应用程序指示筛选器表管理器自动生成全部表。

  2、应用程序和表管理器共同完成表生成的工作。

  3、应用程序通过独立的添加和连接每个筛选器,生成整个表。

途径1:筛选器表管理器生成全部表

  当你只是想简单的播放一个文件或某些可识别的格式时(如AVI、MPEG、WAV或MP3),可使用此途径。这个技术在文章<如何播放一个文件>中有示例。在DirectShow中,术语“还原”经常用来代替“播放”,其过程就是在监视器上显示视频数据,或通过系统的喇叭播放音频数据。为了指示筛选器表管理器自动创建一个能还原指定文件的筛选器表,应用程序使用IGraphBuilder::RenderFile方法。(注意,此方法实际上并不会播放文件;它只是生成表。)下面的部分介绍了表管理器建立表的基本步骤:

发现筛选器

  筛选器表管理器的第一步是发现和创建需要的筛选器。它首先根据数据的媒体类型选择筛选器。这是因为两个筛选器,只有它们的插头所处理的媒体类型一致时,这两个插头才能进行连接。筛选器表管理器通过搜索注册表中媒体类型和文件扩展名的组合来确定媒体类型。如.wma、.avi和.wav。如果没有此扩展名的组合,筛选器表管理器搜索文件中特有的“检验字节”。从这些检验字节,能够确定DirectShow媒体类型和相应的源筛选器。在内部,RenderFile方法调用IGraphBuilder::AddSourceFilter来完成这个任务。

  如果发现某个名字对象的源筛选器,可以读取指定类型的文件,筛选器表管理器将使用CoCreateInstance,利用返回的GUID,创建一个筛选器的实例。对于大部分文件类型,源筛选器将作为文件源(同步)筛选器。然后,筛选器表管理器调用IFilterGraph::AddFilter方法将筛选器添加到筛选器表。当筛选器得到添加入表的通知,它会创建一个或多个与将要读取的文件类型相匹配的输出插头。

  在插头创建完成后,表管理器检查每个插头支持的媒体类型,然后再次查看注册表,寻找筛选器,这个筛选器要能够访问输入插头的媒体类型。当它发现一个合适的筛选器,就将它添加到表中。所有的DirectShow筛选器在Windows注册表中都具有唯一的标识GUID,与GUID同时存储着其它信息,包括筛选器的种类、把持的媒体类型和merit。筛选器表管理器使用这些信息来确定要创建哪一个筛选器。

 种类标识了筛选器的一般功能,用于限制搜索范围。

 媒体类型描述了哪种类型的数据可以被筛选器访问,做为输入,哪种类型的数据可以发送,做为输出。

 merit值表示在自动表生成过程中,是否应该考虑此筛选器。如果系统中有两个筛选器具有相似的媒体类型信息,筛选器表管理器就会选择merit值较高的那个。某些筛选器特意给出一个较低的merit值,因为它们是为专用的筛选器表设计的。这种筛选器必须由应用程序单独的添加到表中。

  为了搜索注册表,筛选器表管理器会创建一个DirectShow Filter Mapper对象的实例,并调用IFilterMapper2::EnumMatchingFilters方法来执行搜索。这个方法从媒体类型、插头数目、merit和其它条件与DirectShow筛选器进行匹配。它返回一个标准的COM IEnumMoniker对象,其中包含了符合搜索条件的所有筛选器的名字对象。(名字对象的使用使这个方法能在不创建实例的情况下就能查询对象,并且列举出来的并不一定是真正的COM对象,如硬件设备。)

连接筛选器

  当每个筛选器进行添加时,它会配置自己的插头,并做好连接上一个筛选器(上游筛选器)的准备。筛选器表管理器调用IGraphBuilder::Connect方法,连接上游筛选器的输出插头和下游筛选器的输入插头。两个插头互相沟通以确认连接的媒体类型,并确定由哪个插头提供内存分配对象。

完成表

  两个插头连接完成后,筛选器表管理器检查新的筛选器输出插头支持的媒体类型,并搜索能够处理此媒体类型的筛选器。这个过程重复进行,直到所有需要的筛选器都被加入到表中。在一个文件播放表中,第二个筛选器一般是分解筛选器,它读取未加工的数据流,如AVI或MPEG,然后分解为音频流和视频流,并为每个流创建输出插头。如果流中的数据是压缩的,流的下一个筛选器就是解压缩器,再后面是一个还原器。

  表生成以后,应用程序只需要从筛选器表管理器获得IMediaControl接口,然后调用IMediaControl::Run方法,就可以开始播放文件了。

途径2:应用程序和筛选器表管理器共同完成表生成工作

  除了简单的还原文件外,如果还要做其它的事情,就需要您的应用程序至少做一些表生成的工作了。例如,如果你想生成一个将AVI文件转换为ASF文件的筛选器表,您仍然可以调用IGraphBuilder::RenderFile来让筛选器表管理器创建一个AVI播放表,但是后面您必须修改这个表,以输出一个ASF文件。这个需要断开连接,移除视频音频还原器(通过调用IFilterGraph::RemoveFilter),并用ASF写筛选器来替代它们。

  还有一件必须要做的事是添加一个中介筛选器,用以将流从一种媒体类型转换为另一种类型。应用程序可以直接添加中介筛选器,或者使用IGraphBuilder::Connet方法。当调用此方法时,筛选器表管理器首先尝试直接连接筛选器,如果不能统一媒体类型,管理器将搜索中介筛选器。只要表管理器找到一能够处理给定媒体类型的筛选器,它先尝试与已经被添加到表中的筛选器进行连接。要禁止表管理器插入中介筛选器,请使用IFilterGraph::ConnetDirect方法。

  在上例中,应用程序生成表的下游一部分。在其它情况下,应用程序可能需要生成表的上游部分。此时,一旦您已经添加并连接好必须手工添加的部分,就可以使用IGraphBuilder::Render方法来指示表管理器从指定输出插头完成表的其它部分。如果一个筛选器有多于一个的输出插头,应用程序必须为每个插头调用Render。

途径3:应用程序自己生成整个表

  在有些情况下,您的应用程序也许需要独立添加和连接每个筛选器,生成整个表。此时,您可能特别了解哪些筛选器应当被加入表中,因此不需要使用筛选器映像对象来探索筛选器。可使用AddFilter方法向表中添加筛选器,然后使用Connect或ConnectDirect将它们进行连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值