通常在过滤器图形上执行搜索命令,在图形中的渲染器上调用,并通过过滤器向上游传递调用,直到可以处理搜索的过滤器执行实际的搜索操作。
单个滤波器是否可以以相同的方式寻找连接到其一个或多个输入引脚的上游滤波器,而不会以意外的方式影响图形的下游部分?我不希望在上游调用IMediaSeeking.SetPositions时不会出现任何图形状态变化。
我假设所有上游过滤器仅通过此过滤器连接到图表的其余部分。
显然,需要准备过滤器以适当地处理来自上游的结果BeginFlush,EndFlush和NewSegment调用,并区分在搜索操作之前和之后到达的样本。还需要在其输出样本上设置新的采样时间,以便输出样本具有一致的样本呈现时间。还有其他问题吗?
答案 0 :(得分:2)
完成你所需的工作是完全可行的。我使用这种方法为视频编辑器构建视频和音频混合器过滤器。有关该代码的完整说明,请参阅http://www.bbc.co.uk/rd
提供的BBC白皮书129和138如果您搜索AAFEditPack,可以在www.SourceForge.net上找到相当古老的代码版本。代码使用DSPack在Delphi中编写,以访问DirectShow头文件。我这样做是因为它可以更容易地处理com对象的生命周期 - 默认情况下通过实现智能指针。如果您正在使用它,那么将想法转移到C ++实现应该相当简单。
过滤器保留子图的列表(图表的一部分,但在与混音器相同的FilterGraph中运行)。这些过滤器实现了TBCPosPassThru的自定义版本,该版本了解每个媒体剪辑的子图的输出引脚。它处理传递搜索命令以在达到时间线中的点时使每个剪辑准备好重放。混音器为每个子图处理BeginFlush,EndFlush,NewSegment和EndOfStream调用,以便他们保持高兴。编辑器只使用一个包含视频和音频图形的FilterGraph。寻求命令由视频和音频渲染器上的图形组成,这些命令被上游传递给实现它们的混音器。
当前未激活的子图由混合器阻止,这些子图保持对它们已传送的样本的引用。这不会给FilterGraph带来任何问题,因为正如Roman R所说,下游过滤器只关心获取连续的样本流而不知道上游会发生什么。
确保避免浪费调试时间所需的一些关键点是:
您的解码器过滤器需要能够排队到确切的媒体帧或音频时间。并不像你想象的那么容易,尤其是压缩格式,如mpeg2,它是专为传输而设计的,文件中没有帧索引。如果您不这样做,过滤器可能会无限期地等待以正确的媒体时间进行NewSegment调用。
您的子图需要在传送样本之前显示一个NewSegment时间,该时间等于您在seek命令中要求的值。有些解码器可能会寻找最近的关键帧,这有点无用,而且有些解码器的NewSegment和后续样本的时序有些随意。
每个剪辑的开始和停止时间必须在文件的持续时间内。在DirectShow过滤器中对此进行警告可能不是一个好主意,因为您可能希望构建时间轴而无需先运行过滤器。我在管理FilterGraph的组件中做到了这一点。
如果您想在时间轴中连续添加来自同一源文件的部分,并且具有跨越转换的效果,则需要为该文件提供两个子图实例,如果您有超过对于同一源文件的一个转换,您的列表需要交替连续剪辑的图形。这是因为每个子图应该只是单调播放:调用大量的SetPosition调用会浪费cpu周期,并且不能很好地处理压缩文件。
滤波器的输出引脚定义了图形的整个搜索行为。输出样本时间戳(IMediaSample.SetTime)由过滤器实现,因此您需要使它们更正,而不会丢失任何时间戳。如果您愿意,也可以设置MediaTime(IMediaSample.SetMediaTime)值,尽管您必须小心使它们正确或图形可能会丢失样本或停止。
祝你的发展顺利。如果您需要更多信息,请通过StackOverflow或DTSMedia.co.uk与我联系