GStreamer 1.0
Atmark-techno Inc.
Dev, ShotaTAMURA
shota.tamura@atmark-techno.com
目標
- 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, READY
PAUSED, PLAYING
- Communication
- Buffer, Event,
Message, Query
2. もう少し詳しいことを
- 内部構造的なこと
- Buffer / Event flow
- Thread について
- 実践的なこと
- 簡単な GStreamer アプリの作り方
- Appsink の使い方
Buffer flow
Buffer flow: GstBuffer
struct GstBuffer {
GstMiniObject
mini_object;
GstBufferPool *pool;
/* timestamp */
GstClockTime pts;
GstClockTime dts;
GstClockTime duration;
/* media specific offset */
guint64 offset;
guint64 offset_end;
};
Buffer flow: GstBufferImpl
typedef 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
pipeline
bin
filter element
srcsink
sink element
sink
src element
src
Thread
queue は内部で GstTask を使っているのでThread が増える
GstTask は pthread の wrapper library
image 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 の作り方
xvimagesink
sink
pipeline
gst_pipeline_new ()
gst_element_factory_make ()
gst_element_factory_make ()
videotestsrc
src
GStreamer App の作り方
pipeline
videotestsrc
src
videotestsrc
src
xvimagesink
sink
xvimagesink
sink
gst_bin_add ()
gst_bin_add ()
GStreamer App の作り方
pipeline
videotestsrc
src
xvimagesink
sink
gst_element_link ()
GStreamer App の作り方
gst_element_set_state (pipeline, GST_STATE_PLAYING);
pipeline
videotestsrc
src
xvimagesink
sink
GStreamer App の作り方
gst_element_get_bus (pipeline)
pipeline
videotestsrc
src
xvimagesink
sink
bus
GStreamer App の作り方
gst_bus_timed_pop_filtered ()
pipeline
videotestsrc
src
xvimagesink
sink
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 Tips
GStreamer のコードを読むなら
これらすべてを clone してタグを作ろう
- gstreamer
- http://gstreamer.freedesktop.org/modules/
- glib-2.0 (大事)
- https://git.gnome.org/browse/glib/
GStreamer Tips
GStreamer のコードを読むなら
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 Tips
playbin や 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=100
multifilesrc location=”piyo%d.txt” loop=true
identity datarate=1024 drop-probability=0.3
※ “handoff” シグナルがあるので、bufferが通過するごとになにか処理させることも可能
fakesink num-buffers=30 sync=true async=false
fakesink dump=true
GStreamer Tips
gst-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
GstElement
struct 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;
};
GstElement
struct 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 Hierarchy
Pipeline も Element
GObject
╰── GInitiallyUnowned
╰── GstObject
╰── GstElement
╰── GstBin
╰── GstPipeline
Object Hierarchy
Pad はインターフェースなので Element ではない
GObject
╰── GInitiallyUnowned
╰── GstObject
╰── GstPad

About GStreamer 1.0 application development for beginners