From 6c4268df1dff13f3b1a7b778eb2e993648bff519 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 30 Jan 2008 17:30:27 +0000 Subject: Enable gstreamer plugin to use autoconnect flag. --- audio/gsta2dpsink.c | 28 +++++++++++++++++++++++++++- audio/gsta2dpsink.h | 1 + audio/gstavdtpsink.c | 20 ++++++++++++++++++++ audio/gstavdtpsink.h | 1 + audio/gstsbcparse.c | 41 ++++++++++++++++++++++++++++++++--------- audio/gstsbcparse.h | 3 +++ 6 files changed, 84 insertions(+), 10 deletions(-) diff --git a/audio/gsta2dpsink.c b/audio/gsta2dpsink.c index b5b1c576..6595d0b5 100644 --- a/audio/gsta2dpsink.c +++ b/audio/gsta2dpsink.c @@ -37,9 +37,12 @@ GST_DEBUG_CATEGORY_STATIC(gst_a2dp_sink_debug); #define A2DP_SBC_RTP_PAYLOAD_TYPE 1 #define TEMPLATE_MAX_BITPOOL_STR "64" +#define DEFAULT_AUTOCONNECT TRUE + enum { PROP_0, - PROP_DEVICE + PROP_DEVICE, + PROP_AUTOCONNECT }; GST_BOILERPLATE(GstA2dpSink, gst_a2dp_sink, GstBin, GST_TYPE_BIN); @@ -170,6 +173,14 @@ static void gst_a2dp_sink_set_property(GObject *object, guint prop_id, self->device = g_value_dup_string(value); break; + case PROP_AUTOCONNECT: + self->autoconnect = g_value_get_boolean(value); + + if (self->sink != NULL) + g_object_set(G_OBJECT(self->sink), "auto-connect", + self->autoconnect, NULL); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -190,7 +201,13 @@ static void gst_a2dp_sink_get_property(GObject *object, guint prop_id, g_value_take_string(value, device); } break; + case PROP_AUTOCONNECT: + if (self->sink != NULL) + g_object_get(G_OBJECT(self->sink), "auto-connect", + &self->autoconnect, NULL); + g_value_set_boolean(value, self->autoconnect); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -266,6 +283,9 @@ static GstStateChangeReturn gst_a2dp_sink_change_state(GstElement *element, gst_avdtp_sink_set_device(self->sink, self->device); + g_object_set(G_OBJECT(self->sink), "auto-connect", + self->autoconnect, NULL); + ret = gst_element_set_state(GST_ELEMENT(self->sink), GST_STATE_READY); break; @@ -340,6 +360,11 @@ static void gst_a2dp_sink_class_init(GstA2dpSinkClass *klass) "Bluetooth remote device address", NULL, G_PARAM_READWRITE)); + g_object_class_install_property(object_class, PROP_AUTOCONNECT, + g_param_spec_boolean("auto-connect", "Auto-connect", + "Automatically attempt to connect to device", + DEFAULT_AUTOCONNECT, G_PARAM_READWRITE)); + GST_DEBUG_CATEGORY_INIT(gst_a2dp_sink_debug, "a2dpsink", 0, "A2DP sink element"); } @@ -649,6 +674,7 @@ static void gst_a2dp_sink_init(GstA2dpSink *self, self->fakesink = NULL; self->rtp = NULL; self->device = NULL; + self->autoconnect = DEFAULT_AUTOCONNECT; self->capsfilter = NULL; self->newseg_event = NULL; self->taglist = NULL; diff --git a/audio/gsta2dpsink.h b/audio/gsta2dpsink.h index d79307b2..cf11d43e 100644 --- a/audio/gsta2dpsink.h +++ b/audio/gsta2dpsink.h @@ -53,6 +53,7 @@ struct _GstA2dpSink { GstElement *fakesink; gchar *device; + gboolean autoconnect; gboolean sink_is_in_bin; GstGhostPad *ghostpad; diff --git a/audio/gstavdtpsink.c b/audio/gstavdtpsink.c index 25fc1ced..d5737258 100644 --- a/audio/gstavdtpsink.c +++ b/audio/gstavdtpsink.c @@ -51,6 +51,8 @@ GST_DEBUG_CATEGORY_STATIC(avdtp_sink_debug); #define CRC_PROTECTED 1 #define CRC_UNPROTECTED 0 +#define DEFAULT_AUTOCONNECT TRUE + #define GST_AVDTP_SINK_MUTEX_LOCK(s) G_STMT_START { \ g_mutex_lock (s->sink_lock); \ } G_STMT_END @@ -73,6 +75,7 @@ struct bluetooth_data { enum { PROP_0, PROP_DEVICE, + PROP_AUTOCONNECT }; GST_BOILERPLATE(GstAvdtpSink, gst_avdtp_sink, GstBaseSink, @@ -193,6 +196,9 @@ static void gst_avdtp_sink_set_property(GObject *object, guint prop_id, sink->device = g_value_dup_string(value); break; + case PROP_AUTOCONNECT: + sink->autoconnect = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -209,6 +215,9 @@ static void gst_avdtp_sink_get_property(GObject *object, guint prop_id, g_value_set_string(value, sink->device); break; + case PROP_AUTOCONNECT: + g_value_set_boolean(value, sink->autoconnect); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -764,6 +773,8 @@ static gboolean gst_avdtp_sink_get_capabilities(GstAvdtpSink *self) if (self->device == NULL) return FALSE; strncpy(req->device, self->device, 18); + if (self->autoconnect) + req->flags |= BT_FLAG_AUTOCONNECT; io_error = gst_avdtp_sink_audioservice_send(self, &req->h); if (io_error != G_IO_ERROR_NONE) { @@ -1198,6 +1209,13 @@ static void gst_avdtp_sink_class_init(GstAvdtpSinkClass *klass) "Bluetooth remote device address", NULL, G_PARAM_READWRITE)); + g_object_class_install_property(object_class, PROP_AUTOCONNECT, + g_param_spec_boolean("auto-connect", + "Auto-connect", + "Automatically attempt to connect " + "to device", DEFAULT_AUTOCONNECT, + G_PARAM_READWRITE)); + GST_DEBUG_CATEGORY_INIT(avdtp_sink_debug, "avdtpsink", 0, "A2DP headset sink element"); } @@ -1212,6 +1230,8 @@ static void gst_avdtp_sink_init(GstAvdtpSink *self, self->dev_caps = NULL; + self->autoconnect = DEFAULT_AUTOCONNECT; + self->sink_lock = g_mutex_new(); /* FIXME this is for not synchronizing with clock, should be tested diff --git a/audio/gstavdtpsink.h b/audio/gstavdtpsink.h index 237597da..333f1a4b 100644 --- a/audio/gstavdtpsink.h +++ b/audio/gstavdtpsink.h @@ -54,6 +54,7 @@ struct _GstAvdtpSink { GIOChannel *stream; struct bluetooth_data *data; + gboolean autoconnect; GIOChannel *server; /* mp3 stream data (outside caps data)*/ diff --git a/audio/gstsbcparse.c b/audio/gstsbcparse.c index 1f699620..80bf23a2 100644 --- a/audio/gstsbcparse.c +++ b/audio/gstsbcparse.c @@ -68,6 +68,7 @@ static GstFlowReturn sbc_parse_chain(GstPad *pad, GstBuffer *buffer) timestamp = GST_BUFFER_TIMESTAMP(buffer); + /* FIXME use a gstadpter */ if (parse->buffer) { GstBuffer *temp; temp = buffer; @@ -84,18 +85,29 @@ static GstFlowReturn sbc_parse_chain(GstPad *pad, GstBuffer *buffer) while (offset < size) { GstBuffer *output; - GstCaps *temp; int consumed; - consumed = sbc_parse(&parse->sbc, data + offset, size - offset); + consumed = sbc_parse(&parse->new_sbc, data + offset, + size - offset); if (consumed <= 0) break; - temp = GST_PAD_CAPS(parse->srcpad); + if (parse->first_parsing || (memcmp(&parse->sbc, + &parse->new_sbc, sizeof(sbc_t)) != 0)) { + + memcpy(&parse->sbc, &parse->new_sbc, sizeof(sbc_t)); + if (parse->outcaps != NULL) + gst_caps_unref(parse->outcaps); + + parse->outcaps = gst_sbc_parse_caps_from_sbc( + &parse->sbc); + + parse->first_parsing = FALSE; + } res = gst_pad_alloc_buffer_and_set_caps(parse->srcpad, GST_BUFFER_OFFSET_NONE, - consumed, temp, &output); + consumed, parse->outcaps, &output); if (res != GST_FLOW_OK) goto done; @@ -128,10 +140,11 @@ static GstStateChangeReturn sbc_parse_change_state(GstElement *element, switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: GST_DEBUG("Setup subband codec"); - if (parse->buffer) { - gst_buffer_unref(parse->buffer); - parse->buffer = NULL; - } + + parse->channels = -1; + parse->rate = -1; + parse->first_parsing = TRUE; + sbc_init(&parse->sbc, 0); break; @@ -142,8 +155,12 @@ static GstStateChangeReturn sbc_parse_change_state(GstElement *element, gst_buffer_unref(parse->buffer); parse->buffer = NULL; } - sbc_finish(&parse->sbc); + if (parse->outcaps != NULL) { + gst_caps_unref(parse->outcaps); + parse->outcaps = NULL; + } + sbc_finish(&parse->sbc); break; default: @@ -189,6 +206,12 @@ static void gst_sbc_parse_init(GstSbcParse *self, GstSbcParseClass *klass) self->srcpad = gst_pad_new_from_static_template( &sbc_parse_src_factory, "src"); gst_element_add_pad(GST_ELEMENT(self), self->srcpad); + + self->outcaps = NULL; + self->buffer = NULL; + self->channels = -1; + self->rate = -1; + self->first_parsing = TRUE; } gboolean gst_sbc_parse_plugin_init (GstPlugin * plugin) diff --git a/audio/gstsbcparse.h b/audio/gstsbcparse.h index eb9ca441..a71aea72 100644 --- a/audio/gstsbcparse.h +++ b/audio/gstsbcparse.h @@ -50,6 +50,9 @@ struct _GstSbcParse { GstBuffer *buffer; sbc_t sbc; + sbc_t new_sbc; + GstCaps *outcaps; + gboolean first_parsing; gint channels; gint rate; -- cgit