Tuesday, December 8, 2015

GStreamer でプログラミング 3 (Element と Property)

GStreamer の pipeline には複数のエレメントが含まれているようですが、どうやってエレメントを取り出すんでしょうか? 自分でエレメントを作成し、pineline に追加した時は良いのですが、 gst_parse_launch() を使った場合は?

答は、 gst_bin_get_by_name() を使います。でも取り出したいエレメントの名前が分らない? 各エレメントのインスタンス名は、デフォルトで「"エレメント名" + "インデックス番号"」となるので簡単です。インデックスは、0 始まりなので filesrc を取り出すときは、 "filesrc0" を指定してあげれば良いです。パイプライン中で、同じエレメントの複数のインスタンスがある場合、順次番号が増えていきます。また、 queue2 のようにエレメント名が数字で終っている場合は、「"エレメント名" + "-" + "インデックス番号"」と間にハイフンが入ります。

前回のコードの filesrc を取り出すなら、こんな感じです。

#include <gst/gst.h>
gboolean on_message(GstBus *bus, GstMessage *message, gpointer p)
{
GMainLoop *mainloop = p;
(void)bus;
if ((GST_MESSAGE_TYPE(message) & GST_MESSAGE_EOS))
g_main_loop_quit(mainloop);
return TRUE;
}
int main(int argc, char *argv[])
{
GMainLoop *mainloop;
GstElement *pipeline;
GError *error = NULL;
GstBus *bus;
GstElement *src;
gst_init(&argc, &argv);
mainloop = g_main_loop_new(NULL, FALSE);
pipeline = gst_parse_launch("filesrc location=a.txt ! fdsink", &error);
bus = gst_element_get_bus(pipeline);
gst_bus_add_watch(bus, on_message, mainloop);
src = gst_bin_get_by_name(GST_BIN(pipeline), "filesrc0");
if (src) {
g_print("name: %s\n", gst_element_get_name(src));
g_object_unref(src);
}
gst_element_set_state(pipeline, GST_STATE_PLAYING);
g_main_loop_run(mainloop);
return 0;
}
view raw element.c hosted with ❤ by GitHub
gst-launch-1.0 -q \
videotestsrc ! tee name=t \
t. ! queue ! ximagesink \
t. ! queue ! ximagesink \
t. ! queue ! ximagesink \
t. ! queue ! ximagesink

よく、こんな風に name= となっているものを見かけます。 teedemux を使うときに使われることが多いようです。実はこれが、 gst-launch で名前を付ける方法です。 gst-launch の時も、名前を指定しなければ tee0 と指定できます。

gst-launch-1.0 -q \
videotestsrc ! tee \
tee0. ! queue ! ximagesink \
tee0. ! queue ! ximagesink \
tee0. ! queue ! ximagesink \
tee0. ! queue ! ximagesink

なので、この2つのコマンドは同じように動きます。ただし、同じエレメントを複数使った場合は紛らわしかったり、実装が変って違う名前が付くと動かなくなるので、明示的に指定しています。

さて、C に戻ります。

gst-launch-1.0 filesrc name=mysrc location=a.txt ! fdsink

これをそのまま gst_parse_launch() に渡し

pipeline = gst_parse_launch("filesrc name=mysrc location=a.txt ! fdsink", &error);

とすると、

src = gst_bin_get_by_name(GST_BIN(pipeline), "mysrc");

として取れるんですね。取れた filesrc エレメントの名前は、もちろん "mysrc" です。 gst_element_get_name() で確認できます。 GstElement の元になっている GstObjectname というプロパティがあるので、 GstElement から派生しているオジェクトであれば、みんな名前が取れます。 pipeline でも。お試しあれ。

#include <gst/gst.h>
gboolean on_message(GstBus *bus, GstMessage *message, gpointer p)
{
GMainLoop *mainloop = p;
(void)bus;
if ((GST_MESSAGE_TYPE(message) & GST_MESSAGE_EOS))
g_main_loop_quit(mainloop);
return TRUE;
}
int main(int argc, char *argv[])
{
GMainLoop *mainloop;
GstElement *pipeline;
GError *error = NULL;
GstBus *bus;
GstElement *src;
gst_init(&argc, &argv);
mainloop = g_main_loop_new(NULL, FALSE);
pipeline = gst_parse_launch("filesrc name=mysrc location=a.txt ! fdsink", &error);
bus = gst_element_get_bus(pipeline);
gst_bus_add_watch(bus, on_message, mainloop);
src = gst_bin_get_by_name(GST_BIN(pipeline), "mysrc");
if (src) {
g_print("name: %s\n", gst_element_get_name(src));
g_object_unref(src);
}
gst_element_set_state(pipeline, GST_STATE_PLAYING);
g_main_loop_run(mainloop);
return 0;
}
view raw mysrc.c hosted with ❤ by GitHub

No comments:

Post a Comment