1、gstreamer 的同步机制由如下几个组件组成
2、GstClock
GstClock是精确到纳秒的表示当前时间的一个计数。其值用absolute_time表示。
5、GstBuffer中的时间戳
struct GstBuffer {
/* the parent structure */
GstMiniObject mini_object;
/* pointer to the pool owner of the buffer */
GstBufferPool *pool;
/* timestamp */
/* presentation timestamp of the buffer, can be GST_CLOCK_TIME_NONE
when the pts is not known or relevant. The pts contains the timestamp
when the media should be presented to the user */
GstClockTime pts;
/* decoding timestamp of the buffer, can be GST_CLOCK_TIME_NONE
when the dts is not known or relevant. The dts contains the timestamp
when the media should be processed. */
GstClockTime dts;
/* duration in time of the buffer data, can be GST_CLOCK_TIME_NONE
when the duration is not known or relevant. */
GstClockTime duration;
/* media specific offset */
/* a media specific offset for the buffer data. For video frames, this is the
frame number of this buffer. For audio samples, this is the offset of the first
sample in this buffer. For file data or compressed data this is the byte offset
of the first byte in this buffer */
guint64 offset;
/* the last offset contained in this buffer. It has the same format as offset */
guint64 offset_end;
};
6、segment片段的时间戳
Stream 其实就是媒体数据从产生、搬运、处理再到展示的这么一个过程。典型的stream会以start事件作为开始,紧接着是segment事件,在segment事件中会标示其后所跟buffer的timestamp的范围。在此之后,buffer会源源不断的被逐个传递直到EOS事件结束这个stream。
+-----+-------+ +-++-+ +-+ +---+
|START|SEGMENT| |B||B| ... |B| |EOS|
+-----+-------+ +-++-+ +-+ +---+
segment的结构如下:
延迟(latency)的计算与实现
1、延迟的引入
管道中元素与时钟的同步仅仅发生在各个sink中,如果其他元素对buffer没有延迟的话,那么延迟就为0。延迟的引入主要是基于这样的考 虑,buffer从source推送到sink会花费一定的时间,从而可能导致buffer被丢弃。这个问题一般发生在活动管道,sink被设置为 PLAYING并且buffer没有被预送(preroll)至sink。
2、延迟的实现
一般的解决方案是在被预送(preroll)之前所有的sink都不能设置为PLAYING状态。为了达到这样的目的,管道需要跟踪所有需要预送的元素 (就是在状态改变后返回ASYNC的元素),这些元素发送一个ASYNC_START消息,当元素进行预送,便把状态设置为PAUSED,同时发送一个 ASYNC_DONE消息,该消息恰好与之前的ASYNC_START相对应。当管道收集了所有的与ASYNC_START消息对应的 ASYNC_DONE消息以后便可以开始计算全局延迟了。
3、延迟的计算
GstBus *bus;
/* allocated clock */
GstClock *clock;
GstClockTimeDiff base_time; /* NULL/READY: 0 - PAUSED: current time - PLAYING: difference to clock */
GstClockTime start_time;
struct _GstPipelinePrivate
{
/* with LOCK */
gboolean auto_flush_bus;
/* when we need to update stream_time or clock when going back to
* PLAYING*/
GstClockTime last_start_time;
gboolean update_clock;
GstClockTime latency;
};
struct _GstPipeline {
GstBin bin;
/*< public >*/ /* with LOCK */
GstClock *fixed_clock;
GstClockTime stream_time;
GstClockTime delay;
/*< private >*/
GstPipelinePrivate *priv;
gpointer _gst_reserved[GST_PADDING];
};
struct _GstPipeline {
#define G_TYPE_CHAR G_TYPE_MAKE_FUNDAMENTAL (3)