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