Lennart:
As a quick aside, I wanted to let the libcanberra community know that
Sun's ARC decided to not move the location of the canberra-gtk-play
file to libexec. They decided that it is better to stay compatible
with the upstream community. However, they did feel that your
examples were not a great justification for it being in /usr/bin.
Even though this may be used in scripting, it is still not a command
that users would commonly run or need in their PATH. Anyone clever
enough to write a script, or integrate canberra into their Makefile
process, is probably smart enough to know how to run a script that
is in libexec, especially if it is a documented interface, like with
a manpage. I just wanted to share their final opinion with you.
Brian, I will release libcanberra 0.8 shortly. If you want to make
sure that the Gst driver works fine on solaris before I do the
release, please test quickly!
Sorry I was not able ot test before the release. I just tested, and
I found it doesn't work for two reasons. One reason I fixed in the
attached patch. On Solaris, it is necessary to include "audioconvert !
audioconfig" in the GStreamer pipeline. This is needed to ensure that
GStreaner "just works" with sink plugins that may not implement the
full range of possible output that can come out of decodebin.
The attached patch fixes this. Totem, rhythmbox, and other GStreamer
based programs use similar logic.
Before the above fix, GStreamer would just hang, which would also
happen with the gst-launch command if you ran it with a similar
pipeline without "audioconvert".
The second problem is that after fixing the above, canberra-gtk-play
just immediately returns and does not play the file. I believe the
issue is somehow in the bus_cb function, since it does work much
better and plays the file if I comment out these lines from the
driver_play function:
/*
bus = gst_pipeline_get_bus(GST_PIPELINE (out->pipeline));
gst_bus_set_sync_handler(bus, bus_cb, out);
gst_object_unref(bus);
*/
However, after commenting out those lines, it seems that
canberra-gtk-play hangs after playing the file and never exits.
I suspect this is probably because the bus_cb is supposed to
catch this. But, for some reason, this doesn't seem to be
working on Solaris. I'm not sure why.
Brian
--- gstreamer.c-orig 2008-08-28 20:42:38.144911000 -0500
+++ gstreamer.c 2008-08-28 23:52:51.886346000 -0500
@@ -286,22 +286,38 @@ static int ca_gst_sound_file_open(ca_sou
static void on_pad_added(GstElement *element, GstPad *pad, gboolean arg1,
gpointer data)
{
- GstPad *sinkpad;
- GstElement *sink = GST_ELEMENT (data);
-
- sinkpad = gst_element_get_static_pad (sink, "sink");
-
- gst_pad_link (pad, sinkpad);
-
- gst_object_unref (sinkpad);
+ GstStructure *structure;
+ GstElement *sinkelement;
+ GstCaps *caps;
+ GstPad *vpad;
+ const char *type;
+
+ sinkelement = (GstElement *)data;
+
+ caps = gst_pad_get_caps (pad);
+ if (gst_caps_is_empty (caps) || gst_caps_is_any (caps)) {
+ gst_caps_unref (caps);
+ return;
+ }
+
+ structure = gst_caps_get_structure (caps, 0);
+ type = gst_structure_get_name (structure);
+ if (g_str_has_prefix (type, "audio/x-raw") == TRUE) {
+ vpad = gst_element_get_pad (sinkelement, "sink");
+ gst_pad_link (pad, vpad);
+ gst_object_unref (vpad);
+ }
+ gst_caps_unref (caps);
}
int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist,
ca_finish_callback_t cb, void *userdata) {
struct private *p;
struct outstanding *out = NULL;
ca_sound_file *f;
- GstElement *decodebin, *sink;
+ GstElement *decodebin, *sink, *audioconvert, *audioresample, *bin;
GstBus *bus;
+ GstPad *audiopad;
+ GstPad *pad;
int ret;
ca_return_val_if_fail(c, CA_ERROR_INVALID);
@@ -327,26 +343,42 @@ int driver_play(ca_context *c, uint32_t
if (!(out->pipeline = gst_pipeline_new(NULL))
|| !(decodebin = gst_element_factory_make("decodebin2", NULL))
+ || !(audioconvert = gst_element_factory_make("audioconvert", NULL))
+ || !(audioresample = gst_element_factory_make("audioresample", NULL))
|| !(sink = gst_element_factory_make("autoaudiosink", NULL))) {
ret = CA_ERROR_OOM;
goto fail;
}
+ bin = gst_bin_new ("audiobin");
+
+ g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (on_pad_added),
bin);
+
bus = gst_pipeline_get_bus(GST_PIPELINE (out->pipeline));
gst_bus_set_sync_handler(bus, bus_cb, out);
gst_object_unref(bus);
gst_bin_add_many(GST_BIN (out->pipeline),
- f->fdsrc, decodebin, sink, NULL);
+ f->fdsrc, decodebin, NULL);
if (!gst_element_link(f->fdsrc, decodebin)) {
f->fdsrc = NULL;
decodebin = NULL;
+ audioconvert = NULL;
+ audioresample = NULL;
sink = NULL;
goto fail;
}
- g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (on_pad_added),
sink);
+ gst_bin_add_many (GST_BIN (bin), audioconvert, audioresample, sink, NULL);
+ gst_element_link_many (audioconvert, audioresample, sink, NULL);
+
+ audiopad = gst_element_get_pad (audioconvert, "sink");
+ gst_element_add_pad (bin, gst_ghost_pad_new ("sink", audiopad));
+
+ gst_object_unref (audiopad);
+
+ gst_bin_add (GST_BIN (out->pipeline), bin);
decodebin = NULL;
sink = NULL;
@@ -381,7 +413,7 @@ int driver_play(ca_context *c, uint32_t
if (decodebin)
gst_object_unref(decodebin);
- if (out->pipeline)
+ if (out && out->pipeline)
gst_object_unref(out->pipeline);
ca_free(out);
_______________________________________________
libcanberra-discuss mailing list
[email protected]
https://tango.0pointer.de/mailman/listinfo/libcanberra-discuss