About GStreamer 1.0 application development for beginners
-
Upload
shota-tamura -
Category
Technology
-
view
2.360 -
download
26
Transcript of About GStreamer 1.0 application development for beginners
目標
- GStreamer の全体像と構成要素についてざっくり知ってもらう
- 私が半年間やって知ったことの 6, 7割くらいをこの1時間で知ってもらう
目次
- 1. GStreamer 概要- 全体像- 構成要素
- 2. もう少し詳しいこと- 内部構造的なこと- 実践的なこと
- GStreamer Tips
GStreamer とは
image from: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-gstreamer.html
GStreamer とは
GStreamerは、オープンソースのマルチメディアフレームワークです。
小さなコアライブラリに様々な機能をプラグインとして追加できるようになっており、多彩な形式のデータを扱うことができます。
※ Armadillo-840 製品マニュアル引用
ちなみに
GStreamer は- オブジェクト指向な C で書かれています- Linux, Windows, Android, iOS, OS X で使えます- バージョンは
- 偶数が stable (..., 1.2, 1.4, ...)- 奇数が unstable (..., 1.3, 1.5, ….)
2015/6/7 に 1.5.1 (unstable) がリリースされている、活発なライブラリです。
全体像
image from: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-intro-basics-communication.html
全体像
GStreamerが提供
全体像
ユーザーが実装
全体像: Thread
GStreamer Application は大きく分けて 2 種類の Thread から成る
Application thread
Streaming threads
全体像: Bus
Application thread
Streaming threads
2つの Thread をつなぐ Bus
GStreamer の bus は
Streaming threads が自らの Context をApplication thread に伝えるためのシステム
※翻訳が間違ってたらすいません
Streaming thread について
Application thread
Streaming threads
Pipeline
Top-level Bin
自分の bus を持っている image from: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-helloworld.html
Bin
Element の集まり
自分の bus は持っていない
image from: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-helloworld.html
Element
4種類のElement- Src element- Filter element- Filter element (Pad が3つ以上)- Sink element
Pad
Element
srcsink
Pad
Pad
Element
srcsink
PadPad は Element の外界へのインターフェース
- Element 同士では- 接続 (Link)- Buffer の受け渡し- Event の受け渡し- etc...
State Change
NULL READY PAUSED PLAYING
NULL READY PAUSED PLAYING
詳しくはこちらを参照http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-elements-states.html
Preroll は State ではありません
Preroll を気にするのは Sink Element だけ ↓
ちなみに
NULL READY PAUSED PLAYING
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/chapter-other-base.html#section-base-sink
Prerolling
Prerolled
Communication
まとめ
- GStreamer Application は2つ以上の Thread から成る
- Application thread - Streaming threads
- Bus は Application thread と Streaming threadの架け橋
- Pipeline- Bus を持っている Bin
- Bin- Element の集まり
- Pad- Element の外界への
インターフェース- Element States
- NULL, READYPAUSED, PLAYING
- Communication- Buffer, Event,
Message, Query
2. もう少し詳しいことを
- 内部構造的なこと- Buffer / Event flow- Thread について
- 実践的なこと- 簡単な GStreamer アプリの作り方- Appsink の使い方
Buffer flow
Buffer flow: GstBufferstruct GstBuffer { GstMiniObject mini_object;
GstBufferPool *pool;
/* timestamp */ GstClockTime pts; GstClockTime dts; GstClockTime duration;
/* media specific offset */ guint64 offset; guint64 offset_end;};
Buffer flow: GstBufferImpltypedef struct{ GstBuffer buffer; gsize slice_size;
/* the memory blocks */
guint len; GstMemory *mem[GST_BUFFER_MEM_MAX];
/* memory of the buffer when allocated from 1 chunk */ GstMemory *bufmem;
/* FIXME, make metadata allocation more efficient by usingpart of the * GstBufferImpl */ GstMetaItem *item;} GstBufferImpl;
GstBuffer は複数の不連続なメモリ領域を持つことがある
gst_buffer_map() でこれを連続領域にすることができる
Buffer flow
filter element
srcsink
sink element
sink_chain ()
pad_push ()
gst_XXXXX_chain () →省略→ _chain()
実際の名前は)- gst_video_encoder_chain ()- gst_queue_chain ()- gst_qtdemux_chain ()- etc...
なぜ _chain () ?
Event flow
Event flow
filter element
srcsink
sink element
sink_sink_event ()
pad_push_event ()
Event flow
filter element
srcsink
sink element
sink_src_event ()
pad_push_event ()
Event は downstream から upstream へ行くこともある
Event flow: _sink_event()switch (GST_EVENT_TYPE(event)) {case GST_EVENT_CAPS:
[..]
case GST_EVENT_EOS:
[..]case GST_EVENT_STREAM_START:
[..]
case GST_EVENT_SEGMENT:[..]
default:ret = GST_VIDEO_ENCODER_CLASS (parent_class)->sink_event(enc,
event);break;
}
_chain (), _sink_event ()Pad に 何か が来た時の処理は、 Pad に登録する
gst_pad_set_chain_function (basesink->sinkpad,gst_base_sink_chain);
gst_pad_set_event_function (
qtdemux->sinkpad,
gst_qtdemux_handle_sink_event);
ちなみに
gst-launch の -e オプションは pipeline に EOS Event を送ります
gst-launch
pipelinebin
filter element
srcsink
sink element
sink
src element
src
Threadqueue は内部で GstTask を使っているのでThread が増える
GstTask は pthread の wrapper libraryimage from: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-threads-uses.html
Thread を見る
GDBで
- queue を使わなくても、2 Thread- application thread : main()- streaming thread : _chain(), etc...
もう少し詳しいことを
- 内部構造的なこと- Buffer / Event flow- Thread について
- 実践的なこと- 簡単な GStreamer アプリの作り方- Appsink の使い方
絶対 に書くこと
#include <gst/gst.h>
int main (int argc, char *argv[])
{
gst_init (&argc, &argv);
return 0;
}
GStreamer App の作り方
GStreamer App の作り方
xvimagesinksink
pipelinegst_pipeline_new ()
gst_element_factory_make ()
gst_element_factory_make ()videotestsrc
src
GStreamer App の作り方
pipeline
videotestsrcsrc
videotestsrcsrc
xvimagesinksink
xvimagesinksink
gst_bin_add ()
gst_bin_add ()
GStreamer App の作り方
pipeline
videotestsrcsrc
xvimagesinksink
gst_element_link ()
GStreamer App の作り方
gst_element_set_state (pipeline, GST_STATE_PLAYING);
pipeline
videotestsrcsrc
xvimagesinksink
GStreamer App の作り方
gst_element_get_bus (pipeline)
pipeline
videotestsrcsrc
xvimagesinksink
bus
GStreamer App の作り方
gst_bus_timed_pop_filtered ()
pipeline
videotestsrcsrc
xvimagesinksink
bus
Application
AppSink の使い方
AppSink (AppSrc) は
Plugin Element を作成せずとも、
Element 内の処理をユーザーが実装できる Element
“new-sample” や “eos” など用意されているコールバック関数に
自分で実装した関数 (処理) を登録するだけ
とっても簡単
AppSink の使い方
用意されているコールバック関数は inspect で確認
$ gst-inspect-1.0 appsink[..]Element Signals: "eos" : void user_function (GstElement* object, gpointer user_data); "new-preroll" : GstFlowReturn user_function (GstElement* object, gpointer user_data); "new-sample" : GstFlowReturn user_function (GstElement* object, gpointer user_data);
AppSink の使い方
例えば、new-sample を使う場合
$ gst-inspect-1.0 appsink[..]Element Signals: "eos" : void user_function (GstElement* object, gpointer user_data); "new-preroll" : GstFlowReturn user_function (GstElement* object, gpointer user_data); "new-sample" : GstFlowReturn user_function (GstElement* object, gpointer user_data);
AppSink の使い方
GstFlowReturn cb_new_sample (GstAppSink *sink, gpointer data){ [..]}int main (int argc, char *argv[]){ GstElemet *appsink_element; [..] g_signal_connect ( appsink_element, "new-sample", G_CALLBACK (cb_new_sample), &data); [..]}
GStreamer Tips公式サイト
- http://gstreamer.freedesktop.org/
公式ドキュメントはこちら
- http://gstreamer.freedesktop.org/documentation/
GStreamer Tips欲しいプラグインがあるか調べるときは
- コマンドラインで- gst-inspect-1.0 | grep -i xxxxxxxx
- ウェブページで- http://gstreamer.freedesktop.org/documentation/plugins.html- ※ Windows 用の ksvideosrc などはここに無いので基本 inspect で!
GStreamer TipsGStreamer のコードを読むなら
これらすべてを clone してタグを作ろう
- gstreamer- http://gstreamer.freedesktop.org/modules/
- glib-2.0 (大事)- https://git.gnome.org/browse/glib/
GStreamer TipsGStreamer のコードを読むなら
Devhelp が 便利
$ sudo apt-get install devhelp \ gstreamer1.0-plugins-xxxxx-doc \ gstreamer1.0-doc \ libglib2.0-doc
Vim や Emacs に Devhelp への
サポートプラグインがあるのでそれも一緒に。
GStreamer Tipsサンプルコードが欲しい時は
タグを作ったディレクトリで
$ find -type f | grep examples | grep -e '\.c'
結果
./gst-plugins-good/tests/examples/v4l2/camctrl.c ./gstreamer/tests/examples/queue/queue.c ./gst-plugins-base/tests/examples/app/appsrc_ex.c ./gst-plugins-base/tests/examples/app/appsink-src.c ./gst-plugins-base/tests/examples/app/appsrc-stream.c [..]
GStreamer Tips自分でビルドした GStreamer ライブラリを使うには
- Element そのものをビルドした時- GST_PLUGIN_PATH_1_0=/set/lib/path/.lib gst-launch-1.0 ....
- Element が使う so をビルドした時- LD_LIBRARY_PATH=/home/atmark/src/gst-plugins-acm/gst-plugin/src/.libs gst-launch-1.0
…
GStreamer Tipsplaybin や decodebin、rtpbin など既存の Bin の中で、
どの Element が動いているかを知りたい時
http://manual.atmark-techno.com/armadillo-840/armadillo-840_product_manual_ja-1.5.1/ch15.html#sct.acm.about_gst_pipeline_img
GStreamer Tips個人的によく使うもの
- src element- filesrc, multifilesrc, videotestsrc, v4l2src
- filter element- capsfilter, queue, identity, videoconvert- avdec_h264, x264enc, h264parse, qtmux, qtdemux
- sink element- filesink, multifilesink, fakesink, ximagesink
PC 上で映像を確認したいときは xvimagesink (videoconvert + ximagesink)が便利!!
GStreamer Tipsいちおしの 3つ
- multifilesrc
- identity
- fakesink
multifilesrc location=”hoge%02d.txt” num-buffers=100multifilesrc location=”piyo%d.txt” loop=true
identity datarate=1024 drop-probability=0.3
※ “handoff” シグナルがあるので、bufferが通過するごとになにか処理させることも可能
fakesink num-buffers=30 sync=true async=falsefakesink dump=true
GStreamer Tipsgst-launch の Pipeline の読みやすい書き方
読みやすい :)gst-launch-1.0 \filesrc location=/mnt/big-buck-bunny-30sec-fullhd.mp4 ! qtdemux name=demux0 \demux0.audio_0 ! queue ! acmaacdec ! audioresample ! audio/x-raw,rate=48000,channels=2 ! alsasink \demux0.video_0 ! queue ! acmh264dec ! acmfbdevsink device=/dev/fb0
読みにくい :(gst-launch-1.0 filesrc location=/mnt/big-buck-bunny-30sec-fullhd.mp4 \! qtdemux name=demux0 demux0.audio_0 ! queue ! acmaacdec ! audioresample \! audio/x-raw,rate=48000,channels=2 ! alsasink demux0.video_0 ! queue \! acmh264dec ! acmfbdevsink device=/dev/fb0
GstElementstruct GstElement { GRecMutex state_lock;
/* element state */ GCond state_cond; guint32 state_cookie; GstState target_state; GstState current_state; GstState next_state; GstState pending_state; GstStateChangeReturn last_return;
GstBus *bus;
/* allocated clock */ GstClock *clock; GstClockTimeDiff base_time; GstClockTime start_time;
guint16 numpads; GList *pads; guint16 numsrcpads; GList *srcpads; guint16 numsinkpads; GList *sinkpads; guint32 pads_cookie;};
GstElementstruct GstElement { GRecMutex state_lock;
/* element state */ GCond state_cond; guint32 state_cookie; GstState target_state; GstState current_state; GstState next_state; GstState pending_state; GstStateChangeReturn last_return;
GstBus *bus;
/* allocated clock */ GstClock *clock; GstClockTimeDiff base_time; GstClockTime start_time;
guint16 numpads; GList *pads; guint16 numsrcpads; GList *srcpads; guint16 numsinkpads; GList *sinkpads; guint32 pads_cookie;};
Object Hierarchy
GObject ╰── GInitiallyUnowned ╰── GstObject ╰── GstElement ╰── GstQueue
GObject ╰── GInitiallyUnowned ╰── GstObject ╰── GstElement ╰── GstBaseSink ╰── GstFileSink
GObject ╰── GInitiallyUnowned ╰── GstObject ╰── GstElement ╰── GstBaseSrc ╰── GstPushSrc ╰── GstUDPSrc
Object HierarchyPipeline も Element
GObject ╰── GInitiallyUnowned ╰── GstObject ╰── GstElement ╰── GstBin ╰── GstPipeline
Object HierarchyPad はインターフェースなので Element ではない
GObject ╰── GInitiallyUnowned ╰── GstObject ╰── GstPad