From 1354fcea158eea1cda98db0ec529a405e707bd05 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 30 Jan 2008 14:21:43 +0000 Subject: [PATCH] bluez: Fixes gstreamer caps and code cleanup. --- sys/bluez/gsta2dpsink.c | 42 +++++++++++++++++++++++---------- sys/bluez/gstavdtpsink.c | 51 ++++++++++++++++++++++++---------------- sys/bluez/gstavdtpsink.h | 1 - 3 files changed, 61 insertions(+), 33 deletions(-) diff --git a/sys/bluez/gsta2dpsink.c b/sys/bluez/gsta2dpsink.c index 80486afb04..a1811403ed 100644 --- a/sys/bluez/gsta2dpsink.c +++ b/sys/bluez/gsta2dpsink.c @@ -79,6 +79,18 @@ gst_a2dp_sink_finalize (GObject * obj) G_OBJECT_CLASS (parent_class)->finalize (obj); } +static GstState +gst_a2dp_sink_get_state (GstA2dpSink * self) +{ + GstState current, pending; + + gst_element_get_state (GST_ELEMENT (self), ¤t, &pending, 0); + if (pending == GST_STATE_VOID_PENDING) + return current; + + return pending; +} + /* * Helper function to create elements, add to the bin and link it * to another element. @@ -88,6 +100,7 @@ gst_a2dp_sink_init_element (GstA2dpSink * self, const gchar * elementname, const gchar * name, GstElement * link_to) { GstElement *element; + GstState state; GST_LOG_OBJECT (self, "Initializing %s", elementname); @@ -102,16 +115,17 @@ gst_a2dp_sink_init_element (GstA2dpSink * self, goto cleanup_and_fail; } - if (gst_element_set_state (element, GST_STATE_PLAYING) == - GST_STATE_CHANGE_FAILURE) { + state = gst_a2dp_sink_get_state (self); + if (gst_element_set_state (element, state) == GST_STATE_CHANGE_FAILURE) { GST_ERROR_OBJECT (self, "%s failed to go to playing", elementname); goto remove_element_and_fail; } - if (!gst_element_link (link_to, element)) { - GST_ERROR_OBJECT (self, "couldn't link %s", elementname); - goto remove_element_and_fail; - } + if (link_to != NULL) + if (!gst_element_link (link_to, element)) { + GST_ERROR_OBJECT (self, "couldn't link %s", elementname); + goto remove_element_and_fail; + } return element; @@ -239,7 +253,6 @@ gst_a2dp_sink_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_NULL_TO_READY: self->sink_is_in_bin = FALSE; - self->sink = GST_AVDTP_SINK (gst_element_factory_make ("avdtpsink", "avdtpsink")); if (self->sink == NULL) { @@ -256,8 +269,10 @@ gst_a2dp_sink_change_state (GstElement * element, GstStateChange transition) break; } - if (ret == GST_STATE_CHANGE_FAILURE) + if (ret == GST_STATE_CHANGE_FAILURE) { + g_mutex_unlock (self->cb_mutex); return ret; + } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); @@ -287,7 +302,6 @@ gst_a2dp_sink_change_state (GstElement * element, GstStateChange transition) gst_a2dp_sink_remove_dynamic_elements (self); break; - default: break; } @@ -546,15 +560,15 @@ gst_a2dp_sink_handle_event (GstPad * pad, GstEvent * event) if (self->newseg_event != NULL) gst_event_unref (self->newseg_event); self->newseg_event = gst_event_ref (event); + } else if (GST_EVENT_TYPE (event) == GST_EVENT_TAG && parent != GST_OBJECT_CAST (self)) { - if (self->taglist == NULL) { + if (self->taglist == NULL) gst_event_parse_tag (event, &self->taglist); - } else { + else { gst_event_parse_tag (event, &taglist); gst_tag_list_insert (self->taglist, taglist, GST_TAG_MERGE_REPLACE); } - /* FIXME handle tag events */ } if (parent != NULL) @@ -604,11 +618,15 @@ static gboolean gst_a2dp_sink_remove_fakesink (GstA2dpSink * self) { g_mutex_lock (self->cb_mutex); + if (self->fakesink != NULL) { + gst_element_set_locked_state (self->fakesink, TRUE); gst_element_set_state (self->fakesink, GST_STATE_NULL); + gst_bin_remove (GST_BIN (self), self->fakesink); self->fakesink = NULL; } + g_mutex_unlock (self->cb_mutex); return TRUE; diff --git a/sys/bluez/gstavdtpsink.c b/sys/bluez/gstavdtpsink.c index b41467b564..1bd753402b 100644 --- a/sys/bluez/gstavdtpsink.c +++ b/sys/bluez/gstavdtpsink.c @@ -69,7 +69,7 @@ struct bluetooth_data }; #define IS_SBC(n) (strcmp((n), "audio/x-sbc") == 0) -#define IS_MPEG(n) (strcmp((n), "audio/mpeg") == 0) +#define IS_MPEG_AUDIO(n) (strcmp((n), "audio/mpeg") == 0) enum { @@ -88,8 +88,12 @@ GST_ELEMENT_DETAILS ("Bluetooth AVDTP sink", static GstStaticPadTemplate avdtp_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("application/x-rtp, " - "media = (string) \"audio\", " - "encoding-name = (string) \"SBC\";" + "media = (string) \"audio\"," + "payload = (int) " + GST_RTP_PAYLOAD_DYNAMIC_STRING ", " + "clock-rate = (int) { 16000, 32000, " + "44100, 48000 }, " + "encoding-name = (string) \"SBC\"; " "application/x-rtp, " "media = (string) \"audio\", " "payload = (int) " @@ -234,7 +238,7 @@ gst_avdtp_sink_bluetooth_recvmsg_fd (GstAvdtpSink * sink) } static gboolean -gst_avdtp_sink_init_pkt_conf (GstAvdtpSink * sink, +gst_avdtp_sink_init_sbc_pkt_conf (GstAvdtpSink * sink, GstCaps * caps, sbc_capabilities_t * pkt) { sbc_capabilities_t *cfg = &sink->data->caps.sbc_capabilities; @@ -244,9 +248,9 @@ gst_avdtp_sink_init_pkt_conf (GstAvdtpSink * sink, GstStructure *structure = gst_caps_get_structure (caps, 0); name = gst_structure_get_name (structure); - /* FIXME only sbc supported here, should suport mp3 */ + if (!(IS_SBC (name))) { - GST_ERROR_OBJECT (sink, "Unsupported format %s", name); + GST_ERROR_OBJECT (sink, "Unexpected format %s, " "was expecting sbc", name); return FALSE; } @@ -810,7 +814,7 @@ gst_avdtp_sink_tag (const GstTagList * taglist, if (!gst_tag_list_get_boolean (taglist, tag, &crc)) { GST_WARNING_OBJECT (self, "failed to get crc tag"); - self->mpeg_stream_changed = TRUE; + return; } gst_avdtp_sink_set_crc (self, crc); @@ -819,7 +823,7 @@ gst_avdtp_sink_tag (const GstTagList * taglist, if (!gst_tag_list_get_string (taglist, tag, &channel_mode)) { GST_WARNING_OBJECT (self, "failed to get channel-mode tag"); - self->mpeg_stream_changed = TRUE; + return; } self->channel_mode = gst_avdtp_sink_get_channel_mode (channel_mode); @@ -878,7 +882,6 @@ gst_avdtp_sink_start (GstBaseSink * basesink) self->stream_caps = NULL; self->mp3_using_crc = -1; self->channel_mode = -1; - self->mpeg_stream_changed = FALSE; if (!gst_avdtp_sink_get_capabilities (self)) { GST_ERROR_OBJECT (self, "failed to get capabilities " "from device"); @@ -948,8 +951,16 @@ gst_avdtp_sink_init_mp3_pkt_conf (GstAvdtpSink * self, GstCaps * caps, { const GValue *value = NULL; gint rate, layer; + const gchar *name; GstStructure *structure = gst_caps_get_structure (caps, 0); + name = gst_structure_get_name (structure); + + if (!(IS_MPEG_AUDIO (name))) { + GST_ERROR_OBJECT (self, "Unexpected format %s, " "was expecting mp3", name); + return FALSE; + } + /* layer */ value = gst_structure_get_value (structure, "layer"); layer = g_value_get_int (value); @@ -1007,9 +1018,6 @@ gst_avdtp_sink_init_mp3_pkt_conf (GstAvdtpSink * self, GstCaps * caps, /* vbr - we always say its vbr, we don't have how to know it */ pkt->bitrate = 0x8000; - /* bitrate - we don't set anything, its vbr */ - /* FIXME - is this right? */ - return TRUE; } @@ -1035,7 +1043,7 @@ gst_avdtp_sink_configure (GstAvdtpSink * self, GstCaps * caps) structure = gst_caps_get_structure (caps, 0); if (gst_structure_has_name (structure, "audio/x-sbc")) - ret = gst_avdtp_sink_init_pkt_conf (self, caps, &req->sbc_capabilities); + ret = gst_avdtp_sink_init_sbc_pkt_conf (self, caps, &req->sbc_capabilities); else if (gst_structure_has_name (structure, "audio/mpeg")) ret = gst_avdtp_sink_init_mp3_pkt_conf (self, caps, &req->mpeg_capabilities); @@ -1168,8 +1176,8 @@ gst_avdtp_sink_class_init (GstAvdtpSinkClass * klass) g_param_spec_string ("device", "Device", "Bluetooth remote device address", NULL, G_PARAM_READWRITE)); - GST_DEBUG_CATEGORY_INIT (avdtp_sink_debug, "a2dpsendersink", 0, - "A2DP sink element"); + GST_DEBUG_CATEGORY_INIT (avdtp_sink_debug, "avdtpsink", 0, + "A2DP headset sink element"); } static void @@ -1183,6 +1191,11 @@ gst_avdtp_sink_init (GstAvdtpSink * self, GstAvdtpSinkClass * klass) self->dev_caps = NULL; self->sink_lock = g_mutex_new (); + + /* FIXME this is for not synchronizing with clock, should be tested + * with devices to see the behaviour + gst_base_sink_set_sync(GST_BASE_SINK(self), FALSE); + */ } static GIOError @@ -1309,9 +1322,7 @@ gst_avdtp_sink_set_crc (GstAvdtpSink * self, gboolean crc) /* test if we already received a different crc */ if (self->mp3_using_crc != -1 && new_crc != self->mp3_using_crc) { - GST_ERROR_OBJECT (self, "crc changed during stream"); - /* FIXME test this, its not being used anywhere */ - self->mpeg_stream_changed = TRUE; + GST_WARNING_OBJECT (self, "crc changed during stream"); return; } self->mp3_using_crc = new_crc; @@ -1326,8 +1337,8 @@ gst_avdtp_sink_set_channel_mode (GstAvdtpSink * self, const gchar * mode) new_mode = gst_avdtp_sink_get_channel_mode (mode); if (self->channel_mode != -1 && new_mode != self->channel_mode) { - GST_ERROR_OBJECT (self, "channel mode changed during stream"); - self->mpeg_stream_changed = TRUE; + GST_WARNING_OBJECT (self, "channel mode changed during stream"); + return; } self->channel_mode = new_mode; diff --git a/sys/bluez/gstavdtpsink.h b/sys/bluez/gstavdtpsink.h index d038082975..237597dac1 100644 --- a/sys/bluez/gstavdtpsink.h +++ b/sys/bluez/gstavdtpsink.h @@ -57,7 +57,6 @@ struct _GstAvdtpSink { GIOChannel *server; /* mp3 stream data (outside caps data)*/ - gboolean mpeg_stream_changed; gint mp3_using_crc; gint channel_mode;