[英]DirectShow: How to syncronize stream time to system time for video capture devices
我正在创建一个程序,在其中显示一些图形内容,并使用DirectShow使用网络摄像头记录查看器的外观。 知道屏幕上的内容与摄像头记录帧之间的时间差非常重要。
我根本不关心减少延迟或类似的事情,它可以是任何时候,但是我需要尽可能准确地了解捕获延迟 。
当帧进入时,我可以获得帧的流时间 ,但是所有这些帧都是相对于某个特定流开始时间的。 如何获取捕获设备的流开始时间 ? 该值显然在DirectShow的肠子中某处,因为过滤器图针对每一帧进行计算,但是我如何获得它呢? 我已经搜索了文档,但还没有发现它的秘密。
我创建了自己的IBaseFilter IReferenceClock实现类,该类只报告大量调试信息。 那些似乎正在做他们需要做的事情,但是他们没有提供足够的信息。
出于价值考虑,我尝试通过检查DirectShow事件队列来调查此问题,但即使启动图表,似乎也不会触发有关过滤器图表启动的事件。
以下使用测试应用程序记录的图像可能有助于了解我在做什么。 现在的图形内容只是一个计时秒数的计时器。 网络摄像头正在记录屏幕。 在捕获帧的特定时刻,系统时间约为1.35秒左右。 DirectShow中记录的样本时间为1.1862秒(忽略图片中的标题)。 在此示例中,如何计算0.1637秒的差异? 流的开始时间是得出该值的关键。
系统时钟和参考时钟都使用QueryPerformanceCounter()函数,因此我不希望它是计时器的问题。
谢谢。
图形中的过滤器共享参考时钟(除非您将其删除,否则无论如何都不希望如此),并且流时间与该参考时钟的某些基本开始时间有关。 开始时间对应于流时间零。
通常,控制应用程序无权访问此开始时间,因为过滤器图形管理器在内部选择值本身,并作为IBaseFilter::Run
调用中的参数传递给图形中的每个过滤器。 如果您至少拥有一个过滤器,则可以获取该值。
在这种情况下,获取绝对捕获时间是一个简单的数学问题:帧时间是基准时间+流时间,并且您始终可以执行IReferenceClock::GetTime
来检查当前有效时间。
如果您仍然无法开始时间,并且不想在图表中添加自己的过滤器, 则可以使用一个技巧来自己定义基本开始时间。 这就是过滤器图形管理器正在做的事情。
同步启动图形意味着使用
IMediaFilter::Run
而不是IMediaControl::Run
...在所有图形上调用IMediaFilter::Run
,将这段时间作为参数传递。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.