summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
Diffstat (limited to 'audio')
-rw-r--r--audio/gsta2dpsink.c28
-rw-r--r--audio/gsta2dpsink.h1
-rw-r--r--audio/gstavdtpsink.c20
-rw-r--r--audio/gstavdtpsink.h1
-rw-r--r--audio/gstsbcparse.c41
-rw-r--r--audio/gstsbcparse.h3
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;