gStreamer -Part I (Design Overview)

1疼进、Gstreamer design Overview

概括性介紹GStreamer的架構(gòu)及Gstreamer內(nèi)部工作機(jī)制运准。詳細(xì)內(nèi)容可以查看Gstreamer doc/markdown

1.1 Introduction

GStreamer由一些列庫(kù)和插件組成,可用于實(shí)現(xiàn)各種多媒體應(yīng)用:桌面播放器汞幢、音視頻解碼器、多媒體服務(wù)器、音視頻轉(zhuǎn)碼器等俩块。

上述應(yīng)用通過(guò)pipeline構(gòu)建,而pipeline又由單元(elements)構(gòu)成浓领。
單元是在多媒體流中執(zhí)行一系列動(dòng)作的對(duì)象:

  • 讀文件
  • 不同格式之間的編解碼
  • 從硬件設(shè)備捕獲圖像
  • 輸出給硬件設(shè)備
  • 多媒體流的混合或復(fù)用(mix or multiplex)

每個(gè)單元都有輸入pads玉凯、輸出pads,分別叫sink pads联贩、source pads漫仆,單元之間通過(guò)pads連接構(gòu)成pipeline,下面示例是ogg/vorbis 播放的pipeline:

+-----------------------------------------------------------+
|    ----------> downstream ------------------->            |
|                                                           |
| pipeline                                                  |
| +---------+   +----------+   +-----------+   +----------+ |
| | filesrc |   | oggdemux |   | vorbisdec |   | alsasink | |
| |        src-sink       src-sink        src-sink        | |
| +---------+   +----------+   +-----------+   +----------+ |
|                                                           |
|    <---------< upstream <-------------------<             |
+-----------------------------------------------------------+

filesrc讀取來(lái)自磁盤(pán)上的文件撑蒜,oggdemux單元對(duì)數(shù)據(jù)解復(fù)用(demultiplexes 1轉(zhuǎn)多)歹啼,將壓縮的音頻數(shù)據(jù)流發(fā)送給vorbisdec單元,vorbisdec單元對(duì)壓縮的數(shù)據(jù)解碼并發(fā)送給alsasink單元座菠,alsasink將解碼后的數(shù)據(jù)發(fā)送給聲卡播放狸眼。
Downstream、Upstream用于描述pipeline的方向浴滴,從source端到sink端傳遞叫Downstream拓萌,反之稱(chēng)為Upstream,數(shù)據(jù)流總是Downstream(source到sink端)

應(yīng)用的本質(zhì)是使用上述存在的單元構(gòu)成pipeline升略,這在pipeline topic中有詳細(xì)介紹微王。
應(yīng)用不用去管理復(fù)雜的數(shù)據(jù)流/解碼/轉(zhuǎn)換/同步,只需調(diào)用pipeline對(duì)象的高層函數(shù)如:播放/暫停/停止品嚣。
應(yīng)用還接受來(lái)自pipeline的消息和通知炕倘,如metadata,warning翰撑,error罩旋,EOS消息。
若應(yīng)用需要對(duì)圖像更多的控制眶诈,可以直接訪問(wèn)pipeline中的單元和pads涨醋。

gst-application to pipeline.png

1.2 Design overview

GStreamer設(shè)計(jì)目標(biāo):

  • 對(duì)大量數(shù)據(jù)的快速處理
  • 允許同時(shí)多線程處理
  • 多種多媒體格式的支持能力
  • 不同數(shù)據(jù)流之間的同步
  • 應(yīng)對(duì)多個(gè)硬件設(shè)備的處理能力

應(yīng)用的能力依賴(lài)于構(gòu)成單元的數(shù)量以及各單元在系統(tǒng)中的功能。
GStreamer core主要用于media agnostic逝撬,但仍可以提供一些單元特性用于描述media format浴骂。

1.3 單元(Elements)

pipeline最小構(gòu)成為單元,每個(gè)單元提供一定數(shù)目的pads宪潮,可以是source 或sink pads溯警。source pads提供數(shù)據(jù)趣苏,sink pads接收數(shù)據(jù),下面是oggdemux單元由一個(gè)接收數(shù)據(jù)的sink pads愧膀,兩個(gè)提供數(shù)據(jù)的source pads組成拦键。

 +-----------+
 | oggdemux  |
 |          src0
sink        src1
 +-----------+

單元包含四種狀態(tài):NULL, READY, PAUSED, PLAYINGNULLREADY狀態(tài)下檩淋,單元不會(huì)處理數(shù)據(jù)芬为。PLAYING狀態(tài)下處理數(shù)據(jù),中間態(tài)PAUSED用于在pipeline中預(yù)裝載數(shù)據(jù)蟀悦,使用gst_element_set_state()函數(shù)改變狀態(tài)媚朦。
單元狀態(tài)之間的變換需要經(jīng)過(guò)中間態(tài),即處于READY狀態(tài)想要變換為PLAYING狀態(tài)日戈,需要先變?yōu)橹虚g態(tài)PAUSED询张。
當(dāng)單元狀態(tài)變?yōu)?code>PAUSED,將激活單元的pads浙炼。首先激活的是source pads份氧,然后sink pads。pads激活后弯屈,會(huì)調(diào)用激活函數(shù)蜗帜,有些pads將開(kāi)啟GstTask線程或其它的機(jī)制,開(kāi)始發(fā)送和接收數(shù)據(jù)(producing and consuming data)
PAUSED比較特別资厉,因?yàn)樗枰獙?shù)據(jù)預(yù)裝載(preroll)到pipeline中厅缺,目的是用數(shù)據(jù)填充pipeline中的所有的連接單元以使得接下來(lái)的PLAYING狀態(tài)快速完成,有些單元甚至?xí)霈F(xiàn)已經(jīng)接收完所有數(shù)據(jù)宴偿,但還沒(méi)有完成PAUSED狀態(tài)的轉(zhuǎn)換湘捎。

詳細(xì)的單元狀態(tài)的轉(zhuǎn)變見(jiàn):states

單元的分類(lèi):

  • source elements: pipeline中不接收數(shù)據(jù),僅提供數(shù)據(jù)的單元

  • sink elements:不輸出數(shù)據(jù)給其它單元窄刘,僅接收數(shù)據(jù)提供給外部設(shè)備窥妇。

  • transform elements: 需要完成數(shù)據(jù)流之間轉(zhuǎn)變的單元,如編碼器/解碼器/轉(zhuǎn)換器娩践。

  • demuxer elements: 一個(gè)數(shù)據(jù)流變成多個(gè)數(shù)據(jù)流秩伞。

  • mixer/muxer elements: 多個(gè)數(shù)據(jù)流組合成單個(gè)數(shù)據(jù)流。

單元的其它分類(lèi)方式 (see klass).

1.4 Bins

bin是單元的子類(lèi)欺矫,其作用是作為其它單元的容器,這樣多個(gè)單元可以組成一個(gè)單元展氓。組成的一個(gè)單元叫bin穆趴。
bin相配合的子狀態(tài)改變稍后給出解釋?zhuān)琤in也會(huì)給單元分配事件和各種函數(shù)。
bin可以有自己的source 和 sink pads遇汞,通過(guò)鏡像一個(gè)或多個(gè)自身的子pads未妹。
如下圖簿废,有兩個(gè)單元的bin,bin的sink pad由一個(gè)單元的sink pad鏡像而來(lái)络它。

 +---------------------------+
 | bin                       |
 |    +--------+   +-------+ |
 |    |        |   |       | |
 |  /sink     src-sink     | |
sink  +--------+   +-------+ |
 +---------------------------+

1.5 Pipeline

pipeline 特殊的bin子類(lèi)族檬,為其小孩提供下面特性:

  • 為其所有小孩選擇和管理全局時(shí)鐘。
  • 管理 running_time 化戳,Running_time是pipeline消耗在PLAYING狀態(tài)以及用于同步的時(shí)間单料。
  • 管理pipeline的延遲。
  • 為單元提供與應(yīng)用之間的通訊手段:GstBus
  • 管理單元的全局狀態(tài)点楼,如Errors扫尖、EOS
    一般情況下,應(yīng)用創(chuàng)建一個(gè)pipeline來(lái)管理應(yīng)用中的所有單元掠廓。

1.6 Dataflow and buffers

GStreamer支持兩種可能類(lèi)型的數(shù)據(jù)流换怖,push and pull model,push model蟀瞧,upstream單元通過(guò)調(diào)用sinkpad的方法發(fā)送數(shù)據(jù)給downstream單元沉颂;pull model,downstream單元通過(guò)調(diào)用source pad的方法向upstream單元請(qǐng)求數(shù)據(jù)悦污。
大都數(shù)數(shù)據(jù)流的方式是push model铸屉,pull model可用于demuxer單元,也用于低延遲的音頻應(yīng)用中塞关。
在pads之間傳輸?shù)臄?shù)據(jù)存儲(chǔ)在Buffer中抬探,buffer包含指向存儲(chǔ)區(qū)域的指針以及對(duì)存儲(chǔ)區(qū)域的描述metadata。

metadata包含:

  • 數(shù)據(jù)的時(shí)間戳帆赢,何時(shí)捕捉的數(shù)據(jù)小压,何時(shí)播放數(shù)據(jù)...

  • 數(shù)據(jù)的偏置,音頻小樣椰于,視頻幀..

  • 數(shù)據(jù)持續(xù)時(shí)間怠益。

  • 數(shù)據(jù)其它特性的描述符號(hào),如discontinuities or delta units.

  • 其它仲裁metadata

通過(guò)連接單元之間的pad發(fā)送buffer瘾婿,push model下蜻牢,通過(guò) gst_pad_push()函數(shù)將buffer推送給相對(duì)應(yīng)的pad;pull model下偏陪,通過(guò)gst_pad_pull_range()函數(shù)向upstream的pad請(qǐng)求數(shù)據(jù)抢呆。

push model單元在發(fā)送buffer前,需要確認(rèn)相配對(duì)的單元能夠理解buffer的內(nèi)容笛谦。詢(xún)問(wèn)相配對(duì)單元能夠支持的格式抱虐,選擇合適的格式,發(fā)送buffer前饥脑,通過(guò)CAPS事件先發(fā)送選擇的格式恳邀。buffer發(fā)送之間的握手詳見(jiàn):negotiation

配對(duì)單元接收CAPS事件懦冰,將會(huì)檢查其是否能夠理解媒體類(lèi)型(media type),當(dāng)媒體類(lèi)型不被接受時(shí)谣沸,配對(duì)單元將拒絕接受buffer刷钢。

gst_pad_push()gst_pad_pull_range() 函數(shù)都有返回值指示操作是否成功,返回值錯(cuò)誤表示數(shù)據(jù)發(fā)送or數(shù)據(jù)接收沒(méi)有成功乳附,線程中初始化數(shù)據(jù)流的source單元將停止處理線程内地。

buffer的創(chuàng)建:gst_buffer_new() 或從buffer pool中請(qǐng)求可用的buffer:gst_buffer_pool_acquire_buffer(),當(dāng)使用第二種方法時(shí)许溅,配對(duì)單元可以執(zhí)行定制化的buffer分配算法瓤鼻。

The process of selecting a media type is called caps negotiation.
選擇媒體類(lèi)型的過(guò)程叫:caps negotiation

1.7 Caps

媒體類(lèi)型(Caps)的描述使用包含key/value對(duì)的列表,key類(lèi)型是string贤重,value類(lèi)型是single/list/range of int/float/string茬祷。

帶有變量的Caps也可用于描述可能的媒體類(lèi)型--可被pad處理。

1.8 Dataflow and events

數(shù)據(jù)流并行是一個(gè)事件流并蝗,不同于buffer祭犯,事件可在upstream和downstream之間同時(shí)傳遞,有些事件僅傳送給upstream或downstream滚停。

事件可用于指代數(shù)據(jù)流的特別條件沃粗,如EOS、通知插件的一些具體事件如 flushing or seeking键畴。

一些事件必須用buffer流序列化最盅,序列化的事件在buffer之間插入,沒(méi)有序列化的事件跳到當(dāng)前處理的任何buffer前面起惕。

序列化事件的示例是TAG事件:buffer之間插入TAG事件來(lái)標(biāo)識(shí)這些buffer的metadata涡贱。

非序列化事件的例子:FLUSH事件。

1.9 Pipeline construction

使用gst_pipeline_new()創(chuàng)建pipeline惹想,使用gst_bin_add() and gst_bin_remove()在pipeline中添加和刪除單元

增加單元后问词,通過(guò)gst_element_get_pad()函數(shù)找回單元的pads纽帖,使用gst_pad_link()函數(shù)完成pads之間的連接衔统。

當(dāng)真實(shí)的數(shù)據(jù)流出現(xiàn)在pipeline中,一些單元會(huì)創(chuàng)建新的pads橘蜜,當(dāng)單元?jiǎng)?chuàng)建新的pad時(shí)锋叨,g_signal_connect()函數(shù)會(huì)接收到一個(gè)通知垄分,而后新創(chuàng)建的pads才能連接到其它未連接的pads上。

一些單元不能連接娃磺,因?yàn)樗麄兊臄?shù)據(jù)類(lèi)型不一樣锋喜, gst_pad_get_caps()函數(shù)可以找回pad支持的數(shù)據(jù)類(lèi)型。

下面創(chuàng)建了一個(gè)MP3播放器的pipeline,后續(xù)的example中將會(huì)使用該示例嘿般。

+-------------------------------------------+
| pipeline                                  |
| +---------+   +----------+   +----------+ |
| | filesrc |   | mp3dec   |   | alsasink | |
| |        src-sink       src-sink        | |
| +---------+   +----------+   +----------+ |
+-------------------------------------------+

1.10 Pipeline clock

pipeline的一個(gè)重要作用:為所有的單元選擇全局時(shí)鐘。
該時(shí)鐘的目的是提供嚴(yán)格的每秒增加值GST_SECOND涯冠,各單元使用該時(shí)鐘同步數(shù)據(jù)的播放炉奴。
在pipeline狀態(tài)設(shè)置為PLAYING前,pipeline會(huì)詢(xún)問(wèn)每個(gè)單元是否能提供時(shí)鐘蛇更,時(shí)鐘以下面的順序選擇:

  • 應(yīng)用選擇時(shí)鐘瞻赶。
  • source單元提供時(shí)鐘。
  • 其他單元提供時(shí)鐘派任,從sink開(kāi)始砸逊。
  • 如果沒(méi)有單元提供始終,使用pipeline的默認(rèn)系統(tǒng)時(shí)鐘掌逛。

對(duì)典型的播放pipeline师逸,算法將會(huì)選擇sink單元提供的時(shí)鐘,如audio sink豆混。
對(duì)捕捉pipeline篓像,典型地使用數(shù)據(jù)產(chǎn)生器的時(shí)鐘,大都數(shù)情況下不能控制其產(chǎn)生數(shù)據(jù)的數(shù)據(jù)率皿伺。

1.11 Pipeline states

當(dāng)所有pads员辩、所有信號(hào)連接好,pipeline可以放在PAUSED狀態(tài)以開(kāi)始數(shù)據(jù)流鸵鸥。
當(dāng)bin開(kāi)始轉(zhuǎn)變狀態(tài)奠滑,將改變其所有孩子的狀態(tài)。pipeline將從sink單元到source單元逐步改變孩子的狀態(tài)妒穴,這將確保upstream單元發(fā)送數(shù)據(jù)給其它單元時(shí)宋税,不會(huì)發(fā)生該單元還沒(méi)有準(zhǔn)備好接收的情況。
對(duì)MP3播放pipeline宰翅,單元的狀態(tài)改變依次為alsasink,mp3dec,filesrc弃甥。

下面列出MP3 pipeline中各個(gè)單元的所有中間態(tài)轉(zhuǎn)變,導(dǎo)致下面狀態(tài)改變:

  • alsasink 轉(zhuǎn)變?yōu)?code>READY:音頻設(shè)備已準(zhǔn)備好(probed)汁讼。
  • mp3dec轉(zhuǎn)變?yōu)?code>READY:Nothing happens
  • filesrc轉(zhuǎn)變?yōu)?code>READY:文件已準(zhǔn)備好
  • alsasink 轉(zhuǎn)變?yōu)?code>PAUSED:音頻設(shè)備已打開(kāi)淆攻,alsasink作為sink,將返回 ASYNC(因?yàn)檫€不能接收數(shù)據(jù))
  • mp3dec to PAUSED: mp3dec轉(zhuǎn)變?yōu)?PAUSED:解碼庫(kù)已完成初始化嘿架。
  • filesrc 轉(zhuǎn)變?yōu)?code>PAUSED:文件已打開(kāi)瓶珊,線程已開(kāi)始push數(shù)據(jù)到mp3dec。
    至此耸彪,數(shù)據(jù)流從filesrc--mp3dec--alsasink伞芹,因?yàn)閙p3dec處于PAUSED狀態(tài),其接收來(lái)自filesrc sinkpad端的數(shù)據(jù),并對(duì)此壓縮的數(shù)據(jù)進(jìn)行解碼為原始音頻格式唱较。

mp3解碼器計(jì)算原始音頻數(shù)據(jù)的采樣率扎唾,信道數(shù)以及其他音頻特性,并發(fā)送媒體類(lèi)型的caps事件南缓。
Alsasink接收該caps事件胸遇,解析caps,并完成自身配置汉形,以能夠處理媒體類(lèi)型纸镊。

mp3dec 將解碼后samples放到Buffer中,繼而給buffer發(fā)送給下一個(gè)單元概疆。

Alsasink接收帶有samples的buffer逗威,因?yàn)樗邮誷amples的第一個(gè)buffer,完成狀態(tài)轉(zhuǎn)變?yōu)镻AUSED狀態(tài)岔冀,pipeline已prerolled凯旭,所有的單元都有samples,此時(shí)Alsasink有能力提供時(shí)鐘給pipeline楣颠。

alsasink處于PAUSED狀態(tài)尽纽,接收第一個(gè)buffer數(shù)據(jù),alsasink blocks童漩。mp3dec 和filesrc 在 gst_pad_push()中也是blocks弄贿。

所有單元gst_element_get_state()函數(shù)返回SUCCESS ,pipeline可以變?yōu)?code>PLAYING狀態(tài)矫膨。

在進(jìn)入PLAYING之前差凹,pipeline會(huì)選擇一時(shí)鐘,采樣時(shí)鐘的當(dāng)前時(shí)間侧馅,成為base_time危尿,將該時(shí)間分配給所有單元,各單元利用該時(shí)鐘的 running_time base_time 實(shí)現(xiàn)同步馁痴,詳見(jiàn):synchronisation

而后發(fā)生下面的狀態(tài)轉(zhuǎn)變:

  • alsasink to PLAYING: 解碼后的數(shù)據(jù)在音頻設(shè)備中播放谊娇。

  • mp3dec 轉(zhuǎn)變?yōu)?code>PLAYING:Nothing Happens。

  • 轉(zhuǎn)變?yōu)?code>PLAYING:Nothing Happens

1.12 Pipeline status

pipeline通過(guò)bus給應(yīng)用發(fā)具體事件罗晕,bus是pipieline提供的一個(gè)對(duì)象济欢,可通過(guò)gst_pipeline_get_bus()配置。

bus能夠被polled 或增加到glib mainloop小渊。
bus分布在所有單元中法褥,單元使用bus往上層推送消息,消息類(lèi)型主要有:ERRORS, WARNINGS, EOS, STATE_CHANGED等酬屉。

pipeline以一特別的方式來(lái)處理來(lái)自單元的EOS消息半等,當(dāng)所有sink單元向上推送EOS消息時(shí)揍愁,僅發(fā)送第一條給應(yīng)用。
其他的獲取pipeline狀態(tài)包括:詢(xún)問(wèn)功能(Query functionality)杀饵,通過(guò)執(zhí)行函數(shù) gst_element_query()獲取狀態(tài)莽囤,詢(xún)問(wèn)的類(lèi)型對(duì)于獲取pipeline的位置及總時(shí)間信息是非常有用的,也可以用于詢(xún)問(wèn)支持的seeking格式和范圍凹髓。

1.13 Pipeline EOS

當(dāng)source濾波器遇到數(shù)據(jù)流的結(jié)束部分烁登,將發(fā)出EOS事件給配對(duì)的單元,該事件將會(huì)通知downstream單元以及與其連接的所有單元蔚舀,配對(duì)端sink pad收到EOS事件后,將不會(huì)接收任何數(shù)據(jù)锨络。

單元在發(fā)送完EOS事件后赌躺,將停止提供流線程。

EOS事件最終會(huì)到達(dá)sink單元羡儿,sink單元將在bus上發(fā)送EOS消息礼患,以通知pipeline一個(gè)特別的數(shù)據(jù)流已經(jīng)完成。當(dāng)所有的sink都向上發(fā)送EOS消息掠归,pipeline僅向應(yīng)用發(fā)送第一條EOS消息缅叠。EOS消息僅在PLAYING狀態(tài)下發(fā)送給應(yīng)用。

當(dāng)處于EOS虏冻,pipeline保持PLAYING 狀態(tài)肤粱,這是應(yīng)用的職責(zé)對(duì)于PAUSE or READY pipeline。應(yīng)用還可以發(fā)布seek厨相。

1.14 Pipeline READY

當(dāng)運(yùn)行的pipeline從 PLAYING 變?yōu)?code>READY狀態(tài)领曼,pipeline接下來(lái)將發(fā)生:
alsasink轉(zhuǎn)為 PAUSED,alsasink將在下一個(gè)樣本完成狀態(tài)改變蛮穿,若單元之前是EOS庶骄,將不會(huì)等待樣本完成狀態(tài)轉(zhuǎn)變。

  • mp3dec to PAUSED: Nothing.
  • filesrc to PAUSED: Nothing

轉(zhuǎn)換到中間態(tài)PAUSED践磅,將阻止所有的單元( _push()函數(shù))单刁,這是由于sink單元接收完第一個(gè)buffer后阻止后面的數(shù)據(jù)傳輸。

Some elements might be performing blocking operations in the PLAYING state that must be unblocked when they go into the PAUSED state. This makes sure that the state change happens very fast.
有些單元在PLAYING狀態(tài)下也會(huì)出現(xiàn)阻止操作府适,在這些單元進(jìn)入到PAUSED狀態(tài)時(shí)羔飞,必須放開(kāi)。確保狀態(tài)能夠快速轉(zhuǎn)變细溅。

下一個(gè)PAUSEDREADY狀態(tài)的改變褥傍,pipeline關(guān)閉,所有流線程需停止數(shù)據(jù)傳輸喇聊,過(guò)程如下:

  • alsasink轉(zhuǎn)為READY:alsasink放開(kāi)( _chain()函數(shù))恍风,函數(shù)FLUSHING 返回值發(fā)送給配對(duì)的單元,sinkpad此時(shí)為非激活狀態(tài)不能用于發(fā)送數(shù)據(jù)。
  • mp3dec轉(zhuǎn)為READY:pads進(jìn)入非激活狀態(tài)朋贬,當(dāng)mp3dec離開(kāi)_chain()函數(shù)后完成狀態(tài)變化凯楔。
  • filesrc轉(zhuǎn)為READY:pads進(jìn)入非激活狀態(tài),線程停止锦募。

由于downstream單元返回一個(gè)錯(cuò)誤代碼(_push()返回FLUSHING)摆屯,upstream單元完成_chain() 函數(shù)。這個(gè)錯(cuò)誤代碼最終會(huì)反饋開(kāi)始流線程的單元(filesrc)糠亩,filesrc將停止線程并完成狀態(tài)改變虐骑。

這個(gè)事件的順序使得所有的單元放開(kāi),所有的流線程停止赎线。

1.15 Pipeline seeking

pipeline seeking需要嚴(yán)格的操作步驟廷没,以確保單元保持同步,seek以最小的延遲運(yùn)行垂寥。

應(yīng)用通過(guò)單元gst_element_send_event() 函數(shù)觸發(fā)pipeline上seek事件颠黎,該事件可以是單元支持的任何格式的seek事件。

pipeline暫停pipeline以加速seek操作滞项。

pipeline繼而將seek事件發(fā)送給所有sink單元狭归。sink前傳seek事件給upstream直到某個(gè)單元對(duì)seek事件進(jìn)行操作。所有的中間單元可以給seek偏置轉(zhuǎn)為另外的格式文判,由此过椎,解碼器單元能夠?qū)eek轉(zhuǎn)為時(shí)間戳的幀數(shù)。

當(dāng)seek事件到達(dá)一個(gè)單元律杠,將執(zhí)行seek操作潭流,單元相應(yīng)地執(zhí)行下面步驟:

  1. 發(fā)送 FLUSH_START事件給配對(duì)的所有downstream和upstream單元。
  2. 確保流線程沒(méi)有運(yùn)行柜去,因?yàn)椴襟E1灰嫉,流線程將一直是停止。
  3. 執(zhí)行seek操作嗓奢。
  4. 發(fā)送FLUSH完成事件給所有配對(duì)的downstream和upstream讼撒。
  5. 發(fā)送SEGMENT事件通知新位置的所有的單元,完成seek操作股耽。

步驟1中所有的downstream單元必須從所有的阻塞操作返回根盒,必須拒絕接下來(lái)的任何buffer或者除FLUSH外的其它事件。

第一個(gè)步驟確保流線程最終解除阻塞物蝙,繼而第二步可以操作炎滞,此時(shí)pipeline的數(shù)據(jù)流全面停止。

步驟3诬乞,單元執(zhí)行請(qǐng)求位置的seek操作册赛。

步驟4钠导,所有的配對(duì)單元又能夠接收數(shù)據(jù),新位置的數(shù)據(jù)流能夠連續(xù)森瘪,F(xiàn)LUSH完成事件發(fā)送給所有配對(duì)單元牡属,配對(duì)單元也能夠接收新的數(shù)據(jù),開(kāi)啟其數(shù)據(jù)流線程扼睬。

步驟5逮栅,通知新位置的所有單元,事件函數(shù)返回應(yīng)用窗宇,流線程開(kāi)始處理新的數(shù)據(jù)措伐。
因?yàn)閜ipeline仍然處于PAUSED狀態(tài),這將在sink端預(yù)處理下一個(gè)媒體樣本军俊,應(yīng)用可以用_get_state()函數(shù)等待預(yù)處理完成废士。

seek操作的最后一步是調(diào)節(jié)pipeline流的running_time =0,設(shè)置pipeline返回PLAYING狀態(tài)蝇完。

MP3播放器示例中的seek事件順序:

                                   | a) seek on pipeline
                                   | b) PAUSE pipeline
+----------------------------------V--------+
| pipeline                         | c) seek on sink
| +---------+   +----------+   +---V------+ |
| | filesrc |   | mp3dec   |   | alsasink | |
| |        src-sink       src-sink        | |
| +---------+   +----------+   +----|-----+ |
+-----------------------------------|-------+
           <------------------------+
                 d) seek travels upstream

    --------------------------> 1) FLUSH event
    | 2) stop streaming
    | 3) perform seek
    --------------------------> 4) FLUSH done event
    --------------------------> 5) SEGMENT event

    | e) update running_time to 0
    | f) PLAY pipeline
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市矗蕊,隨后出現(xiàn)的幾起案子短蜕,更是在濱河造成了極大的恐慌,老刑警劉巖傻咖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朋魔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡卿操,警方通過(guò)查閱死者的電腦和手機(jī)警检,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)害淤,“玉大人扇雕,你說(shuō)我怎么就攤上這事】悖” “怎么了镶奉?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)崭放。 經(jīng)常有香客問(wèn)我哨苛,道長(zhǎng),這世上最難降的妖魔是什么币砂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任建峭,我火速辦了婚禮,結(jié)果婚禮上决摧,老公的妹妹穿的比我還像新娘亿蒸。我一直安慰自己凑兰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布祝懂。 她就那樣靜靜地躺著票摇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪砚蓬。 梳的紋絲不亂的頭發(fā)上矢门,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音灰蛙,去河邊找鬼祟剔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛摩梧,可吹牛的內(nèi)容都是我干的物延。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼仅父,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼叛薯!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起笙纤,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤耗溜,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后省容,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體抖拴,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年腥椒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阿宅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笼蛛,死狀恐怖洒放,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情伐弹,我是刑警寧澤拉馋,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站惨好,受9級(jí)特大地震影響煌茴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜日川,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一蔓腐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧龄句,春花似錦回论、人聲如沸散罕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)欧漱。三九已至,卻和暖如春葬燎,著一層夾襖步出監(jiān)牢的瞬間误甚,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工谱净, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窑邦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓壕探,卻偏偏與公主長(zhǎng)得像冈钦,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子李请,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 本文對(duì) V4L2 的運(yùn)行時(shí)數(shù)據(jù)流設(shè)備管理做一個(gè)詳細(xì)的介紹瞧筛,包括什么叫「運(yùn)行時(shí)設(shè)備管理」,它是干什么用的导盅,怎么使用等...
    yellowmax閱讀 6,751評(píng)論 0 4
  • Java NIO(New IO)是從Java 1.4版本開(kāi)始引入的一個(gè)新的IO API驾窟,可以替代標(biāo)準(zhǔn)的Java I...
    zhisheng_blog閱讀 1,119評(píng)論 0 7
  • Java NIO(New IO)是從Java 1.4版本開(kāi)始引入的一個(gè)新的IO API,可以替代標(biāo)準(zhǔn)的Java I...
    編碼前線閱讀 2,268評(píng)論 0 5
  • 先扔個(gè)炸彈认轨,如果我是海軍司令,我就不讓紅海行動(dòng)這樣播出月培,即便是事實(shí)嘁字,是根據(jù)真實(shí)事件改編的,也要求編劇從另一個(gè)角度來(lái)...
    紅帽姐姐閱讀 571評(píng)論 0 0
  • 就在剛剛午飯后杉畜,我還在熱火朝天地玩著單機(jī)游戲1010纪蜒,打到一半的時(shí)候,卻突然想起了一個(gè)人此叠,然后鬼使神差地纯续,編輯了條...
    沉棲閱讀 466評(píng)論 0 2