Gstreamer 工具使用(二)

2021-06-09 14:14:59 字數 2292 閱讀 1789

前面兩篇我們完成了兩件很重要的事情,第一是建立了編寫外掛程式的環境和測試方法,第二是替外掛程式裝好了進出水閥 (sinkpad 和 srcpad) 的格式和屬性,格式不合的資料進不來,也出不去。接下來我們要開始放水,讓資料流進這個外掛程式。

gstreamer 在處理資料的流動有兩種主要的模式,乙個是「推」,乙個是「拉」。兩種模式需要實作的 routine 不同,在對資料的操作 (manipulation) 上的重點也不一樣,很容易被搞得摸不清方向(其實我到現在還是有很多沒搞懂的地方…)。首先先解釋一下兩者的不同。

「推」模式就是由上游的外掛程式控制資料的大小、流速,向下「推」到下游的外掛程式,所以下游的外掛程式並不會事先知道有多少資料會被送進來,它就必須先準備乙個緩衝區來承接資料,然後判斷緩衝區裡的資料是否足夠拆解出乙個壓縮單位的資料,夠的話就把資料切割出乙個固定大小送給解碼器,剩下的資料要留著和下一筆流進來的資料做連線。

「拉」模式則是需要自己控制資料大小、流速,告訴上游的外掛程式說自己要多少資料,從幾分幾秒開始讀,自己控制速度、大小等等變數,把資料「拉」進來。因為要流進來的資料量 (舉例來說,media-object 的 size、chunk size、packet size) 自己可以控制,就不需要設計乙個緩衝區來放資料。

通常,「拉」模式會用在 demuxer,而「推」模式用在其他外掛程式,所以 gst-template 提供的例子是「推」模式的寫法。_chain() 函式就是讓上游外掛程式把資料送進來的介面,當資料開始流動的時候 (完成啟動階段(activation stage)後,啟動的部份留待後述。) 會直接喚起初始階段時向 pad 註冊的 chain 函式,這個函式的介面 (gstpadchainfunction) 是已經被定義好的,其中乙個變數是 gstbuffer 的指標,資料就被塞在這個指標所指向的記憶體空間。我們便可以透過註冊進去的函式,取得操作這段資料的 handle 。

到目前為止都很抽象,我們走進原始碼來看就會好一點。

為了處理剛提到的狀態切換,我們要註冊乙個 _change_state() 函式。

1:

static gststatechangereturn

2:     gst_***dec_change_state(gstelement* element, gststatechange transition)
3:
18:
19:     ret = parent_class->change_state(element, transition);
20:

if(ret == gst_state_change_failure)

21:

return ret;

22:
23:

switch(transition)

24:
31:

return ret;

32: }
33:
34:

static

void gst_***dec_clas_init()

35:

如剛所說,當狀態從 null 轉到 ready 時 (gst_state_change_null_to_ready),外掛程式要做初始化,配置記憶體等。反過來當狀態從ready轉到null時 (gst_state_change_ready_to_null),就要釋放資源。為了避免當主要的執行續(main thread)還在運作時,就因為收到「停止」的指令,從 playing 切進 null ,把資源都給釋放掉,所以狀態轉換要分成兩個 switch-case 來處理。

我們可以試著討論一下 pipeline 如此處理狀態切換的理由是什麼。想像你手上有乙個濾水器,乙個水桶的汙水和乙個乾淨的水壺。當你要開始過濾汙水的時候,你會不會先檢查水壺已經正確地接在濾水器的另一端了?要開始把汙水往下倒時,會不會先把濾水器的開關開啟,會吧?水壺和濾水器都「ready」了以後,才開始把汙水往下倒。如果你使用濾水器的方法和我不同,請麻煩接受這個「由下而上ready」的想法,因為這是 gstreamer 在做開關控制的精神。

反過來看,如果要停止濾水,該是怎樣的順序?沒錯,把上面過濾的順序反過來。先停止倒汙水,再關閉濾水器,最後才蓋上水壺。這樣的流程要怎麼用程式碼表達呢?

當 pipeline 的狀態被切換到 playing 的時候,gstreamer 會開始做 preroll (提取影音資料進緩衝區),此時 _chain() 函式就會被觸發。主要的資料處理工作就是在 _chain() 裡完成,在「拉」模式的情況下,主要的資料處理工作則是在 _loop() 裡完成,以後會說明。因為 _chain() 裡面牽涉到 mpeg audio 解碼的程式,和 libmad 呼叫的部份、處理緩衝佇列等等比較複雜,將另開篇幅說明

GStreamer除錯 引數與函式的使用

原文出處 一 gstreamer的五個列印除錯資訊的函式 gst log 5 gst debug 4 gst info 3 gst warning 2 gst error 1 現摘錄 gstreamer plugin writer s guide 中23.2節中debugging 的第一句話 ele...

Git for Windows 工具的使用(二)

git分支 當乙個人開發功能a而另乙個人開發功能b,之後 進行整合的時候,使 既有功能a也有功能b。在git中,git給了我們分支的概念。分支可以使用我們快速的開發協作,並且快速的合併。分支的使用 通過命令git branch來檢視分支情況,當前分支會前面帶 標識。git branch 來建立分支。...

抓包工具 Charles基礎使用(二)

未安裝charles可以檢視安裝篇,傳送門 這篇主要講解charles的一些常用功能 步驟 1 右擊介面鏈結,選擇 breakpoints 2 在瀏覽器重新整理對應介面的頁面 3 此時會自動跳轉到charles並顯示出介面請求資訊 4 點選 edit request 修改請求的資訊,edit res...