SlideShare a Scribd company logo
GStreamer
Application Development Manual 導讀
第一章到第十章
Wen Liao
目標
了解GStreamer是什麼
注意
● 只包含手冊第一章到第十章
● 可能有誤,請自行斟酌對照手冊
● 請留意囉唆的程式碼變數顏色
my_var = my_func();
my_hash(my_var);
Outline
● Backgrounds
● Overview
● Demo
● References
Background
● Framework
○ Longman:
■ the main supporting parts of a building, vehicle,
or object
● http://www.ldoceonline.com/dictionary/framework
● Software framework
○ 一般性,可重複使用的軟體平台
○ 用於降降低開發軟體的成本
Multimedia Framework
● 一種Software framework
● 專門來處理多媒體相關應用程式
○ 多媒體播放器
○ 多媒體格式轉換
○ 多媒體編輯器
○ Video conference
○ ….
GStreamer
● 一種Multimedia framework
● 以基於C語言開發的GObject發展
● 支援多平台
● LGPL
Element and Pipeline in GStreamer:
Series of Producer - Consumer
http://en.wikipedia.org/wiki/GStreamer#Technical_overview
PAD
兩邊有協定溝
通決定要傳送
那些資料
兩邊有協定溝
通決定要傳送
那些資料
Plugin
● 一種Element
● 大部分以static library形式
● 種類
○ codec
○ container formats
○ IO driver
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-gstreamer.html
Outline
● Backgrounds
● Overview
● Demo
● References
前情提要
http://en.wikipedia.org/wiki/GStreamer#Technical_overview
PAD
兩邊有協定溝
通決定要傳送
那些資料
兩邊有協定溝
通決定要傳送
那些資料
Overview
● Element
● Pad
● Bin and pipeline
● Communication
Element
● 提供基本功能的元件。可以透過Pad和其他
Element組合。
○ 播放聲音
○ 讀取檔案
○ 透過網路取得多媒體內容
○ 多媒體解碼
○ …
● 分類
○ Source element
○ 一般element
○ Sink element
Source Element
● 從檔案或是音效卡讀出資料用
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html
一般Element
● 有輸入有輸出
● 應用:
○ Filters
○ convertors
○ demuxers
○ muxers
○ codecs
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html
Sink Element
● 單純Consume資料,通常就是Render或是音
效卡
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html
產生Element
方法一:懶人法
/* 建立 */
element =
gst_element_factory_make ("fakesrc", "source");
...
/* 宰掉 */
gst_object_unref (GST_OBJECT (element));
Factory
name
自己給的名稱
Factory name
GST會內部maintain
reference counter,每次unref
就遞減。減到0就deallocate
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html
產生Element
方法二:非懶人法
/* 建立 */
factory = gst_element_factory_find ("fakesrc");
element = gst_element_factory_create (factory, "source");
...
/* 宰掉 */
gst_object_unref (GST_OBJECT (element));
Factory
name
自己給的名稱
Factory name
GST會內部maintain
reference counter,每次unref
就遞減。減到0就deallocate
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html
Element
● gst-inspect指令可以顯示系統可用的element
資訊
● GstElement資料結構繼承自GObject
○ 可用GObject的屬性
○ 可用GObject的signal及對應的callback
○ GObject資訊
■ https://developer.gnome.org/gobject/stable/rn01.
html
Element和Factory
● GstElementFactory
○ Framework maintain所有系統上可以用的plugin
(element)資訊(metadata)
■ ex:
● gst_element_factory_get_metadata (factory,
GST_ELEMENT_METADATA_DESCRIPTION))
○ 這些metadata可以用來確認目前element和element之
間是否可以互相連接
連接Elements
1. 產生pipeline
2. 決定並產生elements
3. 把elements打包成bin
a. (要記得pipeline是bin的一種)
4. 建立link
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-elements-link.html
範例
/* 1.產生 pipeline */
pipeline = gst_pipeline_new ("my-pipeline");
/* 2. 產生elements */
source = gst_element_factory_make ("fakesrc", "source");
filter = gst_element_factory_make ("identity", "filter");
sink = gst_element_factory_make ("fakesink", "sink");
/* 3. 打包 */
gst_bin_add_many (GST_BIN (pipeline), source, filter, sink,
NULL);
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html
接關
/* 4. 連連看 */
if (!gst_element_link_many (source, filter, sink, NULL)) {
g_warning ("Failed to link elements!");
}
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html
Element內部狀態
● GST_STATE_NULL
○ 建立時預設狀態
○ 內部沒有分配任何資源
○ 狀態被設成NULL framework會自動清除資源
○ 當reference count為零時必須要在該狀態
● GST_STATE_READY
○ 資源已配置或是被reset掉
Element內部狀態
● GST_STATE_PAUSED
○ 資源已分配並可以執行,但是偏不去處理資料
○ 此時可以趁機更動控制資料以達到trick play的目的
○ 因為隨時都有可能從暫停狀態切換到播放狀態,
Element需要想辦法降低狀態切換所需時間。
● GST_STATE_PLAYING
○ 和PAUSE差別就是會去處理資料
○ 精確的說法,是clock有沒有在run的差別
■ 在這邊有解釋clock
● http://gstreamer.freedesktop.
org/data/doc/gstreamer/head/manual/html/chapter-clocks.
關於Element狀態
● 透過下面API更改
○ gst_element_set_state (GstElement *element,
GstState state);
NULL
READY PAUSE
PLAYING
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#GstState
NULL
READY PAUSE
PLAYING
Upward state
change
Downward
state change
Overview
● Element
● Pad
● Bin and pipeline
● Communication
Pad
● Element的input/output部份
○ Sink: Input
○ Source: Output
● Element之間的連結方式
● GStreamer允許element之間透過negociate
決定link以及資料傳輸方式
○ GstCaps
■ GStreamer capabilities of an element
● 想像螢幕可以顯示HDMI或是VGA訊號,這些
信號線就是PAD
More about Pad
● 主要組成
○ 資料傳輸方向
■ Source
■ Sink
○ Availability
■ Always
■ Sometimes (Dynamic)
● 應用程式可以透過監聽pad-added event處理對應行為
● gst-inspect指令會列出支援的events
■ On request
● element夠過下面API產生Pad
○ gst_element_get_request_pad
○ gst_element_get_compatible_pad
Capabilities
● 支援的屬性稱為property
○ Key: 字串
○ Value:
■ 基本type如int, float
■ Range: 如1~100
■ List
● 多個基本type
■ Array
● 多個相同的基本type
Capabilities
● 想像Mimetype
● 用途
○ PnP
○ 檢查相容性
○ 提供Metadata
○ Filter,限制處理的資料特性
取得Capabilities metadata範例
cap_str = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (cap_str, "width", &width) ||
!gst_structure_get_int (cap_str, "height",
&height))
{
g_print ("No width/height availablen");
return;
}
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-caps-api.html
Capabilities 作為filter應用方式
● 設定elements兩邊link滿足條件(下面方式擇一)
○ filter_cap = gst_caps_new_full(..);
○ filter_cap = gst_caps_new_simple(..);
● link兩個element,前面的條件作為參數帶入
○ gst_element_link_filtered (ele1, ele2, filter_cap);
Ghost Pad
● 用於處理bin的pad問題。因為bin沒有pad,並
且實際上處理pad的仍然是element
● 想法:Unix下的symbolic link
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-pads-ghost.html
做一個假的
bin本身沒有pad
建立Ghost Pad
● 產生element和bin
● 把element打包到bin
● link element內部
● 產生Ghost Pad
範例
/* 產生element和bin */
sink = gst_element_factory_make ("fakesink", "sink");
bin = gst_bin_new ("mybin");
gst_bin_add (GST_BIN (bin), sink);
/* 產生ghost pad */
pad = gst_element_get_static_pad (sink, "sink");
gst_element_add_pad (bin,
gst_ghost_pad_new ("sink", pad));
gst_object_unref (GST_OBJECT (pad));
把element的pad
轉給ghost pad
Overview
● Element
● Pad
● Bin and pipeline
● Communication
Bin
● Bin
○ 一組透過pad連接起來的elements
○ GStreamer提供針對bin的操作。只要操作bin,
GStreamer幫你搞定裏面的element。
■ 設定狀態
■ 傳送錯誤通知
■ …
Bin
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-bins.html
● 精確的來說,Bin是一個container element
○ 所有對element/GObject的操作都可以apply到bin
Pipeline
● Pipeline
○ 一種bin
○ 最高層的bin,和一般bin的差別是他提供介面給應用程
式控制
○ 實作上面,每個pipe都是單獨的thread
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-intro-basics-bins.html
使用bin
● 產生pipeline給應用程式使用
● 產生bin
● 產生element處理實體資料
● 打包成bin
● 告訴pipeline處理bin
● 連連看
● 開工
範例
/* 1. 產生pipeline給應用程式使用 */
pipeline = gst_pipeline_new ("my_pipeline");
/* 2. 產生bin */
bin = gst_bin_new ("my_bin");
/* 3. 產生element處理實體資料 */
source = gst_element_factory_make ("fakesrc", "source");
sink = gst_element_factory_make ("fakesink", "sink");
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-bin-create.html
範例
/* 4. 打包成bin */
gst_bin_add_many (GST_BIN (bin), source, sink, NULL);
/* 5. 告訴pipeline處理bin */
gst_bin_add (GST_BIN (pipeline), bin);
/* 6. 連連看 */
gst_element_link (source, sink);
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-bin-create.html
Overview
● Element
● Pad
● Bin and pipeline
● Communication
○ bus and message
○ buffer
Bus
● 用來傳遞GStreamer framework和應用程式
之間的訊息
Communication
● 對象:Pipeline、element、應用程式
● 方式
○ buffer object
■ 對象:element之間
■ 用於傳送Streaming需要的資料
■ 單向的從source 到 sink
○ event object
■ 對象:
● Element之間
● 應用程式到element
■ 雙向
■ source 到 sink的event可支援和streaming 同步
Communication
● 對象:Pipeline、element、應用程式
● 方式
○ message object
■ 對象:element到應用程式
■ 支援同步或非同步方式
■ Thread safe
○ Queries object
■ 對象:
● 應用程式到pipeline
● Element之間
■ 用來讓應用程式查詢狀態如已播放時間等
■ 為同步傳輸。表示應用程式送出query要等到
pipeline回應才能繼續執行。
圖示
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-intro-basics-communication.html
➀
➁
➂
➃
Overview
● Element
● Pad
● Bin and pipeline
● Communication
○ bus and message
○ buffer
More about Bus and Message
● Pipeline產生時就會自動分配Bus資源
● 使用方式
○ 使用GLib/Gtk+ main loop去
i. 告訴loop要聽bus event,從對應的callback參數中
去撈event如
● GST_MESSAGE_EOS
● GST_MESSAGE_ERROR
● ..
ii. polling
使用GLib/Gtk+ main loop 處理message (1)
● 撰寫callback,撈想看的event
● 應用程式中
○ 告訴main loop要聽bus event,前面的callback為參數
○ 啟動main loop
範例
/* 1. 寫callback */
my_bus_callback (...)
{
...
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_ERROR:
…
}
}
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-bus.html
範例
/* 以下都在main() 裏面 */
/* 2. 我要從main loop 聽GStreamer bus event */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
bus_watch_id = gst_bus_add_watch (bus,
my_bus_callback, NULL);
gst_object_unref (bus);
/* 3. 開工 */
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
….
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-bus.html
上頁callback
function
使用GLib/Gtk+ main loop 處理message (2)
● 直接註冊signal callback
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline);
gst_bus_add_signal_watch (bus);
g_signal_connect (bus, "message::error", G_CALLBACK
(cb_message_error), NULL);
g_signal_connect (bus, "message::eos", G_CALLBACK
(cb_message_eos), NULL);
Callback function for
events
Messages
● 格式
○ message source
■ 從哪個element送出
○ message type
○ timestamp
● 分類
○ 錯誤或警告通知
○ 播放結束通知 (EOS)
○ Tag:和metadata 相關
○ 狀態改變,如從PLAYING轉換到PAUSE
○ 緩衝相關
○ Element自訂訊息
Overview
● Element
● Pad
● Bin and pipeline
● Communication
○ bus and message
○ buffer
More about Buffer
● GStreamer element之間實際傳送的多媒體資
料
● GStreamer幫你弄buffer 機制
● 包含
○ 指標
○ timestamp
○ reference count。減到零自動GG
○ flag
典型Buffer生命週期
● Source element: 新增分配、分配記憶體空間、
放資料、傳給Sink element
● Sink element: 從buffer讀資料、處理資料、
unreference buffer、framework發現reference
count變為0所以釋放相關資源
Outline
● Backgrounds
● Overview
● Demo
● References
Environment
● Ubuntu 12.04.4 64-bit
Element Information
● gst-inspect oggdemux
○ Class hierarchy
○ Details
手冊Hello World範例程式
● 程式說明
● 編譯
● Demo
程式描述
● 出處:
○ http://gstreamer.freedesktop.
org/data/doc/gstreamer/head/manual/html/chapter-helloworld.html#section-
helloworld
● 目的:從檔案播放 Ogg影片中Vorbis格式的聲音
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-helloworld.html
架構 Recap
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-helloworld.html
ogg為一個container。
可放audio/video等資料
vorbis為一種聲音格式
需要把解出來的資料轉
成音效卡支援的格式
元件
Elements
Pads
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-helloworld.html
程式架構
● Element訊息處理Callback
● 處理pad add event
● 主程式
○ 準備
■ 分配資源
● elements
● GLib mainloop協助處理message
■ 把element打包成pipeline
■ 連連看
■ 設定通訊及相關callback
○ 開始執行
○ 結束、清場
很囉唆的細節,請自行斟酌
/* 1. Element訊息處理Callback */
bus_call (...)
{
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_main_loop_quit (loop);
break;
...
}
}
播放結束處理
很囉唆的細節,請自行斟酌
/* 2. 處理pad add event */
on_pad_added(..., GstPad *pad, gpointer data)
{
GstPad *sinkpad;
GstElement *decoder = (GstElement *) data;
….
sinkpad = gst_element_get_static_pad (decoder, "sink");
gst_pad_link (pad, sinkpad);
gst_object_unref (sinkpad);
}
oggdemux動態產
生pad,所以產生
時才link decoder
很囉唆的細節,請自行斟酌
main(...)
{
...
/* 3. 初始化 GStreamer和GLib mainloop */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
….
/* 接下頁 */
很囉唆的細節,請自行斟酌
/* 4. 分配資源 */
pipeline = gst_pipeline_new ("audio-player");
source = gst_element_factory_make ("filesrc",
"file-source");
demuxer = gst_element_factory_make ("oggdemux",
"ogg-demuxer");
decoder = gst_element_factory_make ("vorbisdec",
"vorbis-decoder");
conv = gst_element_factory_make ("audioconvert",
"converter");
sink = gst_element_factory_make ("autoaudiosink",
"audio-output");
很囉唆的細節,請自行斟酌
/* 5. 告訴程式開哪個檔案 */
g_object_set (G_OBJECT (source), "location",
argv[1], NULL);
/* 6. 叫mainloop聽GStreamer bus */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
bus_watch_id = gst_bus_add_watch (bus,
bus_call,
loop);
gst_object_unref (bus);
前面的callback
很囉唆的細節,請自行斟酌
/* 7. 打包 */
gst_bin_add_many (GST_BIN (pipeline),
source, demuxer, decoder, conv, sink, NULL);
/* 8. 連連看 */
gst_element_link (source, demuxer);
gst_element_link_many (decoder, conv, sink, NULL);
/* 9. 註冊要處理的event */
g_signal_connect (demuxer, "pad-added", G_CALLBACK
(on_pad_added), decoder);
oggdemux動態產
生pad,所以產生
時才link decoder
前面的callback
callback
吃的參數
很囉唆的細節,請自行斟酌
/* 10. 將pipeline內的elements狀態設為可以播放 */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* 11. 開工 */
g_main_loop_run (loop);
很囉唆的細節,請自行斟酌
/* 12. 收工 */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
g_source_remove (bus_watch_id);
g_main_loop_unref (loop);
}
狀態設成null,
element要自行釋
放資源
bus_call() 中呼叫g_main_loop_quit
(loop)就會到這邊
手冊Hello World範例程式
● 程式說明
● 編譯
● Demo
編譯參數
● gcc -Wall helloworld.c -o helloworld $(pkg-
config --cflags --libs gstreamer-1.0)
$ echo $(pkg-config --cflags --libs gstreamer-0.10)
-pthread -I/usr/include/gstreamer-0.10 -
I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0
/include -I/usr/include/libxml2 -pthread -lgstreamer-0.10
-lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lxml2 -
lglib-2.0
Ubuntu 12.04.4使
用0.10
手冊Hello World範例程式
● 程式說明
● 編譯
● Demo
Outline
● Backgrounds
● Terminology
● Demo
● References
References
● GStreamer - Wikipedia
○ http://en.wikipedia.org/wiki/GStreamer
● Overview of the design of GStreamer
○ http://cgit.freedesktop.
org/gstreamer/gstreamer/plain/docs/design/part-
overview.txt
● Application Development Manual
○ http://gstreamer.freedesktop.org/documentation/

