我正在创建一个程序,在其中显示一些图形内容,并使用DirectShow使用网络摄像头记录查看器的面部。非常重要的是,我知道屏幕上的内容与网络摄像头记录帧时之间的时差。
我根本不关心减少延迟或类似的事情,它可能是它会发生什么,但我需要尽可能准确地知道捕获延迟。
当帧进入时,我可以get the stream times帧,但所有这些帧相对到某个特定的流开始时间。 如何访问捕获设备的流启动时间?这个值显然位于directshow的内部,因为过滤器图形为每一帧计算它,但我怎样才能得到它?我已经搜索了文档,但还没有发现它的秘密。
我已经创建了自己的IBaseFilter IReferenceClock实现类,它只是报告大量的调试信息。那些似乎正在做他们需要做的事情,但他们没有提供足够的信息。
对于它的价值,我试图通过检查DirectShow事件队列来调查这一点,但是即使我启动图表,似乎也没有触发有关启动过滤器图的事件。
使用测试应用程序记录的以下图像可能有助于了解我正在做什么。现在的图形内容只是计算秒数的计时器。 网络摄像头正在录制屏幕。在捕获帧的特定时刻,系统时间约为1.35秒左右。在DirectShow中记录的样本时间是1.1862秒(忽略图中的标题)。 如何在此示例中说明.1637秒的差异?流启动时间是获取该值的关键。
系统时钟和参考时钟都使用QueryPerformanceCounter()函数,所以我不希望它是计时器难以理解。
谢谢。
答案 0 :(得分:2)
图表中的过滤器共享参考时钟(除非您将其删除,这不是您想要的)并且流时间相对于此参考时钟的某个基本开始时间。开始时间对应于流时间为零。
通常,控制应用程序无权访问此开始时间,因为过滤器图形管理器在内部选择值本身并作为IBaseFilter::Run
调用中的参数传递给图形中的每个过滤器。如果您拥有自己的至少一个过滤器,则可以获得该值。
在这种情况下获得绝对捕获时间是一个简单的数学问题:帧时间是基准时间+流时间,你总是可以IReferenceClock::GetTime
来检查当前的有效时间。
如果您无法获得开始时间,并且您不想将自己的过滤器添加到图表中,there is a trick您可以自己定义基本开始时间。这就是过滤器图形管理器正在做的事情。
启动图表同步意味着使用
IMediaFilter::Run
代替IMediaControl::Run
...在所有图表上调用IMediaFilter::Run
,将此时间传递给参数。
答案 1 :(得分:0)
参考时钟:https://msdn.microsoft.com/en-us/library/dd377506(v=vs.85).aspx
有关详细信息,请访问: