天天看點

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);

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

繼續閱讀