Day 2
GStreamer Advent Calender 2016: Day 9
GStreamer Advent Calender 2016 の 9日目の記事です。
はじめに
Day 2では Boilerplate code をたくさん削って、fakesink
だけが入った Bin を作成しました。
decodetimebin の最終目標は decodebin のような Filleter element ですが、
今回は_とにかくコードをシンプルにするため_に Sink element にしました。
Bin を作成するための手順
Commit Diff を参照しながら Bin を作るために必要な変更を実際に見ていきましょう。
1. Bin を作りたいので Bin を継承する
もともとのコードは Element を継承していたので Bin を継承するには、以下の変更が必要です。
G_DEFINE_TYPE
による宣言の変更- 定義の変更
もちろん、Bin ではなく Element を作成した場合はこの変更は不要です。
2. Element をクラスの中に含めておく
今回は fakesink を使うので、これを decodetimebin クラスに含めておきます。
f805764#diff-ce4664f1c528d9cff0251d7affe82d6dR71
3. インスタンスの初期化
今回の手順の中でインスタンスの初期化が 最も重要 です。
f805764#diff-8e987f947ad52dcce6536866295255f3R126
ここでやっていることは主に2つ
- Element を作成して Bin に入れる
gst_element_factory_make
gst_bin_add
- Bin の外から Bin の中の Element にアクセスできるようにする
gst_element_get_static_pad
gst_static_pad_template_get
gst_ghost_pad_new_from_template
gst_pad_set_active
gst_element_add_pad
● Element を作成して Bin に入れる
これについては説明不要ですね。
● Bin の外から Bin の中の Element にアクセスできるようにする
これを実現するには Ghost pad というものを使います。
Ghost pad とは Linux のシンボリックリンクのようなもので、「Ghost pad にデータを投げ込むと、実際には Ghost pad のリンク先に投げこまれる」そんな動作を実現できます。
今回の場合だと decodetimebin に投げ込まれたデータがそのまま Bin の中にいる fakesink に渡されることになります。つまり、decodetimebin は _chain()
を実装しなくていいんです。受け取ったバッファの処理はすべて fakesink がやってくれます。
Bin を作成するための手順は以上です!
おわりに
いかがでしたでしょうか。こう見ると比較的 Bin の作成は Element よりも簡単なのかもしれません。_chain
なども不要ですし。もちろん、それだけでやりたことを実現できるかどうかは別の話ですが。。
参考
https://gstreamer.freedesktop.org/documentation/application-development/basics/pads.html#ghost-pads