More Related Content Similar to Guide to GStreamer Application Development Manual: CH1 to CH10 (20) Guide to GStreamer Application Development Manual: CH1 to CH105. Background
● Framework
○ Longman:
■ the main supporting parts of a building, vehicle,
or object
● http://www.ldoceonline.com/dictionary/framework
● Software framework
○ 一般性,可重複使用的軟體平台
○ 用於降降低開發軟體的成本
8. Element and Pipeline in GStreamer:
Series of Producer - Consumer
http://en.wikipedia.org/wiki/GStreamer#Technical_overview
PAD
兩邊有協定溝
通決定要傳送
那些資料
兩邊有協定溝
通決定要傳送
那些資料
16. 一般Element
● 有輸入有輸出
● 應用:
○ Filters
○ convertors
○ demuxers
○ muxers
○ codecs
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-elements.html
18. 產生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
19. 產生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
23. 範例
/* 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
24. 接關
/* 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
26. 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.
27. 關於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
29. Pad
● Element的input/output部份
○ Sink: Input
○ Source: Output
● Element之間的連結方式
● GStreamer允許element之間透過negociate
決定link以及資料傳輸方式
○ GstCaps
■ GStreamer capabilities of an element
● 想像螢幕可以顯示HDMI或是VGA訊號,這些
信號線就是PAD
30. 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
33. 取得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
37. 範例
/* 產生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
41. Pipeline
● Pipeline
○ 一種bin
○ 最高層的bin,和一般bin的差別是他提供介面給應用程
式控制
○ 實作上面,每個pipe都是單獨的thread
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-intro-basics-bins.html
43. 範例
/* 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
44. 範例
/* 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
51. 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
52. 使用GLib/Gtk+ main loop 處理message (1)
● 撰寫callback,撈想看的event
● 應用程式中
○ 告訴main loop要聽bus event,前面的callback為參數
○ 啟動main loop
53. 範例
/* 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
54. 範例
/* 以下都在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
55. 使用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
56. Messages
● 格式
○ message source
■ 從哪個element送出
○ message type
○ timestamp
● 分類
○ 錯誤或警告通知
○ 播放結束通知 (EOS)
○ Tag:和metadata 相關
○ 狀態改變,如從PLAYING轉換到PAUSE
○ 緩衝相關
○ Element自訂訊息
58. More about Buffer
● GStreamer element之間實際傳送的多媒體資
料
● GStreamer幫你弄buffer 機制
● 包含
○ 指標
○ timestamp
○ reference count。減到零自動GG
○ flag
59. 典型Buffer生命週期
● Source element: 新增分配、分配記憶體空間、
放資料、傳給Sink element
● Sink element: 從buffer讀資料、處理資料、
unreference buffer、framework發現reference
count變為0所以釋放相關資源
68. 很囉唆的細節,請自行斟酌
/* 1. Element訊息處理Callback */
bus_call (...)
{
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_main_loop_quit (loop);
break;
...
}
}
播放結束處理
69. 很囉唆的細節,請自行斟酌
/* 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
71. 很囉唆的細節,請自行斟酌
/* 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");
72. 很囉唆的細節,請自行斟酌
/* 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
73. 很囉唆的細節,請自行斟酌
/* 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
吃的參數
75. 很囉唆的細節,請自行斟酌
/* 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)就會到這邊
77. 編譯參數
● 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
80. 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/