80
GStreamer Application Development Manual 導讀 第一章到第十章 Wen Liao

Guide to GStreamer Application Development Manual: CH1 to CH10

Embed Size (px)

DESCRIPTION

Change log: May/13/2014: Revise description for PAUSE state

Citation preview

Page 1: Guide to GStreamer Application Development Manual: CH1 to CH10

GStreamerApplication Development Manual 導讀

第一章到第十章

Wen Liao

Page 2: Guide to GStreamer Application Development Manual: CH1 to CH10

目標

了解GStreamer是什麼

Page 3: Guide to GStreamer Application Development Manual: CH1 to CH10

注意

● 只包含手冊第一章到第十章● 可能有誤,請自行斟酌對照手冊● 請留意囉唆的程式碼變數顏色

my_var = my_func();

my_hash(my_var);

Page 4: Guide to GStreamer Application Development Manual: CH1 to CH10

Outline

● Backgrounds● Overview● Demo● References

Page 5: Guide to GStreamer Application Development Manual: CH1 to CH10

Background

● Framework○ Longman:

■ the main supporting parts of a building, vehicle, or object● http://www.ldoceonline.com/dictionary/framework

● Software framework○ 一般性,可重複使用的軟體平台○ 用於降降低開發軟體的成本

Page 6: Guide to GStreamer Application Development Manual: CH1 to CH10

Multimedia Framework

● 一種Software framework● 專門來處理多媒體相關應用程式

○ 多媒體播放器○ 多媒體格式轉換○ 多媒體編輯器○ Video conference○ ….

Page 7: Guide to GStreamer Application Development Manual: CH1 to CH10

GStreamer

● 一種Multimedia framework● 以基於C語言開發的GObject發展● 支援多平台● LGPL

Page 8: Guide to GStreamer Application Development Manual: CH1 to CH10

Element and Pipeline in GStreamer:Series of Producer - Consumer

http://en.wikipedia.org/wiki/GStreamer#Technical_overviewPAD

兩邊有協定溝通決定要傳送那些資料

兩邊有協定溝通決定要傳送那些資料

Page 9: Guide to GStreamer Application Development Manual: CH1 to CH10

Plugin

● 一種Element● 大部分以static library形式● 種類

○ codec○ container formats○ IO driver

Page 11: Guide to GStreamer Application Development Manual: CH1 to CH10

Outline

● Backgrounds● Overview ● Demo● References

Page 12: Guide to GStreamer Application Development Manual: CH1 to CH10

前情提要

http://en.wikipedia.org/wiki/GStreamer#Technical_overviewPAD

兩邊有協定溝通決定要傳送那些資料

兩邊有協定溝通決定要傳送那些資料

Page 13: Guide to GStreamer Application Development Manual: CH1 to CH10

Overview

● Element● Pad● Bin and pipeline● Communication

Page 14: Guide to GStreamer Application Development Manual: CH1 to CH10

Element

● 提供基本功能的元件。可以透過Pad和其他Element組合。○ 播放聲音○ 讀取檔案○ 透過網路取得多媒體內容○ 多媒體解碼○ …

● 分類○ Source element○ 一般element○ Sink element

Page 15: Guide to GStreamer Application Development Manual: CH1 to CH10

Source Element

● 從檔案或是音效卡讀出資料用

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html

Page 16: Guide to GStreamer Application Development Manual: CH1 to CH10

一般Element

● 有輸入有輸出● 應用:

○ Filters○ convertors○ demuxers○ muxers○ codecs

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html

Page 17: Guide to GStreamer Application Development Manual: CH1 to CH10

Sink Element

● 單純Consume資料,通常就是Render或是音效卡

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html

Page 18: Guide to GStreamer Application Development Manual: CH1 to CH10

產生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

Page 19: Guide to GStreamer Application Development Manual: CH1 to CH10

產生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

Page 20: Guide to GStreamer Application Development Manual: CH1 to CH10

Element

● gst-inspect指令可以顯示系統可用的element資訊

