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);  | 
