在DirectShow框架中,应用程序使用DirectShow提供的方法完成需要的功能,这些方法被称为接口。所有的DirectShow都提供IBaseFilter接口,所有的Pin也都提供IPin接口。DirectShow也定义了许多其他的接口以实现特定的功能。应用程序就是通过调用这些接口,来使用DirectShow的功能,完成数据的控制和处理过程。
数据流概述
数据是以简单字节数组的形式被保存在缓冲区里的。每一个缓冲区被COM对象媒体样本所包装,媒体样本实现IMediaSample。样本由COM对象分配器创建,可以提高资源利用率,分配器实现IMemAllocator接口。每一个Pin连接都指定一个媒体分配器,但是两个或多个PIn连接也可以共享分配器。其关系如下图所示。
每一个分配器都创建了一个媒体样本池,并为每个样本分配缓冲区。一旦一个Filter需要一个缓冲区来填充数据,它调用IMemAllocator::GetBuffer方法从分配器申请一个样本。只要分配器还有没有被其他Filter使用的样本,GetBuffer方法就立即返回一个样本的指针。如果分配器的所有样本已经用完,GetBuffer就阻塞在那里,直到有一个样本变为可用。当GetBuffer返回一个样本后,Filter就将数据写入到样本的缓冲区中去,并在样本上设置适当的标识位(如时间戳),然后将样本传递到下一个Filter去。
上图只显示了一个分配器,但是通常的情况下,每个链路中都会有多个分配器。因此,当Render Filter释放了一个样本时,它会产生一个级联效应,如下图所示:
Decoder Filter保存了一个视频压缩帧,并正在等待Renderer Filter释放一个样本,而Parser Filter也正在等Decoder Filter去释放一个样本。当Render Filter释放了一个样本后,Decoder Filter完成阻塞的GetBuffer调用。于是Decoder Filter对压缩的视频帧进行解码,然后再释放它保存的样本,从而使Parser阻塞的GetBuffer调用得以完成。
传输协议
为了使媒体数据能在Filter Graph中传输,DirectShow Filter必须能支持多个协议中的一个,这些协议被称作传输协议。当两个Filter连接时,它们必须支持同一个传输协议,否则,它们将不能交换数据,通常,一个传输协议要求某个Pin支持一个特定的接口,当两个Filter连接时,一个Pin查询另一个Pin的这个接口。
Filter在主内存中保存媒体数据,并且通过Pin连接向另一个Filter传输数据,这种类型的传输协议被称作本地内存传输协议。尽管本地内存传输协议是在DirectShow中使用最普遍的协议,但并非所有的Filter都使用它。
DirectShow为本地内存传输协议定义了两种机制,推(push)模式和拉(pull)模式。在推模式中,Source Filter产生数据,并递交给下游Filter。下游Filter被动地接收并处理数据,然后再将数据传递给它的下游Filter。在拉模式中,Source Filter与一个Parser Filter相连,Parser Filter向Source Filter请求数据,Source Filter通过传递数据来回应请求。推模式使用IMemInputPin接口,而拉模式使用IAsyncReader接口。推模式比拉模式应用更广泛。
程序编写
DirectShow由于其良好的架构,清晰的设计思路,使其程序开发具有良好的规律性和通用性。
开发DirectShow应用程序,一般有三个阶段,第一阶段创建一个Filter Graph Manager组件;第二阶段,根据实际的应用,创建一条完整的Filter链路;第三阶段,调用Filter Graph Manager上(或者直接在某个Filter上)的各个接口进行控制,并且完成Filter Graph Manager与应用程序的事件交互。当进程结束时,应用程序需要释放Filter Graph Manager和所有的Filter。
DirectShow基于COM,其中的Filter Graph Manager和所有的Filter都是COM对象。在应用程序使用DirectShow之前必须初始化COM库,在程序退出之前同样需要反初始化COM库,释放COM库占用的资源。所以DirectShow程序员必须对COM客户端编程有所了解。
如果DirectShow和其他以安装的Filter不能满足程序的设计要求,那么程序员还必须开发自己的Filter。
GraphEdit介绍
GraphEdit是一个用来建立Filter Graph的可视化工具,它可以在编程前对Filter Graph进行仿真。同时GraphEdit也可以导入应用程序产生的Filter Graph,用以检验应用程序是否建立了正确的Filter Graph。如果是开发自己的Filter,通过GraphEdit就可以快速的检验这个Filter。同时GraphEdit也是DirectShow新手入门的一个好工具,它可以尽快的熟悉Filter Graph和DirectShow框架。
GraphEidt包含以下功能:
·使用一个可视化的界面,建立和修改Filter Graph
·模仿程序命令建立Filter Graph,像IGraphBuilder::RenderFile;
·运行、暂停、停止或检索Filter Graph
·查看在计算机上注册的Filter和它们的注册信息
·查看Filter属性页
·查看Pin连接的媒体类型
参考:
https://www.yuque.com/docs/share/fce2da31-9626-43e5-bd2a-38c3892105ac