如何将GStreamer缓冲区时间戳与Linux系统时钟相关联

nnsrf1az  于 2022-11-22  发布在  Linux
关注(0)|答案(1)|浏览(245)

我正在使用一个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的同时简单地读取系统时钟?

ivqmmu1c

ivqmmu1c1#

我终于找到了解决办法。在内部,GST元件维护一个base_time。每次生成一个缓冲区,一个源元件读取它的时钟(通常与流水线的其余部分共享相同的时钟),并从中减去base_time
当元素转换到PLAYING状态时,base_time被设置为时钟的当前值,因此每个缓冲区的时间戳最终都是元素开始播放后经过的时间。
因此,为了实现我的目标,需要两个步骤:
1.创建管道后,将其配置为使用系统单调时钟,而不是与操作系统时钟不同步的其他时钟。
假设pipe是指向流水线的指针,这会将其时钟设置为系统单调:

GstClock *clock = gst_system_clock_obtain();
g_object_set(clock,
             "clock-type", GST_CLOCK_TYPE_MONOTONIC,
             NULL);
gst_pipeline_use_clock(GST_PIPELINE_CAST(pipe), clock);
gst_object_unref(clock)

1.在管道转换到PLAYING状态之后,获取源元素的base_time值,该值将是与缓冲时间零相对应的系统单调值。
假设vsrc是指向管道开头的v4l2src对象的指针,则以下代码(在gst_element_set_state成功将管道设置为PLAYING状态后执行)将获取源的base_time

GstClockTime base_time;

base_time = gst_element_get_base_time(vsrc);

有了这个值,我现在可以将base_time添加到每个缓冲区的时间戳,以获得对应于缓冲区创建的单调时间:

...
g_signal_emit_by_name(appsink, "pull-sample", &sample);
buffer = gst_sample_get_buffer(sample);
buffer_ts = GST_BUFFER_PTS(buffer);
monotonic_ts = buffer_ts + base_time;

printf("Buffer TS: %" GST_TIME_FORMAT
       " is monotonic TS: %" GST_TIME_FORMAT "\n",
       GST_TIME_ARGS(buffer_ts),
       GST_TIME_ARGS(monotonic_ts));
...

相关问题