+
+
+ /* FIXME: currently, decodebin isn't possible for
+ video streams. in that case, make a manual pipeline. */
+
+ int is_video = !!strstr(filename, "mpg"); /* fixme */
+
+ int use_decodebin = !is_video;
+
+ int all_ok = 0;
+
+ m_gst_pipeline = gst_pipeline_new ("audio-player");
+ if (!m_gst_pipeline)
+ eWarning("failed to create pipeline");
+
+ source = gst_element_factory_make ("filesrc", "file-source");
+ if (!source)
+ eWarning("failed to create filesrc");
+
+ if (use_decodebin)
+ {
+ /* filesrc -> decodebin -> audioconvert -> capsfilter -> alsasink */
+
+ decoder = gst_element_factory_make ("decodebin", "decoder");
+ if (!decoder)
+ eWarning("failed to create decodebin decoder");
+
+ conv = gst_element_factory_make ("audioconvert", "converter");
+ if (!conv)
+ eWarning("failed to create audioconvert");
+
+ flt = gst_element_factory_make ("capsfilter", "flt");
+ if (!flt)
+ eWarning("failed to create capsfilter");
+
+ /* workaround for [3des]' driver bugs: */
+ if (flt)
+ {
+ GstCaps *caps = gst_caps_new_simple("audio/x-raw-int", "endianness", G_TYPE_INT, 4321, (char*)0);
+ g_object_set (G_OBJECT (flt), "caps", caps, (char*)0);
+ gst_caps_unref(caps);
+ }
+
+ sink = gst_element_factory_make ("alsasink", "alsa-output");
+ if (!sink)
+ eWarning("failed to create osssink");
+
+ if (source && decoder && conv && sink)
+ all_ok = 1;
+ } else /* is_video */
+ {
+ /* filesrc -> mpegdemux -> | queue_audio -> dvbaudiosink
+ | queue_video -> dvbvideosink */
+
+ audio = gst_element_factory_make("dvbaudiosink", "audio");
+ queue_audio = gst_element_factory_make("queue", "queue_audio");
+
+ video = gst_element_factory_make("dvbvideosink", "video");
+ queue_video = gst_element_factory_make("queue", "queue_video");
+
+ mpegdemux = gst_element_factory_make("mpegdemux", "mpegdemux");
+
+ eDebug("audio: %p, queue_audio %p, video %p, queue_video %p, mpegdemux %p", audio, queue_audio, video, queue_video, mpegdemux);
+ if (audio && queue_audio && video && queue_video && mpegdemux)
+ all_ok = 1;
+ }
+
+ if (m_gst_pipeline && all_ok)
+ {
+ gst_bus_set_sync_handler(gst_pipeline_get_bus (GST_PIPELINE (m_gst_pipeline)), gstBusSyncHandler, this);
+
+ /* configure source */
+ g_object_set (G_OBJECT (source), "location", filename, NULL);
+
+ if (use_decodebin)
+ {
+ g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK(gstCBnewPad), this);
+ g_signal_connect (decoder, "unknown-type", G_CALLBACK(gstCBunknownType), this);
+
+ /* gst_bin will take the 'floating references' */
+ gst_bin_add_many (GST_BIN (m_gst_pipeline),
+ source, decoder, NULL);
+ gst_element_link(source, decoder);
+
+ /* create audio bin */
+ m_gst_audio = gst_bin_new ("audiobin");
+ GstPad *audiopad = gst_element_get_pad (conv, "sink");
+
+ gst_bin_add_many(GST_BIN(m_gst_audio), conv, flt, sink, (char*)0);
+ gst_element_link_many(conv, flt, sink, (char*)0);
+ gst_element_add_pad(m_gst_audio, gst_ghost_pad_new ("sink", audiopad));
+ gst_object_unref(audiopad);
+ gst_bin_add (GST_BIN(m_gst_pipeline), m_gst_audio);
+ } else
+ {
+ gst_bin_add_many(GST_BIN(m_gst_pipeline), source, mpegdemux, audio, queue_audio, video, queue_video, mpegdemux, NULL);
+ gst_element_link(source, mpegdemux);
+ gst_element_link(queue_audio, audio);
+ gst_element_link(queue_video, video);
+
+ m_gst_audioqueue = queue_audio;
+ m_gst_videoqueue = queue_video;
+
+ g_signal_connect(mpegdemux, "pad-added", G_CALLBACK (gstCBpadAdded), this);
+ }
+ } else
+ {
+ if (m_gst_pipeline)
+ gst_object_unref(GST_OBJECT(m_gst_pipeline));
+ if (source)
+ gst_object_unref(GST_OBJECT(source));
+ if (decoder)
+ gst_object_unref(GST_OBJECT(decoder));
+ if (conv)
+ gst_object_unref(GST_OBJECT(conv));
+ if (sink)
+ gst_object_unref(GST_OBJECT(sink));
+
+ if (audio)
+ gst_object_unref(GST_OBJECT(audio));
+ if (queue_audio)
+ gst_object_unref(GST_OBJECT(queue_audio));
+ if (video)
+ gst_object_unref(GST_OBJECT(video));
+ if (queue_video)
+ gst_object_unref(GST_OBJECT(queue_video));
+ if (mpegdemux)
+ gst_object_unref(GST_OBJECT(mpegdemux));
+
+ eDebug("sorry, can't play.");
+ m_gst_pipeline = 0;
+ }
+
+ gst_element_set_state (m_gst_pipeline, GST_STATE_PLAYING);