【问题标题】:DirectShow: How to syncronize stream time to system time for video capture devicesDirectShow:如何将系统时间与视频捕获设备的系统时间同步
【发布时间】:2017-04-15 04:03:01
【问题描述】:

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

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

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

我创建了我自己的 IBaseFilter IReferenceClock 实现类,它只报告大量调试信息。这些似乎在做他们需要做的事情,但他们没有提供足够的信息。

对于它的价值,我试图通过检查 DirectShow 事件队列来对此进行调查,但似乎没有触发有关过滤器图启动的事件,即使我启动了图表。

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

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

谢谢。

【问题讨论】:

    标签: c++ video webcam directshow


    【解决方案1】:

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

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

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

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

    同步启动图意味着使用IMediaFilter::Run 而不是IMediaControl::Run...在所有图上调用IMediaFilter::Run,传递这个时间...作为参数。

    【讨论】:

    • 在 IMediaFilter 中设置参考时间并不能完成这项工作,但它似乎与我将得到的一样接近。在演示时间中未显示的某处存在一些缓冲。
    【解决方案2】:

    【讨论】:

    • 没有一个 IReferenceClock 方法是足够的。我正在使用与系统时钟同步的参考时钟,但这并没有起到作用,因为过滤器图将其相对基准时间设置为未知的。
    • 你试过设置SetSyncSource(NULL); ? msdn.microsoft.com/en-us/library/windows/desktop/…
    • 没有参考时钟没有帮助。在那种情况下,我的传入样本没有流时间,因此计算偏移量的信息更少。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多