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

时间:2017-04-15 04:03:01

标签: c++ video webcam directshow

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

我根本不关心减少延迟或类似的事情,它可能是它会发生什么,但我需要尽可能准确地知道捕获延迟

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

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

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

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

系统时钟和参考时钟都使用QueryPerformanceCounter()函数,所以我不希望它是计时器难以理解。

Shot captured by the webcam

谢谢。

2 个答案:

答案 0 :(得分:2)

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

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

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

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

  

启动图表同步意味着使用IMediaFilter::Run代替IMediaControl::Run ...在所有图表上调用IMediaFilter::Run,将此时间传递给参数。

答案 1 :(得分:0)