本文主要是介绍《DirectShow开发指南》学习笔记_6,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
动态重建技术
由于下列任何一个原因,我们都需要对已有的Filter Graph进行修改。
- 应用程序在播放一段视频的过程中想要插入一个视频效果Filter;
- Source Filter在运行过程中改变了数据流的媒体类型,需要接入新的解码Filter;
- 应用程序想要在Filter Graph中加入另外一条视频流。
通常的做法是,现将Filter Graph停止,进行修改之后,再重新启动。那么,有没有一种方法能够在保持Filter Graph运行状态的同时实现Filter Graph的重建呢?答案是肯定的。
Filter Graph的重建包括如下几种情形:
- 仅仅改变Filter之间连接媒体类型;
- 增加或删除Filter,重新进行相关Filter之间的连接;
- 对一条Filter链路(Filter Chain)进行操作。
媒体类型的动态改变
当两个Pin连接完成后,就会有一个双方商定的媒体类型用来描述以后在这两个连接Pin之间传递的数据格式。一般情况下,这个媒体类型在Filter Graph运行的整个过程中是不会改变的。但在一些特殊的场合下,“需要”这种媒体类型的动态改变。DirectShow是如何支持的呢?下面分不同情况来讨论。
从上往下要求媒体类型改变,但传送数据使用的内存不需增大
媒体类型的改变由Filter A的输出Pin发起。首先,Filter A调用Filter B的输入Pin上的IPin::QueryAccept或IPinConnection::DynamicQueryAccept,看Filter B是否支持新的媒体类型,如果支持,则Filter A调用IMemAllocator::GetBuffer得到一个空的Sample,通过IMediaSample::SetMediaType将新的媒体类型与Sample相连。然后,Filter A就可以将Sample传送给Filter B。当Filter B接收到新的Sample时,可以通过调用IMediaSample::GetMediaType得到新的媒体类型。
一般来说,Filter B应该具有对媒体类型改变的应变能力,这是在写自己的Filter时应该考虑到的问题。Filter A一般调用QueryAccept来判断Filter B的输入Pin是否支持新的媒体类型。可以从CBasePin::QueryAccept的实现中看到,它仅仅是调用Pin上的CheckMediaType函数。所以QueryAccept返回S_OK并不能保证媒体类型能够在Graph运行状态下改变成功。
这篇关于《DirectShow开发指南》学习笔记_6的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!