Skip to content

Day 2

Compare
Choose a tag to compare
@tetkuz tetkuz released this 16 Dec 11:57
· 13 commits to master since this release

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 を継承するには、以下の変更が必要です。

もちろん、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