● GstElement資料結構繼承自GObject○ 可用GObject的屬性○ 可用GObject的signal及對應的callback○ GObject資訊

■ https://developer.gnome.org/gobject/stable/rn01.html

Page 21: Guide to GStreamer Application Development Manual: CH1 to CH10

Element和Factory

● GstElementFactory○ Framework maintain所有系統上可以用的plugin

(element)資訊(metadata)■ ex:

● gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_DESCRIPTION))

○ 這些metadata可以用來確認目前element和element之間是否可以互相連接

Page 22: Guide to GStreamer Application Development Manual: CH1 to CH10

連接Elements

1. 產生pipeline2. 決定並產生elements3. 把elements打包成bin

a. (要記得pipeline是bin的一種)

4. 建立link

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-elements-link.html

Page 23: Guide to GStreamer Application Development Manual: CH1 to CH10

範例

/* 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

Page 24: Guide to GStreamer Application Development Manual: CH1 to CH10

接關

/* 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

Page 25: Guide to GStreamer Application Development Manual: CH1 to CH10

Element內部狀態

● GST_STATE_NULL○ 建立時預設狀態○ 內部沒有分配任何資源○ 狀態被設成NULL framework會自動清除資源○ 當reference count為零時必須要在該狀態

● GST_STATE_READY○ 資源已配置或是被reset掉

Page 26: Guide to GStreamer Application Development Manual: CH1 to CH10

Element內部狀態

● GST_STATE_PAUSED○ 資源已分配並可以執行,但是偏不去處理資料○ 此時可以趁機更動控制資料以達到trick play的目的○ 必須假設馬上就會被play的情況

● GST_STATE_PLAYING○ 和PAUSE差別就是會去處理資料○ 精確的說法,是clock有沒有在run的差別

■ 在這邊有解釋clock● http://gstreamer.freedesktop.

org/data/doc/gstreamer/head/manual/html/chapter-clocks.

html#section-clock-time-types

Page 27: Guide to GStreamer Application Development Manual: CH1 to CH10

關於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 statechange

Downward state change

Page 28: Guide to GStreamer Application Development Manual: CH1 to CH10

Overview

● Element● Pad● Bin and pipeline● Communication

Page 29: Guide to GStreamer Application Development Manual: CH1 to CH10

Pad

● Element的input/output部份○ Sink: Input○ Source: Output

● Element之間的連結方式● GStreamer允許element之間透過negociate

決定link以及資料傳輸方式○ GstCaps

■ GStreamer capabilities of an element● 想像螢幕可以顯示HDMI或是VGA訊號,這些

信號線就是PAD

Page 30: Guide to GStreamer Application Development Manual: CH1 to CH10

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

Page 31: Guide to GStreamer Application Development Manual: CH1 to CH10

Capabilities

● 支援的屬性稱為property○ Key: 字串○ Value:

■ 基本type如int, float■ Range: 如1~100■ List

● 多個基本type■ Array

● 多個相同的基本type

Page 32: Guide to GStreamer Application Development Manual: CH1 to CH10

Capabilities

● 想像Mimetype● 用途

○ PnP○ 檢查相容性○ 提供Metadata○ Filter,限制處理的資料特性

Page 33: Guide to GStreamer Application Development Manual: CH1 to CH10

取得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 available\n");return;

}http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-caps-api.html

Page 34: Guide to GStreamer Application Development Manual: CH1 to CH10

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);

Page 35: Guide to GStreamer Application Development Manual: CH1 to CH10

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

Page 36: Guide to GStreamer Application Development Manual: CH1 to CH10

建立Ghost Pad

● 產生element和bin● 把element打包到bin● link element內部● 產生Ghost Pad

Page 37: Guide to GStreamer Application Development Manual: CH1 to CH10

範例

/* 產生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

Page 38: Guide to GStreamer Application Development Manual: CH1 to CH10

Overview

● Element● Pad● Bin and pipeline● Communication

Page 39: Guide to GStreamer Application Development Manual: CH1 to CH10

Bin

● Bin○ 一組透過pad連接起來的elements○ GStreamer提供針對bin的操作。只要操作bin,

GStreamer幫你搞定裏面的element。■ 設定狀態■ 傳送錯誤通知■ …

Page 40: Guide to GStreamer Application Development Manual: CH1 to CH10

Bin

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-bins.html

● 精確的來說,Bin是一個container element○ 所有對element/GObject的操作都可以apply到bin

Page 41: Guide to GStreamer Application Development Manual: CH1 to CH10

Pipeline

● Pipeline○ 一種bin○ 最高層的bin,和一般bin的差別是他提供介面給應用程

式控制○ 實作上面,每個pipe都是單獨的thread

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-intro-basics-bins.html

Page 42: Guide to GStreamer Application Development Manual: CH1 to CH10

使用bin

● 產生pipeline給應用程式使用● 產生bin● 產生element處理實體資料● 打包成bin● 告訴pipeline處理bin● 連連看● 開工

Page 43: Guide to GStreamer Application Development Manual: CH1 to CH10

範例

/* 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

Page 44: Guide to GStreamer Application Development Manual: CH1 to CH10

範例

/* 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

Page 45: Guide to GStreamer Application Development Manual: CH1 to CH10

Overview

● Element● Pad● Bin and pipeline● Communication

○ bus and message○ buffer

Page 46: Guide to GStreamer Application Development Manual: CH1 to CH10

Bus

● 用來傳遞GStreamer framework和應用程式之間的訊息

Page 47: Guide to GStreamer Application Development Manual: CH1 to CH10

Communication

● 對象:Pipeline、element、應用程式● 方式

○ buffer object■ 對象:element之間■ 用於傳送Streaming需要的資料■ 單向的從source 到 sink

○ event object■ 對象:

● Element之間● 應用程式到element

■ 雙向■ source 到 sink的event可支援和streaming 同步

Page 48: Guide to GStreamer Application Development Manual: CH1 to CH10

Communication

● 對象:Pipeline、element、應用程式● 方式

○ message object■ 對象:element到應用程式■ 支援同步或非同步方式■ Thread safe

○ Queries object■ 對象:

● 應用程式到pipeline● Element之間

■ 用來讓應用程式查詢狀態如已播放時間等

■ 為同步傳輸。表示應用程式送出query要等到

pipeline回應才能繼續執行。

Page 50: Guide to GStreamer Application Development Manual: CH1 to CH10

Overview

● Element● Pad● Bin and pipeline● Communication

○ bus and message○ buffer

Page 51: Guide to GStreamer Application Development Manual: CH1 to CH10

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

Page 52: Guide to GStreamer Application Development Manual: CH1 to CH10

使用GLib/Gtk+ main loop 處理message (1)

● 撰寫callback,撈想看的event● 應用程式中

○ 告訴main loop要聽bus event,前面的callback為參數○ 啟動main loop

Page 53: Guide to GStreamer Application Development Manual: CH1 to CH10

範例

/* 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

Page 54: Guide to GStreamer Application Development Manual: CH1 to CH10

範例

/* 以下都在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

Page 55: Guide to GStreamer Application Development Manual: CH1 to CH10

使用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

Page 56: Guide to GStreamer Application Development Manual: CH1 to CH10

Messages

● 格式○ message source

■ 從哪個element送出○ message type○ timestamp

● 分類○ 錯誤或警告通知○ 播放結束通知 (EOS)○ Tag:和metadata 相關○ 狀態改變,如從PLAYING轉換到PAUSE○ 緩衝相關○ Element自訂訊息

Page 57: Guide to GStreamer Application Development Manual: CH1 to CH10

Overview

● Element● Pad● Bin and pipeline● Communication

○ bus and message○ buffer

Page 58: Guide to GStreamer Application Development Manual: CH1 to CH10

More about Buffer

● GStreamer element之間實際傳送的多媒體資料

● GStreamer幫你弄buffer 機制● 包含

○ 指標○ timestamp○ reference count。減到零自動GG○ flag

Page 59: Guide to GStreamer Application Development Manual: CH1 to CH10

典型Buffer生命週期

● Source element: 新增分配、分配記憶體空間、放資料、傳給Sink element

● Sink element: 從buffer讀資料、處理資料、unreference buffer、framework發現reference count變為0所以釋放相關資源

Page 60: Guide to GStreamer Application Development Manual: CH1 to CH10

Outline

● Backgrounds● Overview ● Demo● References

Page 61: Guide to GStreamer Application Development Manual: CH1 to CH10

Environment

● Ubuntu 12.04.4 64-bit

Page 62: Guide to GStreamer Application Development Manual: CH1 to CH10

Element Information

● gst-inspect oggdemux○ Class hierarchy○ Details

Page 63: Guide to GStreamer Application Development Manual: CH1 to CH10

手冊Hello World範例程式

● 程式說明● 編譯● Demo

Page 65: Guide to GStreamer Application Development Manual: CH1 to CH10

架構 Recap

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-helloworld.html

ogg為一個container。可放audio/video等資料

vorbis為一種聲音格式需要把解出來的資料轉成音效卡支援的格式

Page 66: Guide to GStreamer Application Development Manual: CH1 to CH10

元件

Elements

Pads

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-helloworld.html

Page 67: Guide to GStreamer Application Development Manual: CH1 to CH10

程式架構

● Element訊息處理Callback● 處理pad add event● 主程式

○ 準備■ 分配資源

● elements● GLib mainloop協助處理message

■ 把element打包成pipeline■ 連連看■ 設定通訊及相關callback

○ 開始執行○ 結束、清場

Page 68: Guide to GStreamer Application Development Manual: CH1 to CH10

很囉唆的細節,請自行斟酌

/* 1. Element訊息處理Callback */bus_call (...){ GMainLoop *loop = (GMainLoop *) data;

switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS:

g_main_loop_quit (loop);break;

... }}

