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