decodebin は、前の項で取り上げた playbin の実際のオートプラッガバックエンドです。簡単に言えば、decodebin は、自身のシンクパッドにリンクされたソースから入力を受け取り、ストリームに含まれているメディアの種類の認識を試み、各メディアの種類に応じてデコーダルーチンをセットアップします。デコーダは decodebin が自動的に選択します。デコードされた各ストリームに対し、decodebin は "new-decoded-pad" シグナルを送信し、新しく見つかったデコード済みストリームについてクライアントに通知します。不明なストリーム (ストリーム全体がそうであることもあります) の場合には、"unknown-type" シグナルを送信します。このとき、エラーをユーザーに報告するのは、アプリケーションの役割になります。
#include <gst/gst.h>
[.. my_bus_callback をここに記述 ..]
GstElement *pipeline, *audio;
static void
cb_newpad (GstElement *decodebin,
GstPad *pad,
gboolean last,
gpointer data)
{
GstCaps *caps;
GstStructure *str;
GstPad *audiopad;
/* only link once */
audiopad = gst_element_get_static_pad (audio, "sink");
if (GST_PAD_IS_LINKED (audiopad)) {
g_object_unref (audiopad);
return;
}
/* check media type */
caps = gst_pad_get_caps (pad);
str = gst_caps_get_structure (caps, 0);
if (!g_strrstr (gst_structure_get_name (str), "audio")) {
gst_caps_unref (caps);
gst_object_unref (audiopad);
return;
}
gst_caps_unref (caps);
/* link'n'play */
gst_pad_link (pad, audiopad);
g_object_unref (audiopad);
}
gint
main (gint argc,
gchar *argv[])
{
GMainLoop *loop;
GstElement *src, *dec, *conv, *sink;
GstPad *audiopad;
GstBus *bus;
/* init GStreamer */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* make sure we have input */
if (argc != 2) {
g_print ("Usage: %s <filename>\n", argv[0]);
return -1;
}
/* setup */
pipeline = gst_pipeline_new ("pipeline");
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, my_bus_callback, loop);
gst_object_unref (bus);
src = gst_element_factory_make ("filesrc", "source");
g_object_set (G_OBJECT (src), "location", argv[1], NULL);
dec = gst_element_factory_make ("decodebin", "decoder");
g_signal_connect (dec, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL);
gst_bin_add_many (GST_BIN (pipeline), src, dec, NULL);
gst_element_link (src, dec);
/* create audio output */
audio = gst_bin_new ("audiobin");
conv = gst_element_factory_make ("audioconvert", "aconv");
audiopad = gst_element_get_static_pad (conv, "sink");
sink = gst_element_factory_make ("alsasink", "sink");
gst_bin_add_many (GST_BIN (audio), conv, sink, NULL);
gst_element_link (conv, sink);
gst_element_add_pad (audio,
gst_ghost_pad_new ("sink", audiopad));
gst_object_unref (audiopad);
gst_bin_add (GST_BIN (pipeline), audio);
/* run */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);
/* cleanup */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
return 0;
}
playbin と同じく、decodebin は以下のような機能を備えています。
デコードできるストリーム数は無制限で、ストリームをデコード済み出力パッドへと送ります。
あらゆる面において、GstElement として処理されます。これには、タグやエラーの転送、状態の処理も含まれます。
decodebin は優れたオートプラッガですが、自動では行わないことや、処理することを意図していないこともたくさんあります。具体的には、以下のとおりです。
メディアの種類が既知の入力ストリーム (DVD、オーディオ CD など) を処理すること。
ストリームの選択 (多言語対応メディアストリームの場合にどの音声トラックを再生するかなど)。
デコード済み動画ストリームへの字幕のオーバーレイ。
"decodebin" は、たとえば gst-launch-0.10 filesrc location=file.ogg ! decodebin ! audioconvert ! audioresample ! autoaudiosink のようなコマンドを実行することで、コマンドラインで簡単にテストすることができます。
新しいアプリケーションでは、古い decodebin の代わりに decodebin2 を使う必要があります。
uridecodebin エレメントは decodebin2 とよく似ていますが、同じなのは、与えられた URI のプロトコルに基づいて自動的にソースプラグインをつなぐところだけです。