播放結束處理

Page 69: Guide to GStreamer Application Development Manual: CH1 to CH10

很囉唆的細節,請自行斟酌

/* 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

Page 70: Guide to GStreamer Application Development Manual: CH1 to CH10

很囉唆的細節,請自行斟酌

main(...) {... /* 3. 初始化 GStreamer和GLib mainloop */ gst_init (&argc, &argv);

loop = g_main_loop_new (NULL, FALSE);…. /* 接下頁 */

Page 71: Guide to GStreamer Application Development Manual: CH1 to CH10

很囉唆的細節,請自行斟酌

/* 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");

Page 72: Guide to GStreamer Application Development Manual: CH1 to CH10

很囉唆的細節,請自行斟酌

/* 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

Page 73: Guide to GStreamer Application Development Manual: CH1 to CH10

很囉唆的細節,請自行斟酌

/* 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

前面的callbackcallback吃的參數

Page 74: Guide to GStreamer Application Development Manual: CH1 to CH10

很囉唆的細節,請自行斟酌

/* 10. 將pipeline內的elements狀態設為可以播放 */ gst_element_set_state (pipeline, GST_STATE_PLAYING);

/* 11. 開工 */ g_main_loop_run (loop);

Page 75: Guide to GStreamer Application Development Manual: CH1 to CH10

很囉唆的細節,請自行斟酌

/* 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)就會到這邊

Page 76: Guide to GStreamer Application Development Manual: CH1 to CH10

手冊Hello World範例程式

● 程式說明● 編譯● Demo

Page 77: Guide to GStreamer Application Development Manual: CH1 to CH10

編譯參數

● 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

Page 78: Guide to GStreamer Application Development Manual: CH1 to CH10

手冊Hello World範例程式

● 程式說明● 編譯● Demo

Page 79: Guide to GStreamer Application Development Manual: CH1 to CH10

Outline

● Backgrounds● Terminology ● Demo● References