DirectShow:如何将视频捕获设备的流时间同步到系统时间

DirectShow: How to syncronize stream time to system time for video capture devices

我正在创建一个显示一些图形内容的程序,并使用 DirectShow 通过网络摄像头记录观看者的面部。知道屏幕上的内容与网络摄像头记录帧之间的时间差非常重要。

我根本不关心减少延迟或类似的东西,它可以是任何东西,但我需要尽可能准确地知道捕获延迟可能。

当帧进入时,我可以 get the stream times 个帧,但所有这些帧都 相对于 某个特定的流开始时间。 如何访问捕获设备的流开始时间?这个值显然在 directshow 的内部某个地方,因为过滤器图会为每一帧计算它,但我怎样才能得到它呢?我已经搜索过文档,但还没有发现它的秘密。

我已经创建了自己的 IBaseFilter IReferenceClock 实现 类,它除了报告大量的调试信息外几乎没有其他作用。那些似乎在做他们需要做的事情,但他们没有提供足够的信息。

为了它的价值,我试图通过检查 DirectShow 事件来调查这个问题 Queue,但是似乎没有触发有关过滤器图启动的事件,即使我启动了图。

以下使用测试应用程序录制的图像可能有助于理解我在做什么。现在的图形内容只是一个计时秒的计时器。 网络摄像头正在录制屏幕。在捕获该帧的特定时刻,系统时间约为 1.35 秒左右。 DirectShow 中记录的样本时间为 1.1862 秒(忽略图片中的标题)。 如何解释此示例中 .1637 秒的差异?流开始时间是得出该值的关键。

系统时钟和参考时钟都在使用 QueryPerformanceCounter() 函数,所以我不认为它是定时器异常。

谢谢。

尝试IReferenceClock::GetTime

参考时钟:https://msdn.microsoft.com/en-us/library/dd377506(v=vs.85).aspx

如需更多信息,请点击此处:

https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/1dc4123a-05cf-4036-a17e-a7648ca5db4e/how-do-i-know-current-time-stamp-referencetime-on-directshow-source-filter?forum=windowsdirectshowdevelopment

图表中的过滤器共享参考时钟(除非您将其删除,这不是您想要的)并且流时间是相对于该参考时钟的特定基本开始时间的。开始时间对应于零流时间。

通常情况下,控制应用程序无权访问此开始时间,因为过滤器图形管理器在内部选择值本身并作为 IBaseFilter::Run 调用中的参数传递给图形中的每个过滤器。如果你至少有一个自己的过滤器,你可以得到值。

在这种情况下获得绝对捕获时间是一个简单的数学问题:帧时间是基础时间 + 流时间,您可以随时 IReferenceClock::GetTime 检查当前有效时间。

如果您无权访问开始时间并且不想将自己的过滤器添加到图表中,there is a trick您可以使用自己定义基本开始时间。这就是过滤器图管理器正在做的事情。

Starting the graphs in sync means using IMediaFilter::Run instead of IMediaControl::Run... Call IMediaFilter::Run on all graphs, passing this time... as the parameter.