原文链接:(原文分为三篇,我合成了一篇)
1.踏出 gstreamer plugin 的第一步
搞 gstreamer 插件已經好一陣子,好不容易勉強算的上知道怎麼去寫一個插件,嚴格說來看 gstreamer 寫的 plugin writer’s guide 應該是看不懂要怎麼接著去叫 gstreamer 做事的,網路上找的到的資料,也絕大多數是在講 integration layer (也就是純 player 啦) 的部份,而對於 development layer (也就是 pipeline 裡的 element) 該怎麼撰寫付之闕如。我打算趁手上的 wmv 插件告個段落時寫個筆記,算是為了交流,也算是幫自己重新確認觀念無誤。
這回我想拿 mp3 檔案做例子,用一個比較普遍而且廣泛應用的格式做練習有很多好處,一來沒有影像,就先省去同步的問題,也不會有 cpu / bandwidth 不夠的問題 (因為 video 的 bitrate 比 audio 高出很多);二來測試檔案滿地爬,而且橫跨多種不同參數的壓縮格式,更好的是可以互相參照的播放器也是滿地爬(一不小心就踩到的程度…搭捷運時年輕人幾乎人手一台 player),抓蟲或對照功能時很好用。
gstreamer 提供了一個 command line 建立 pipeline 的工具:gst-launch。給不同的參數可以自動或手動的方式去播放一個多媒體檔,這個工具說方便很方便,說不方便也的確有點麻煩。方便是一個指令就可以叫它開始播檔案,省去圖型化介面的慢和滑老鼠的動作;不方便是因為它除了 play 以外沒有別的 navigation command,不像 mplayer 還有給 hotkey 快轉 (快轉對於看謎片來說是很重要的呀!!)。至於所謂的 pipeline,長得就像這樣
箭頭和方塊組成的結構就稱為 pipeline,而每個方塊 (element) 都負責某一部份的資料處理,稱為 element。這和 DirectShow 的 graph 是相當神似的。有 DirectShow 基礎的人應該會比我還快了解 gstreamer 吧。
總之,自動建立 pipeline 的指令是如此:
gst-launch playbin uri=file:///path/to/file.mp3
而手動建立的話可以這麼簡單:
gst-launch filesrc location=/path/to/file.mp3 ! mad ! alsasink
其中的 mad 就是 gstreamer 會 runtime 去 load 的 element ,也就是接下來會深入去講的主題。如果你的系統缺少了解碼 mp3 必要的函式庫或 gstreamer 針對 mp3 的插件,那就會播放失敗。開源的 mp3 函式庫很多,我們就用 mad (mpeg audio decoder)。以 ubuntu 為例,安裝必要的函式庫很容易:
sudo apt-get install libmad0 gstreamer0.10-plugins-ugly
如此應該就可以順利聽到 mp3 的音樂了。其他必要的 element 像是 audio renderer 通常預設就會安裝了。知道了這些工具後我們就可以開始以 mad 為師的 gstreamer 插件學習過程。
首先,我們最好用 gst-inspect 看看 mad 這個插件的一些資料,這些都會是接下來寫程式或多或少會用到的。
gst-inspect mad
我們會看到一些對這個插件的描述,pad template 的 capabilities 等等,gstreamer 的文件裡有比較清楚的列出哪些 properties 對 capabilities 的描述和對應的意義,此處就不多說。
gst-launch 和 gst-inspect 是開發插件時滿重要的兩個工具,玩熟練後我們就可以開始實作自己的 mp3 gstreamer 插件。gstreamer 很體貼的在網站上擺了一個插件的 template,我們就從這個 template 開始走下去。
git clone git://anongit.freedesktop.org/gstreamer/gst-template.git下載後在作業目錄會找到一個 gst-template 的資料夾,然後進到 gst-plugin/src 執行
../tools/make_element mp3dec
這個 tool 會用 mp3dec 為名產生一個 gstreamer plugin 的 template。這兩件事情就是在做 gstreamer plugin writer’s guide 的 section 3.1, 3.2。
接著,我們要「立刻」看到自己寫的 plugin 被 gst-inspect 找到,這要怎麼做呢?
首先,改寫 gst-plugin/src/Makefile.am,讓他編譯我們的程式,用文字編輯器把 gstplugin 這個字串換成 gstmp3dec。接著就像一般我們在編譯開源專案一樣,藉 autotool 來產生 Makefile,執行 gst-plugin/autogen.sh 。接著到 gst-plugin/src 下 make,就會在 gst-plugin/src/.libs/ 下面看到 libgstmp3dec.so,這個就是我們的 gstreamer 插件。你可以用
GST_PLUGIN_PATH=/path/to/gst-template/gst-plugin/src/.libs/ gst-inspect mp3dec
來檢視這個插件的細節,就像之前我們檢視 mad 一樣,會發現很多資訊在 mad 裡面有的,在 mp3dec 這個新生的插件裡看不到,那些就是我們要慢慢加上去的功能。
2 看見 gstreamer plugin 的第二步
上一篇我們把一些編譯 gstreamer 插件的環境給準備好,也透過 gst-inspect 看到新加入的插件 ( 在上一個例子中是「mp3dec」) 的屬性,接著就要親眼見證它的運作了。
先打開 gstmp3dec.c 找到
g_printf(“I'm plugged, therefore I’m in./n”);
這一行,改一下文字,然後跳出重編,執行
gst-launch filesrc location=/path/to/file.mp3 ! mad ! mp3dec ! alsasink
有沒有看到一行你剛剛改的字拚命洗畫面,那就是插件運作的明證。接著我們要開始改寫這個插件,來讓它取代 mad。所以測試方法也很明確,就是要讓
gst-launch filesrc location=/path/to/file.mp3 ! mp3dec ! alsasink
這指令可以正確地播出 file.mp3 的內容。這個指令會在接下來的測試過程中不斷的被執行。