動的にパイプラインを切り替える方法はいくつかありますが、1つの方法として、output-selector
, input-selector
というものがあります。
output-selector でなにか簡単なアプリケーションを書こうと思い調べていたのですが、あまりにもいいサンプルコードが見つかったので書かないことにしました笑
こちらの output-selector-test.c が非常に良いのです。
このプログラムでは以下のようなパイプラインを作っています。
c1 --> sink1
/
src --> c0 --> toverlay --> osel
\
c2 --> sink2
videotestsrc から絵を取って、timeoverlay で時間を映像に入れ、
その後、output-selector で出力先を切り替えます。
切り替えのトリガーには g_timeout_add_seconds()
を使っていて
このトリガーに対応する処理で active-pad
をスイッチする処理が書かれています。
こうすることで出力先が1秒ごとにパタパタしています。
このような output-selector を使ったプログラムを書く上でのポイントを、先ほど紹介したコードの中からピックアップして紹介します。
gst_element_get_request_pad()
該当する箇所: 127行目
このプログラムにおいて最も大切な関数と呼んで過言はないでしょう。
gst_element_get_request_pad()は Element に対して「Pad をくれ!」と要求する関数です。引数には要求する Element と、要求する Pad の名前を書きます。
この要求を行わなければ、output-selector は src の Pad を持っていません。つまり、下流にデータを流してくれないのです。なので、必ず行う必要があります。
gst_element_get_static_pad()
該当する箇所: 140行目
これは、inspect で以下のように表示される Element に対して行う関数です。
Pad Templates:
SINK template: 'sink'
Availability: Always
gst_element_get_request_pad()
で得た Pad の繋げ先を取得するために、
このプログラムでは使われているで、これも大切な処理と言えます。
ただ、gst_element_get_static_pad()
についてはすでに Day 10 で解説されているので詳細な説明は省きます。
g_object_set()
該当する箇所: 58行目
g_object_set()
は Element のプロパティを設定する時にしばしば登場しますが、output-selector においては「出力先の決定」という大きな役目を持っています。(プロパティであることに変わりはありませんが...)
引数には、プロパティを設定したいエレメント、プロパティ名、設定する値、NULL の順番に入れます。
また、設定する値の 型 は inspect で表示されるものに従ってください。
output-selector の active-pad の場合は GstPad
を入れますが、name の場合はもちろん gchar *
です。
エレメントによって、プロパティによって違うことを忘れずに
g_object_get()
該当する箇所: 51行目
g_object_get()
で、Element のプロパティの値を確認できます。
いま、output-selector が「どの Pad に出力しているのか」がこの関数でわかるので、これも重要な関数です。
このほかにの link 関連など 「GStreamer アプリケーションとして」重要な関数はいくつかありますが、またの機会に...
さて、output-selector のプログラムいかがだったでしょうか? ちょっと可能性が広がりそうですね。
また、input-selector を使えば1つの画面に複数のカメラからの映像を切り替えて表示する。なんてこともできるので是非やってみてください :)