About GStreamer 1.0 application development for beginners

Post on 12-Jan-2017

2360 Views

Category:

Technology

26 Downloads

Preview:

Click to see full reader

Transcript

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, 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

top related