在一个 GstPipeline 中,实现sync同步播放是通过以下三个对象实现的:

  1. GstClock 它对整个管道的所有GstElement->clock都是同一个。

  2. GstBuffer 的PTS和DTS.

  3. 视频流开始前的 segment 事件。

基本概念

绝对时间absolute time(对应图中clock time): 通过 gst_clock_get_time 获取的当前时间,有时也称now

运行时间running time: 表示在 PLAYING 状态下花费的总时间。

  • 如果管道处于 NULL/READY 状态,running time 是未定义的。

  • 如果是 PAUSED 状态下, running time 保持在最后一次暂停时刻运行时间。当流第一次进入暂停状态时,running time为0.

  • PLAYING 状态下,running time = absolute_time - base_time (播放中间暂停,base_time会累加暂停时间差)

流时间stream time: 此时播放流的位置(这个时间不用于sync)

alt text

1 GstElement

alt text

  • clock: 这里的时钟对象使用的是 GST_TYPE_SYSTEM_CLOCK 类型对象,获取的时钟是系统运行时间。具体可以参考 GstClock 部分。

  • base_time: NULL和READY状态时候为0,暂停状态的时候就等于当前系统运行时间。播放状态就是开始运行那一刻的时间。(running time = now - base_time)

    • 第一次暂停的时候该值也为0,第一次播放状态的时候 base_time = gst_clock_get_time (clock) 时钟的当前时间。

    • 中间暂停的时候,暂停了多久(当前时刻 - 开始暂停时刻)。base_time = base_time + 暂停的时间差 alt text

  • start_time: 是指元素最后一次处于 PAUSED 状态时的 running_time,这个时间值表示当元素从 PAUSED 状态恢复到 PLAYING 状态时,从哪个时间点继续运行。它确保元素在暂停后能从正确的时间点继续播放,而不是重新开始。

    • 第一次暂停的时候该值也为0,第一次播放的时候 start_time = 0 (最后一次处于暂停时候running time)

    • 中间暂停的时候,等于 running time. alt text

2 GstBuffer

alt text

运行示例程序:02_GstBuffer渲染和解码时间.c 我们播放的视频流每秒是30帧。

alt text

3 GstBaseSink

3.1 视频和音频的sink如何同步

通过 GstBuffer 的PTS或者DTS,GstBaseSink会做同步阻塞等待。

3.2 一个管道多个sink,存在sink未连接

只对其中的元素进行Playing设置状态,就可以正常播放。

参考

参考1:官网Synchronisation

参考2:官网Clocks and synchronization in GStreamer