plugin 開発の話をするまえに、Elementについてもっと知っておかなければならないことがたくさんあります。
今日は、最も基本的な GST_STATE についてお話します。
もしかすると、あなたは GST_STATE の遷移を gst-launch を実行した時に見たことがあるかもしれません。
以下のような表示は見たことがありませんか? これが GST_STATE の遷移です。
$ gst-launch-1.0 -ev fakesrc ! fakesink
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
:
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
GST_STATE は 4つあります。
- NULL
- READY
- PAUSED
- PLAYING
それぞれは決まった流れでしか遷移しません。
NULL → READY → PAUSED → PLAYING
NULL ← READY ← PAUSED ← PLAYING
NULL から PLAYING にジャンプすることもありませんし、PLAYING から READY に一気に切り替わることもありません。必ず順番に遷移します。
gst-launch では「Setting pipeline to PAUSED」など、Pipeline についてしか言及していません。GST_STATE は、Pipeline のみが持つのでしょうか?
答えは No です。
タイトルでも口走っているように、GST_STATE はすべての GstElement が持っています。
これはGstElementの構造体からも確認できます。また、Pipeline が GST_STATE を持っていることは Pipeline の Object Hierarchy から確認できます。
つまり、Pipeline も Element も GST_STATE を持っています。
Pipeline も Element も GST_STATE を持っていることがわかったところで、次に気になるのはPipelieneとElementの状態遷移の関連性です。
Pipeline が PLAYING のとき、その Pipeline に含まれる Element は READY であることがあるのでしょうか?
この答は、デバッグレベルを上げて gst-launch を実行するとわかります。
$ GST_DEBUG=4 gst-launch-1.0 -ev fakesrc ! fakesink
横長で読みにくいですが、Setting pipeline to PAUSED ...
の後に以下のログがあると思います。
GST_STATES gstbin.c:2243:gst_bin_element_set_state:<fakesink0> current NULL pending VOID_PENDING, desired next READY
GST_STATES gstelement.c:2330:gst_element_continue_state:<fakesink0> completed state change to READY
GST_STATES gstelement.c:2235:_priv_gst_element_state_changed:<fakesink0> notifying about state-changed NULL to READY (VOID_PENDING pending)
GST_STATES gstbin.c:2707:gst_bin_change_state_func:<pipeline0> child 'fakesink0' changed state to 2(READY) successfully
GST_STATES gstbin.c:2243:gst_bin_element_set_state:<fakesrc0> current NULL pending VOID_PENDING, desired next READY
GST_STATES gstelement.c:2330:gst_element_continue_state:<fakesrc0> completed state change to READY
GST_STATES gstelement.c:2235:_priv_gst_element_state_changed:<fakesrc0> notifying about state-changed NULL to READY (VOID_PENDING pending)
GST_STATES gstbin.c:2707:gst_bin_change_state_func:<pipeline0> child 'fakesrc0' changed state to 2(READY) successfully
ここから、読み取れる内容の大きなポイントは2つです
- Sink element (下流の Element) から Src element に向かって STATE CHAGE が進んでいくということ
- Pipeline の Elemnet すべての STATE CHANGE が終わってやっと Pipeline の STATE が変わるということ
これは NULL -> PLAY までの順番に変わっていく中でも必ずこの動きをします。
「Pipeline が PLAYING のとき、その Pipeline に含まれる Element は READY であることがあるのでしょうか?」の答えは No です。
この STATE CHANGE の概念を知っていると、Element のデバッグが捗るのでぜひ抑えておくことをおすすめします。
今回の内容は What are states? に書いてありますし、ここでは書かなかったそれぞれの STATE の意味なども書いてあるので見るとより幸せになれます :)