More Related Content

PPTX
Resource Aware Scheduling in Apache Storm
PDF
Efficient execution of quantized deep learning models a compiler approach
PDF
Improving GStreamer performance on large pipelines: from profiling to optimiz...
PDF
Mastering GC.pdf
PDF
golang profiling の基礎
PDF
生成AIが切り拓く新しいゲームの創り方・遊び方
PPTX
High Performance, Scalable MongoDB in a Bare Metal Cloud
PDF
Cuda fortranの利便性を高めるfortran言語の機能
Resource Aware Scheduling in Apache Storm
Efficient execution of quantized deep learning models a compiler approach
Improving GStreamer performance on large pipelines: from profiling to optimiz...
Mastering GC.pdf
golang profiling の基礎
生成AIが切り拓く新しいゲームの創り方・遊び方
High Performance, Scalable MongoDB in a Bare Metal Cloud
Cuda fortranの利便性を高めるfortran言語の機能

What's hot (20)

PDF
脆弱性スキャナVuls(応用編)
PDF
[143] Modern C++ 무조건 써야 해?
PPTX
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
PDF
[D35] インメモリーデータベース徹底比較 by Komori
PDF
My sql 5.6 master slave and master-master replication.step by step configurat...
PPTX
〜Apache Geode 入門 gfsh によるクラスター構築・管理
PDF
PostgreSQL WAL for DBAs
PPT
IBGPのコンバージェンスの改善qunog3
PPTX
PHPとシグナル、その裏側
PDF
Gstreamer Basics
PDF
What Every Developer Should Know About Database Scalability
PDF
Mmorpg의 재미 평가 모델에 관한 연구(2쇄수정)
PPTX
講演資料: コスト最適なプライベートCDNを「NGINX」で実現するWeb最適化セミナー
PPTX
Elasticsearch as a search alternative to a relational database
PDF
Ceph Object Storage Performance Secrets and Ceph Data Lake Solution
PDF
FPGA・リコンフィギャラブルシステム研究の最新動向
PDF
運用中の大規模オンラインゲームで 8年ぶりにPHPバージョンアップをした話
PDF
行ロックと「LOG: process 12345 still waiting for ShareLock on transaction 710 afte...
PDF
객체지향 개념 (쫌 아는체 하기)
PPTX
Linuxのsemaphoreとmutexを見る 
脆弱性スキャナVuls(応用編)
[143] Modern C++ 무조건 써야 해?
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
[D35] インメモリーデータベース徹底比較 by Komori
My sql 5.6 master slave and master-master replication.step by step configurat...
〜Apache Geode 入門 gfsh によるクラスター構築・管理
PostgreSQL WAL for DBAs
IBGPのコンバージェンスの改善qunog3
PHPとシグナル、その裏側
Gstreamer Basics
What Every Developer Should Know About Database Scalability
Mmorpg의 재미 평가 모델에 관한 연구(2쇄수정)
講演資料: コスト最適なプライベートCDNを「NGINX」で実現するWeb最適化セミナー
Elasticsearch as a search alternative to a relational database
Ceph Object Storage Performance Secrets and Ceph Data Lake Solution
FPGA・リコンフィギャラブルシステム研究の最新動向
運用中の大規模オンラインゲームで 8年ぶりにPHPバージョンアップをした話
行ロックと「LOG: process 12345 still waiting for ShareLock on transaction 710 afte...
객체지향 개념 (쫌 아는체 하기)
Linuxのsemaphoreとmutexを見る 
Ad

More from Wen Liao (18)

PDF
Hello world 的一生
PDF
Notes on oracle solaris 11.3 linkers and libraries guide chapter one
PDF
開放街圖 自助旅行的好幫手
PDF
GNU AS簡介
PDF
UPnP 1.0 簡介
PDF
故事:自由軟體和 Richard Stallman
PDF
Hello world在那邊?背景說明
PDF
A successful git branching model 導讀
PDF
GNU ld的linker script簡介
PDF
Trace 程式碼之皮
PDF
淺談Debian套件打包
PDF
GNU Make, Autotools, CMake 簡介
PDF
A Brief Introduction to Regular Expression with Python 2.7.3 Standard Library
PDF
GNU gettext簡介 - 以C語言為範例
PDF
Testing in python 2.7.3
PDF
從組裝軟體中談談軟體發展管理
PDF
軟體組裝心得分享
PDF
Introduce to Linux command line
Hello world 的一生
Notes on oracle solaris 11.3 linkers and libraries guide chapter one
開放街圖 自助旅行的好幫手
GNU AS簡介
UPnP 1.0 簡介
故事:自由軟體和 Richard Stallman
Hello world在那邊?背景說明
A successful git branching model 導讀
GNU ld的linker script簡介
Trace 程式碼之皮
淺談Debian套件打包
GNU Make, Autotools, CMake 簡介
A Brief Introduction to Regular Expression with Python 2.7.3 Standard Library
GNU gettext簡介 - 以C語言為範例
Testing in python 2.7.3
從組裝軟體中談談軟體發展管理
軟體組裝心得分享
Introduce to Linux command line
Ad

Guide to GStreamer Application Development Manual: CH1 to CH10