gst看一下2

set_state能发送给管道中所有元件的change_state函数
每个元件的change_state函数中都会调用parent_class的change_state,
playbin--(parent)-->playbasebin
playbasebin--(parent)-->pipeline
pipeline--(parent)-->bin
最上一级是bin, bin的change_state函数,

while (!done) {
gpointer data;

switch (gst_iterator_next (it, &data)) {
case GST_ITERATOR_OK:
{
GstElement *child;

child = GST_ELEMENT_CAST (data);

/* set state and base_time now */
ret = gst_bin_element_set_state (bin, child, base_time, current, next);

把bin里的元件一个个取出来发送set_state命令,这样所有元件都会改变状态了

gstclock获得时钟的3种方式
1 systemclock系统时钟
2 音频设备 基于采样率而知道的时钟
3 网络包中包含的时钟信息

我只 过systemclock, gstclock->gstsystemtclock->g_get_current_time->gettimeofday->(system call)

音视频时间同步到系统时间
并不是音频和视频谁同步谁,而是大家都跟系统时间同步
NS...B...B...EOS NS=new segment
C.running_time = absolute_time - base_time (系统)
B.running_time = (B.timestamp - NS.start)/NS.abs_rate + NS.accum (元件)
同步就是让B,C的running_time相等, B等待
base_time从NEW_SEGMENT事件发出为基准,比如seek后就是NEW SEGMENT

_class_init给klass挂函数指针

gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass)
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gstbasesink_class = (GstBaseSinkClass *) klass;
把一个klass转换为3种数据结构,可以的原因是一级级都是数据结构的第一个成员,传进来的kclass是最大的数据结构,往小转当然可以

struct _GstBaseAudioSink {
GstBaseSink element;

struct _GstBaseSink {
GstElement element;

struct _GstElement
{
GstObject object;

状态变迁
NULL-->READY
1 probe device
2 open device

READY-->PAUSED
1 激活pad,返回ASYNC,然后起stream thread线程才把状态改变的事情做完,直到sink pad收到first buffer,阻塞住,这时才真正算状态改变完,用get_state可以查询到
2 管道running_time归零
3 如果是live source返回NO_PREROLL,不产生数据(live source是即使暂停也会产生数据的源,比如net和camera)

PAUSED-->PLAYING (大部分元件忽略这个状态)
1 管道选择时钟分发到每个子元件,也就是同步时钟只发生在PLAYING时
2 管道把clock running_time计算出来的base_time分发到每个子元件(change_state时)
3 sink衬垫不再阻塞buffer/event,开始render数据
4 live source开始产生数据

PLAYING-->PAUSED (大部分元件忽略这个状态)
1 如果sink此时无buffer在手一定要等收到buffer才能完成状态改变。 上面的READY->PAUSED也是sink在进入PAUSED前一定要有buffer,为了PLAYING时不至于让用户等待前面的一小撮时间
2 EOS事件无效,但到PLAYING时会repost
3 sink把preroll上的所有等待都解除阻塞
4 live source停止产生数据

PAUSED-->READY
1 sink解除阻塞preroll,元件解除阻塞设备
2 chain和get_range 返回WRONG_STATE,(buffer相关的函数)
3 pad使无效(deactivate),stream thread停止
4 sink忘记所有的协商格式(negotiation caps)

READY-->NULL
1 close device
2 删除所有动态建立的pads

你可能感兴趣的:(thread,数据结构,Stream,iterator,Class,buffer)