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() 函数,所以我不认为它是定时器异常。
谢谢。
参考时钟:https://msdn.microsoft.com/en-us/library/dd377506(v=vs.85).aspx
如需更多信息,请点击此处:
图表中的过滤器共享参考时钟(除非您将其删除,这不是您想要的)并且流时间是相对于该参考时钟的特定基本开始时间的。开始时间对应于零流时间。
通常情况下,控制应用程序无权访问此开始时间,因为过滤器图形管理器在内部选择值本身并作为 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.
我正在创建一个显示一些图形内容的程序,并使用 DirectShow 通过网络摄像头记录观看者的面部。知道屏幕上的内容与网络摄像头记录帧之间的时间差非常重要。
我根本不关心减少延迟或类似的东西,它可以是任何东西,但我需要尽可能准确地知道捕获延迟可能。
当帧进入时,我可以 get the stream times 个帧,但所有这些帧都 相对于 某个特定的流开始时间。 如何访问捕获设备的流开始时间?这个值显然在 directshow 的内部某个地方,因为过滤器图会为每一帧计算它,但我怎样才能得到它呢?我已经搜索过文档,但还没有发现它的秘密。
我已经创建了自己的 IBaseFilter IReferenceClock 实现 类,它除了报告大量的调试信息外几乎没有其他作用。那些似乎在做他们需要做的事情,但他们没有提供足够的信息。
为了它的价值,我试图通过检查 DirectShow 事件来调查这个问题 Queue,但是似乎没有触发有关过滤器图启动的事件,即使我启动了图。
以下使用测试应用程序录制的图像可能有助于理解我在做什么。现在的图形内容只是一个计时秒的计时器。 网络摄像头正在录制屏幕。在捕获该帧的特定时刻,系统时间约为 1.35 秒左右。 DirectShow 中记录的样本时间为 1.1862 秒(忽略图片中的标题)。 如何解释此示例中 .1637 秒的差异?流开始时间是得出该值的关键。
系统时钟和参考时钟都在使用 QueryPerformanceCounter() 函数,所以我不认为它是定时器异常。
谢谢。
参考时钟:https://msdn.microsoft.com/en-us/library/dd377506(v=vs.85).aspx
如需更多信息,请点击此处:
图表中的过滤器共享参考时钟(除非您将其删除,这不是您想要的)并且流时间是相对于该参考时钟的特定基本开始时间的。开始时间对应于零流时间。
通常情况下,控制应用程序无权访问此开始时间,因为过滤器图形管理器在内部选择值本身并作为 IBaseFilter::Run
调用中的参数传递给图形中的每个过滤器。如果你至少有一个自己的过滤器,你可以得到值。
在这种情况下获得绝对捕获时间是一个简单的数学问题:帧时间是基础时间 + 流时间,您可以随时 IReferenceClock::GetTime
检查当前有效时间。
如果您无权访问开始时间并且不想将自己的过滤器添加到图表中,there is a trick您可以使用自己定义基本开始时间。这就是过滤器图管理器正在做的事情。
Starting the graphs in sync means using
IMediaFilter::Run
instead ofIMediaControl::Run
... CallIMediaFilter::Run
on all graphs, passing this time... as the parameter.