我使用优秀的GMFBridge directshow family of filters效果很好,允许我关闭视频录制图并打开一个新的,没有数据丢失。
我的原始源图是从标准视频和音频输入中捕获实时视频。
在GMFBridgeController
过滤器上有一个名为SetLiveTiming()
的无证方法。从名称来看,我认为如果我们从实时图形(而不是从文件中)捕获这应该设置为true
,就像我的情况一样。我将此值设置为true
,一切都按预期工作
相同的捕获硬件允许我捕获实时电视信号(在我的情况下是ATSC),因此我使用BDA架构过滤器创建了新版本的图形,用于调整目的。一旦数据从MPEG分路器流出,图表的其余部分几乎与我的原始图形相同。
但是,在这个问题上,我的复用图(在桥的另一边)没有工作。数据从BridgeSource
滤波器(视频和音频)流出并到达MP4复用滤波器,但没有数据从多路复用器输出流入FileWriter
滤波器。
几个小时后,我将问题追溯到SetLiveTiming()
设置。我关掉了
一切都按预期开始了。
并且muxer过滤器开始生成输出文件,但音频未与视频同步。
有人可以启发我关于SetLiveTiming()
设置的真正目的,也许,为什么一个图表可以启用设置,而另一个图表失败?
UPDATE
我设法编译了GMFBridge项目,并且 由于负时间戳计算,似乎过滤器正在丢弃每个接收到的样本。但是,在启用过滤器日志后,我对结果感到非常困惑。
更新2:通过我启动辅助(muxer)图表的方式引入了丢弃的样本。我使用SampleGrabber(因此在流线程内)作为触发点检查了一个样本,并使用Task.Run()
.NET调用来实例化muxer图。这不知怎么搞砸了时钟,我结束了将来有一个'参考起点' - 当桥试图通过减去参考起点来修复时间戳时,它产生了一个负时间戳 - 一旦我纠正了这个并产生了图表,应用程序线程(通过发布图形事件),问题得到解决。
不幸的是,我的多路复用视频(无论SetLiveTiming()
设置如何)仍然不同步。
我读到GMFBridge filter can have trouble when the InfTee filter is being used,但是,我认为我的图表不应该有这个问题,因为没有InfTee过滤器的实例直接连接到桥接器。
这是我目前的源图:
-->[TIF]
|
[NetworkProvider]-->[DigitalTuner]-->[DigitalCapture]-->[demux]--|-->[Mpeg Tables]
|
|-->[lavAudioDec]-->[tee]-->[audioConvert]-->[sampleGrabber]-->[NULL]
| |
| |
| ->[aacEncoder]----------------
| |--->[*Bridge Sink*]
-->[VideoDecoder]-->[sampleGrabber]-->[x264Enc]--------
这是我的muxer图:
video
... |bridge source|-------->[MP4 muxer]--->[fileWriter]
| ^
| audio |
---------------------
图中的所有样本采集器都是只读的。如果我在没有桥接的情况下复制输出文件(通过将复用器放在捕获图上),输出文件保持同步(这结果不是真的,H264编码器中的延迟设置引入了不同步问题) )然后我不能避免在释放当前捕获图和运行新图之间丢失一些秒(使用更新的文件名)
更新3:
几天前,当我关闭x264vfw编码器中的“零延迟”设置时,我无意中引入了不同步问题。我没有注意到这个设置已经使我已经工作的图表失去了同步,我正在责备桥接过滤器。
总之,我搞砸了以下事情:
作者的评论:
// using this option, you can share a common clock
// and avoid any time mapping (essential if audio is in mux graph)
[id(13), helpstring("Live Timing option")]
HRESULT SetLiveTiming([in] BOOL bIsLiveTiming);
该方法启用了一种解决实时数据的特殊操作模式。在此模式下,采样时间在图表之间相对于相应的时钟开始时间进行转换。否则,默认模式是期望在图形更改时将时间戳重置为零。