diff options
-rw-r--r-- | src/gstreamer.c | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/src/gstreamer.c b/src/gstreamer.c index a294378..2e0dba5 100644 --- a/src/gstreamer.c +++ b/src/gstreamer.c @@ -213,7 +213,7 @@ static GstBusSyncReply bus_cb(GstBus *bus, GstMessage *message, gpointer data) { case GST_MESSAGE_ERROR: err = CA_ERROR_SYSTEM; break; - /* only from bin */ + /* only from bin */ case GST_MESSAGE_EOS: if (GST_OBJECT(out->pipeline) != GST_MESSAGE_SRC(message)) return GST_BUS_DROP; @@ -286,22 +286,38 @@ static int ca_gst_sound_file_open(ca_sound_file **_f, const char *fn) { 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); + 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; + } - gst_object_unref (sinkpad); + 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 id, ca_proplist *proplist, ca_finish_cal 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; @@ -368,7 +400,7 @@ int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_cal return CA_SUCCESS; - fail: +fail: if (f && f->fdsrc) gst_object_unref(f->fdsrc); @@ -381,7 +413,7 @@ int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_cal if (decodebin) gst_object_unref(decodebin); - if (out->pipeline) + if (out && out->pipeline) gst_object_unref(out->pipeline); ca_free(out); |