CoreElements について


CoreElements とは
-------------------

名前の通り、**基本的な** Element群のことです。
Linux 使いなら`cat`, `echo`, `grep`, `sed`... などイメージしてもらうと近いかも...?

### CoreElement 一覧

Linux, Windows で  `fdsrc` といった OS に依存する部分以外はまったく同じであることがわかります。

#### @Debian (testing: gstreamer 1.6.1)

```shell-session
$ gst-inspect-1.0|grep core|sort
coreelements:  capsfilter: CapsFilter
coreelements:  concat: Concat
coreelements:  downloadbuffer: DownloadBuffer
coreelements:  fakesink: Fake Sink
coreelements:  fakesrc: Fake Source
coreelements:  fdsink: Filedescriptor Sink
coreelements:  fdsrc: Filedescriptor Source
coreelements:  filesink: File Sink
coreelements:  filesrc: File Source
coreelements:  funnel: Funnel pipe fitting
coreelements:  identity: Identity
coreelements:  input-selector: Input selector
coreelements:  multiqueue: MultiQueue
coreelements:  output-selector: Output selector
coreelements:  queue2: Queue 2
coreelements:  queue: Queue
coreelements:  streamiddemux: Streamid Demux
coreelements:  tee: Tee pipe fitting
coreelements:  typefind: TypeFind
coreelements:  valve: Valve element
```

#### @Windows (msys: gstreamer 1.6.1)

```shell-session
$  gst-inspect-1.0|grep core|sort    
coreelements:  capsfilter: CapsFilter
coreelements:  concat: Concat
coreelements:  downloadbuffer: DownloadBuffer
coreelements:  fakesink: Fake Sink
coreelements:  fakesrc: Fake Source
coreelements:  filesink: File Sink
coreelements:  filesrc: File Source
coreelements:  funnel: Funnel pipe fitting
coreelements:  identity: Identity
coreelements:  input-selector: Input selector
coreelements:  multiqueue: MultiQueue
coreelements:  output-selector: Output selector
coreelements:  queue: Queue
coreelements:  queue2: Queue 2
coreelements:  streamiddemux: Streamid Demux
coreelements:  tee: Tee pipe fitting
coreelements:  typefind: TypeFind
coreelements:  valve: Valve element
```

CoreElements をいくつか使ってみる
---------------------------------------

GStreamer のパイプラインアーキテクチャの基本となる Element 群ですから、一度触っておいても損はありません。
以下は Linux で触ってみる場合を紹介しています。また、windows の場合は `ximagesink` を `d3dvideosink` または `autovideosink` に置き換えると動きます。


### queue

```bash
#!/bin/sh

gst-launch-1.0 videotestsrc ! queue ! ximagesink
```

いわゆる、スタックとキューの「キュー」です。
`videotestsrc ! ximagesink` と見た目は変わりませんが、gdb などで thread を見てみると `queue` の有無で thread 数が違うので、確認してみてくださいね。

また、thread 数の違いの理由については 1日目 のスライドに書いていたはず...

### tee

linux のコマンドの `tee` と同じです。

パイプラインを1 to Nにします。
忘れがちなのですが、`tee` を使った時には、以下のように `queue` を使う必要があります。

なんで動かないかについても、 1日目のスライドに書いてたような、書いてなかったような...

```bash
#!/bin/sh

gst-launch-1.0 -q \
videotestsrc ! tee name=t \
t. ! queue ! ximagesink \
t. ! queue ! ximagesink \
t. ! queue ! ximagesink \
t. ! queue ! ximagesink
```

### concat

これも Linux のコマンドの `concat` と同じです。

`num-buffers` という `videotestsrc` から *何枚バッファを取り出すか* のオプションを設定しないと、どんなエレメントなのか実感できないので注意です。

```bash
#!/bin/sh

gst-launch-1.0 \
concat name=c ! videoconvert ! ximagesink \
videotestsrc num-buffers=100 pattern=ball ! c. \
videotestsrc num-buffers=100              ! c.
```

### valve`

ご存じ、[バルブ](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%AB%E3%83%96)です。

`drop=true` に設定すれば、下流にバッファが**流れなく**なり、
`drop=false` にすれば、下流にバッファが**流れる**ようになります。

```bash
#!/bin/sh

gst-launch-1.0 videotestsrc ! valve drop=true ! ximagesink
```

gst-launch を使う範囲ではたぶんお世話になることがなさそう...

複数の src element から入力を受けて、まとめて1枚の画面にしたりする時で、「いまはここの入力だけ表示したい！」なんてことをするためには使えそうですね。

### identity

とっても便利な filter element です。

以下のように指定すると、50% ほどフレームドロップします。
実行しみると「カクカク」するはずです。

```bash
#!/bin/sh

gst-launch-1.0 videotestsrc pattern=ball ! identity drop-probability=0.5 ! ximagesink
```

また、identity にはとっても便利な `handoff` という Element Signal があります。

これは、identity が下流にバッファを渡す直前に発生するシグナルで、このシグナルに対するコールバックを書くことで、どんなバッファを下流に渡そうとしているか?などをチェックすることができます。

### typefind

どんなデータかを調べてくれます(`-v`オプションつければユーザーに教えてくれます)

具体的には、以下のような jpegファイルを typefind に食わせると

```bash
#!/bin/sh

gst-launch-1.0 -v filesrc location=hello.jpg ! typefind ! fakesink
```

このような結果が得られます。

```text
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstTypeFindElement:typefindelement0.GstPad:src: caps = "image/jpeg\,\ width\=\(int\)400\,\ height\=\(int\)400\,\ sof-marker\=\(int\)0"
/GstPipeline:pipeline0/GstFakeSink:fakesink0.GstPad:sink: caps = "image/jpeg\,\ width\=\(int\)400\,\ height\=\(int\)400\,\ sof-marker\=\(int\)0"
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Got EOS from element "pipeline0".
Execution ended after 0:00:00.000508308
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
```

大事なのは...

```text
"image/jpeg\,\ width\=\(int\)400\,\ height\=\(int\)400\,\ sof-marker\=\(int\)0"
```

`image/jpeg` の `width, height = 400` のファイルであるということがわかりました！

さて、なにに使うでしょう?

どんなファイルなのかをチェックする機構があれば、動的に使用するElementを変えることができます。

つまり deocodebin のようなことを自前で書けるようになり、書けるアプリの幅が広がります :)

まとめ
-------

いくか CoreElements を見てみました。

よく使われている omxh264dec の中がどうなっているか? autovidoesink の中がどうなっているのか? が垣間見えたかもしれませんね。

基本的な要素を知っておけば、応用がききますし、車輪の再発明をしなくて済みます。

今日はそんな内容でした。

明日は msys2 を使って windows 上で GStreamer と戯れる方法をご紹介しますー