1、gstreamer 的同步机制由如下几个组件组成
- GstClock,是全局的,用于pipeline中的所有elements。
- GstBuffer的timestamps。
- buffers之前的NEW_SEGMENT event。
2、GstClock
GstClock是精确到纳秒的表示当前时间的一个计数。其值用absolute_time表示。
- 系统时钟,精度是微妙。(gstSystemClock)
- 音频设备时钟,精度是纳秒。(gstAudioClock)
- 网络时钟,(GstRtpClock、GstNetClientClock)
- 其它任何element提供的时钟。
选择时钟源
- 从媒体流的最上(most upstream)开始选择一个可以提供时钟的元素;
- 如果管道中所有元素都不能提供时钟,则采用系统时钟。
时钟发布
为了同步不同的元素,管道需要负责为管道中的所有元素选择和发布一个全局的时钟。
时钟发布的时机包括:
时钟发布的时机包括:
- 管道进入PLAYING状态;
- 添加一个可以提供时钟的元素;
- 发送一个GST_MESSAGE_CLOCK_PROVIDE消息——>bus——>通知父bin——>选择一个clock——>发送一个NEW_CLOCK消息——>bus;
时钟移除
发送一个CLOCK_LOST消息——>PAUSED——>PLAYING
3、running_time
pipeline会维护一个基于选定时钟的running_time,running_time指的是pipeline处于Playing运行状态时的时间总和,
计算方法如下:
上述的计算方法在pipeline的状态从Playing状态设定为Pause状态时记录running_time,当从Pause状态转变为Playing状态后基于absolute_time恢复running_time。针对Pause后继续计数的clock,比如system clock,以及Pause后不再计数的clock,比如audioclock都是适用的。
- 如果pipeline处于NULL或者READY状态则running_time处于undefined。
- PAUSE状态下,running_time的值保持不变,如果处于刚开始启动时的PAUSE状态,running_time的值为0。
- flushing seek之后,running_time被置为0。这需要向所有被flush的elemnt指定一个新的base_time。
上述的计算方法在pipeline的状态从Playing状态设定为Pause状态时记录running_time,当从Pause状态转变为Playing状态后基于absolute_time恢复running_time。针对Pause后继续计数的clock,比如system clock,以及Pause后不再计数的clock,比如audioclock都是适用的。
running_time = absolute_time - base_time;
如果pipeline采用系统时钟,由于系统时钟一直都在变,即absolute_time在变,pause状态时running_time不变,则base_time=absolute_time-running_time,此时base_time会变;
如果pipeline采用的audioclock,absolute_time会根据输出的sample数来计算,所以pause状态时不会变,又pause状态时running_time不变,则base_time=absolute_time-running_time,此时base_time也不会变;
4. stream time
Stream time 可理解为在stream中的位置,其值介于零和媒体文件总长度之间。
stream time可以用于:
- 响应POSTION query;
- seek中的位置;
5、GstBuffer中的时间戳
- struct GstBuffer {
- /* the parent structure */
- GstMiniObject mini_object;
-
- /* pointer to the pool owner of the buffer */
- GstBufferPool *pool;
-