我正在使用一个GStreamer-1.0管道,它通过v4l2src
元素从摄像头读取实时视频,并将数据馈送到appsink
元素。我们对appsink生成的图像执行一些图像处理,生成关于图像内容的数据。
应用程序的另一部分从传感器(例如,加速计)读取数据。
我们需要关联来自两个源的数据的时间戳。我们的传感器数据带有Linux单调时钟时间戳。我们现在需要将其与同时处理的视频帧生成的数据关联起来。
在我们的视频处理线程中,我们可以通过以下方式获取缓冲区的时间戳:
...
g_signal_emit_by_name(appsink, "pull-sample", &sample);
buffer = gst_sample_get_buffer(sample);
timestamp = GST_BUFFER_PTS(buffer);
...
但是GST的时间戳与系统的时钟并不相关,它们似乎是从GST特定的时期(我想是当流水线转换到PLAYING的时候)开始的时间偏移。
当然,我可以在读取帧的同时获得系统时钟并计算差值,但我希望有更好的方法来实现这一点。
- 获取与GST的零时间戳对应的Linux系统单调时钟时间。这样我就可以将此偏移量添加到每个缓冲区的时间戳中。
- 使用一个函数(我在阅读文档时一定漏掉了这个函数)将缓冲区时间戳转换为系统时间戳。
- 将管道或其元素配置为使用系统单调时钟作为缓冲区时间戳。
我尝试了几种不同的方法,但都没有成功,包括:
- 获取系统时钟(
gst_system_clock_obtain
),然后将其clock-type
属性设置为MONOTONIC - 执行上述操作,然后调用
gst_pipeline_use_clock
将其设置为管道的时钟 - 在v4 l2 src对象上调用
gst_base_src_set_do_timestamp
(尝试使用true和false)
有什么想法吗?或者最好的方法是在我从appsink获得缓冲区并计算我自己的delta的同时简单地读取系统时钟?
1条答案
按热度按时间ivqmmu1c1#
我终于找到了解决办法。在内部,GST元件维护一个
base_time
。每次生成一个缓冲区,一个源元件读取它的时钟(通常与流水线的其余部分共享相同的时钟),并从中减去base_time
。当元素转换到
PLAYING
状态时,base_time
被设置为时钟的当前值,因此每个缓冲区的时间戳最终都是元素开始播放后经过的时间。因此,为了实现我的目标,需要两个步骤:
1.创建管道后,将其配置为使用系统单调时钟,而不是与操作系统时钟不同步的其他时钟。
假设
pipe
是指向流水线的指针,这会将其时钟设置为系统单调:1.在管道转换到
PLAYING
状态之后,获取源元素的base_time
值,该值将是与缓冲时间零相对应的系统单调值。假设
vsrc
是指向管道开头的v4l2src
对象的指针,则以下代码(在gst_element_set_state
成功将管道设置为PLAYING
状态后执行)将获取源的base_time
:有了这个值,我现在可以将base_time添加到每个缓冲区的时间戳,以获得对应于缓冲区创建的单调时间: