GStreamer流媒體知識介紹

 

 

GStreamer框架linux

一、GStreamer是什麼?app

衆所周知,Microsoft's Windows和Apple's MacOS對多媒體設備、多媒體創做、播放和實時處理等方面都有很好的支持,而Linux對多媒體應用一直略顯不足,因此爲了解決Linux上對多媒體方面的支持,才引進GStreamer。框架

GStreamer是一個通用的跨平臺的流媒體應用程序框架,基於GObject,以C語言寫成。 GStreamer並不受限於音頻和視頻處理,它可以處理任意類型的數據流,所以任意一種流媒體應用均可以支持,如:MeidaPlayer、A/V Editor、VOIP、RTSP、A/V Coder等等。 GStreamer框架是基於插件(plugin)和管道(pipeline)的體系結構,框架中全部功能模塊都是可插拔的組件,可隨意安裝到任意管道上,所以造就了大量的GStreamer的共享庫。ide

 

 

二、 pipeline是什麼?函數

 

這是個典型的MeidaPlayer的模型。post

source —— 數據來源,多是file、http、rtp等。插件

demux —— 負責把容器裏的音視頻數據剝離出來,而後分別送給audio/video decoder。線程

decoder —— 解碼,而後把解完後的數據(pcm/yuv)送給audio/video output輸出。3d

output —— 負責將decoder過來的數據呈現出來。指針

若是把數據想象成流水的話,每一個模塊功能雖然不一樣,但基本都是接收上個模塊過來的數據,而後加工,把加工後的數據送到下一個模塊,這些模塊經過某種方式鏈接起來,就造成了一個流水線(pipeline),這個流水線就是一個MediaPlayer。 GStreamer 把每一個模塊都看作是一個元件(element),而後構建鏈接和操做這些element的方法,用戶能夠經過本身的需求把不一樣的elements排列組合,造成不一樣的pipeline。

 

3. element是什麼?

element是一個對多媒體流進行處理的object,也是一個具體的功能模塊,是pipeline的最小組成部分。

element分類:source(只提供數據源),sink(如播放設備),transform,demuxer,muxer element的輸入爲sink pad,輸出爲source pad,經過pad把element鏈接起來構成pipeline 圖中downstream爲順流方向,upstream爲逆流方向

 

4. pad是什麼?

element的襯墊(pad)對應輸入和輸出接口,對於輸入襯墊爲sink pad,對於輸出襯墊爲source pad element之間都是經過pad來連接的,順序流向不能錯,也基於pad類型進行分類

pad有處理特殊數據的能力,一個pad可以限制數據流類型(GstCaps)的經過。 連接成功的條件是:只有在兩個襯墊(pads)容許經過的數據類型一致的時候才被創建,經過caps negotiation方法。 襯墊有三種類型的時效性: 永久型(always)、隨機型(sometimes)、請求型(on request)。 永久型的襯墊一直會存在,隨機型的襯墊只在某種特定的條件下才存在(會隨機消失的襯墊也屬於隨機型), 請求型的襯墊只在應用程序明確發出請求時纔出現。

 

5. 四種狀態

element有四種可能的狀態,分別是NULL,READY,PAUSED,PLAYING。

GST_STATE_NULL 默認狀態,該狀態將會回收全部被元件佔用的資源。

GST_STATE_READY 準備狀態,該狀態會獲得所需的全局資源,但數據流並未處理。

GST_STATE_PAUSED 暫停狀態,元件已經對流開始處理,一旦狀態變爲 PLAYING,能夠重放數據流, 與PLAYING 狀態的區別是:時鐘是禁止運行的,主要對數據進行preroll。

GST_STATE_PLAYING 與 PAUSED 狀態如出一轍,但能夠運行時鐘,對數據進行處理。

經過函數gst_element_set_state()能夠改變一個元件的狀態,但狀態變換不能跳變,好比不能從READY狀態 直接變換到PLAYING狀態,必須通過中間的PAUSE狀態。

 

6. element流程

element create   

  gstreamer加載時,掃描/usr/lib/gstreamer-1.0目錄下的庫,識別其中的feature,並記錄相關信息。當使用時,檢查gstreamer core是否支持該功能,若是有,則加載相應庫,獲取信息,建立相應的element實例。

element link

  element建立後,會添加到pipeline,在link時會經過gst_pad_query_caps(pad, NULL)查詢pad template caps。由於此時還沒有打開設備、初始化等,因此不知道element真正支持的caps,但只要查詢的caps有交集便可link成功。

NULL->READY

  該狀態下,會初始化設備,根據相應的class調用start()或open()等函數初始化相應的硬件設備,初始化class的結構參數等。

READY->PAUSED

  進一步申請資源,肯定相應的參數設置,同時會激活pad。而後數據預滾(preroll),當數據到達時,檢查數據時間戳是否在segment內,進行數據同步,最後就是commit,進入PAUSED。

PAUSED->PLAYING

  在這個過程,設置clock時鐘運行,接收到數據時,檢查時間有效性,進行數據同步、處理,push到下游,發送QOS事件到上游,完成一個循環。

 

 

7. bin是什麼?

箱櫃(bin)是由多個element構成的容器,同時bin自己也是一種element,因此可以像操做普通element同樣操做一個bin,改變bin的狀態能夠改變bin內部全部elements的狀態。

bin能夠發送總線消息給它的子集elements ,包括:錯誤消息(error messages),標籤消息(tag messages),EOS消息(EOS messages)。

管道(pipeline)是一個特殊的bin,當設定管道暫停或播放狀態的時候,數據流將開始流動,而且媒體數據處理也開始處理。一旦開始,pipeline將在一個單獨的線程中運行,直到被中止或者數據流播放完畢。

data flow:數據流在pads之間傳送,封裝在Buffer裏,Buffer包含指向數據的指針和一些metadata。

event flow:事件流與數據量不一樣,既有downstream方向,也有upstream,能夠捕捉事件信號,進行回調處理

pipeline構建過程

gst_pipeline_new()函數:建立一個pipeline

gst_bin_add()函數:向pipeline中添加elements

gst_bin_remove()函數:從pipeline中移除element

gst_element_link()函數:連接pipeline中的elements

 

 

8. 緩衝區

緩衝區是指管道里的數據流,一般一個源元件會建立一個新的緩衝區,同時元件還將會把緩衝區的數據傳遞給下一個元件。使用GStreamer建立管道,不須要本身來處理緩衝區,元件將會自動處理這些緩衝區。

一個緩衝區主要組成:

指向某塊內存的指針

內存的大小

緩衝區的時間戳

一個引用計數,指出了緩衝區所使用的元件數。沒有元件可引用的時候,這個引用將用於銷燬緩衝區

 

9. message/event/signal

Bus message —— 用於gstreamer和app之間交互的,好比當一個文件播放結束的時候,gstreamer會發一個EOS的message到GstBus上,若是app有去偵聽(函數gst_bus_add_watch),那麼在處理消息的callback函數中就能夠收到這個消息。

event —— 用於gstreamer內部element之間(或pad之間)傳遞事件的,好比source element數據已經結束,會發出一個EOS event,順着pipeline依次向downstream方向傳遞,elements獲得通知,作一些cleanup工做,當全部sink element都收到並處理以後,gstreamer內部產生一條GSTMessage,並post至GstBus,若是APP有監聽,就能知道當前播放已經結束。

signal —— 屬於GObject體系,用於app和GObject之間交互的一種機制。在gstreamer中,element自己也是gobject,因此經過signal,就能夠將app和element聯繫起來。 當element發生了一些事情相讓app知道時,就能夠用signal的方式來通知app,好比動態建立了一個Pad。

 

 

10. 初步總結

須要包含頭文件gst/gst.h來訪問庫函數。

使用gst_init初始化GStreamer庫和一些必要的參數。

使用gst_element_factory_make建立元件,參數爲工廠對象名和新元件名,在bin中可查詢該元件。

使用gst_object_unref釋放元件,元件引用記數減1,任一元件建立時,引用記數爲1,當引用記數爲0時,元件會被銷燬。

使用gst_bin_new或gst_pipeline_new建立箱櫃。

使用gst_bin_add/remove添加/移除元件,元件所屬箱櫃,銷燬箱櫃,則箱櫃中的元件一樣被銷燬,元件移除則自動銷燬。

使用gst_element_link連接元件

每一個管道默認包含一個總線,應用程序不須要再建立總線,只需在總線上設置一個消息處理器,總線會輪詢消息處理器是否有新的消息,當採集到消息後,總線將呼叫相應的回調函數來處理。使用gst_bus_add_watch或gst_bus_add_signal_watch偵聽回調,或使用gst_bus_peek/poll主動輪詢消息。

 

11. 編譯說明

好比以前的helloworld程序

編譯: gcc -Wall helloworld.c -o helloworld $(pkg-config --cflags --libs gstreamer-0.10)

編譯時藉助了pkg-config命令,用於得到某一個庫/模塊的全部編譯相關的信息。

pkg-config --cflags --libs gstreamer-0.10 會把gstreamer-0.10編譯所依賴的庫路徑和頭文件路徑所有找出來,不用再依次寫出,這條命令參數至關於: -pthread -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/gstreamer-0.10 -I/usr/include/libxml2 -pthread -L/usr/lib/i386-linux-gnu -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lxml2 -lgthread-2.0 -lrt -lglib-2.0)

相關文章
相關標籤/搜索