Index: gsta2dpsink.c =================================================================== RCS file: /cvsroot/bluez/utils/audio/gsta2dpsink.c,v retrieving revision 1.6 diff -u -3 -p -u -r1.6 gsta2dpsink.c --- gsta2dpsink.c 18 Oct 2007 23:02:24 -0000 1.6 +++ gsta2dpsink.c 23 Oct 2007 17:24:37 -0000 @@ -70,23 +70,18 @@ GST_DEBUG_CATEGORY_STATIC(a2dp_sink_debu g_cond_signal (s->con_conf_end); \ } G_STMT_END -struct bluetooth_a2dp { +struct bluetooth_data { + struct ipc_data_cfg cfg; /* Bluetooth device config */ sbc_t sbc; /* Codec data */ int codesize; /* SBC codesize */ int samples; /* Number of encoded samples */ - uint8_t buffer[BUFFER_SIZE]; /* Codec transfer buffer */ + gchar buffer[BUFFER_SIZE]; /* Codec transfer buffer */ int count; /* Codec transfer buffer counter */ int nsamples; /* Cumulative number of codec samples */ uint16_t seq_num; /* Cumulative packet sequence */ int frame_count; /* Current frames in buffer*/ }; -struct bluetooth_data { - struct ipc_data_cfg cfg; /* Bluetooth device config */ - uint8_t buffer[BUFFER_SIZE]; /* Encoded transfer buffer */ - int count; /* Transfer buffer counter */ - struct bluetooth_a2dp a2dp; /* A2DP data */ -}; #define IS_SBC(n) (strcmp((n), "audio/x-sbc") == 0) #define IS_MPEG(n) (strcmp((n), "audio/mpeg") == 0) @@ -132,15 +127,13 @@ static void gst_a2dp_sink_base_init(gpoi static gboolean gst_a2dp_sink_stop(GstBaseSink *basesink) { GstA2dpSink *self = GST_A2DP_SINK(basesink); - struct bluetooth_a2dp *a2dp = &self->data->a2dp; self->con_state = NOT_CONFIGURED; self->total = 0; - if (self->stream) { - g_io_channel_close(self->stream); - g_io_channel_unref(self->stream); - self->stream = NULL; + if (self->watch_id != -1) { + g_source_remove(self->watch_id); + self->watch_id = -1; } if (self->server) { @@ -149,10 +142,9 @@ static gboolean gst_a2dp_sink_stop(GstBa self->stream = NULL; } - if (self->data->cfg.codec == CFG_CODEC_SBC) - sbc_finish(&a2dp->sbc); - if (self->data) { + if (self->data->cfg.codec == CFG_CODEC_SBC) + sbc_finish(&self->data->sbc); g_free(self->data); self->data = NULL; } @@ -252,14 +244,14 @@ static gint gst_a2dp_sink_bluetooth_recv return -EINVAL; } -static int gst_a2dp_sink_bluetooth_a2dp_init(GstA2dpSink *sink, +static int gst_a2dp_sink_bluetooth_a2dp_init(GstA2dpSink *self, struct ipc_codec_sbc *sbc) { - struct bluetooth_a2dp *a2dp = &sink->data->a2dp; - struct ipc_data_cfg *cfg = &sink->data->cfg; + struct bluetooth_data *data = self->data; + struct ipc_data_cfg *cfg = &data->cfg; if (cfg == NULL) { - GST_ERROR_OBJECT(sink, "Error getting codec parameters"); + GST_ERROR_OBJECT(self, "Error getting codec parameters"); return -1; } @@ -267,24 +259,24 @@ static int gst_a2dp_sink_bluetooth_a2dp_ return -1; /* FIXME: init using flags? */ - sbc_init(&a2dp->sbc, 0); - a2dp->sbc.rate = cfg->rate; - a2dp->sbc.channels = cfg->mode == CFG_MODE_MONO ? 1 : 2; + sbc_init(&data->sbc, 0); + data->sbc.rate = cfg->rate; + data->sbc.channels = cfg->mode == CFG_MODE_MONO ? 1 : 2; if (cfg->mode == CFG_MODE_MONO || cfg->mode == CFG_MODE_JOINT_STEREO) - a2dp->sbc.joint = 1; - a2dp->sbc.allocation = sbc->allocation; - a2dp->sbc.subbands = sbc->subbands; - a2dp->sbc.blocks = sbc->blocks; - a2dp->sbc.bitpool = sbc->bitpool; - a2dp->codesize = a2dp->sbc.subbands * a2dp->sbc.blocks * - a2dp->sbc.channels * 2; - a2dp->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload); + data->sbc.joint = 1; + data->sbc.allocation = sbc->allocation; + data->sbc.subbands = sbc->subbands; + data->sbc.blocks = sbc->blocks; + data->sbc.bitpool = sbc->bitpool; + data->codesize = data->sbc.subbands * data->sbc.blocks * + data->sbc.channels * 2; + data->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload); - GST_DEBUG_OBJECT(sink, "Codec parameters: \ + GST_DEBUG_OBJECT(self, "Codec parameters: \ \tallocation=%u\n\tsubbands=%u\n \ \tblocks=%u\n\tbitpool=%u\n", - a2dp->sbc.allocation, a2dp->sbc.subbands, - a2dp->sbc.blocks, a2dp->sbc.bitpool); + data->sbc.allocation, data->sbc.subbands, + data->sbc.blocks, data->sbc.bitpool); return 0; } @@ -445,18 +437,19 @@ static gboolean gst_a2dp_sink_conf_recv_ return TRUE; } -static gboolean gst_a2dp_sink_conf_recv_stream_fd(GstA2dpSink *sink) +static gboolean gst_a2dp_sink_conf_recv_stream_fd(GstA2dpSink *self) { + struct bluetooth_data *data = self->data; gint ret; GIOError err; - gsize read; + gsize read=0; - ret = gst_a2dp_sink_bluetooth_recvmsg_fd(sink); + ret = gst_a2dp_sink_bluetooth_recvmsg_fd(self); if (ret < 0) return FALSE; - if (!sink->stream) { - GST_ERROR_OBJECT(sink, "Error while configuring device: " + if (!self->stream) { + GST_ERROR_OBJECT(self, "Error while configuring device: " "could not acquire audio socket"); return FALSE; } @@ -464,15 +457,14 @@ static gboolean gst_a2dp_sink_conf_recv_ /* It is possible there is some outstanding data in the pipe - we have to empty it */ while (1) { - err = g_io_channel_read(sink->stream, - (gchar *) sink->data->buffer, - (gsize) sink->data->cfg.pkt_len, + err = g_io_channel_read(self->stream, data->buffer, + (gsize) data->cfg.pkt_len, &read); if (err != G_IO_ERROR_NONE || read <= 0) break; } - memset(sink->data->buffer, 0, sizeof(sink->data->buffer)); + memset(data->buffer, 0, sizeof(data->buffer)); return TRUE; } @@ -512,10 +504,11 @@ static void gst_a2dp_sink_conf_recv_data static gboolean server_callback(GIOChannel *chan, GIOCondition cond, gpointer data) { - GstA2dpSink *sink = GST_A2DP_SINK(data); + GstA2dpSink *sink; switch (cond) { case G_IO_IN: + sink = GST_A2DP_SINK(data); if (sink->con_state != NOT_CONFIGURED && sink->con_state != CONFIGURED) gst_a2dp_sink_conf_recv_data(sink); @@ -526,12 +519,14 @@ static gboolean server_callback(GIOChann return FALSE; break; case G_IO_ERR: + sink = GST_A2DP_SINK(data); GST_WARNING_OBJECT(sink, "Untreated callback G_IO_ERR"); break; case G_IO_NVAL: return FALSE; break; default: + sink = GST_A2DP_SINK(data); GST_WARNING_OBJECT(sink, "Unexpected callback call"); break; } @@ -546,6 +541,8 @@ static gboolean gst_a2dp_sink_start(GstB gint sk; gint err; + self->watch_id = -1; + sk = socket(PF_LOCAL, SOCK_STREAM, 0); if (sk < 0) { err = errno; @@ -556,7 +553,7 @@ static gboolean gst_a2dp_sink_start(GstB if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { err = errno; - GST_ERROR_OBJECT(self, "Connection fail %s (%d)", + GST_ERROR_OBJECT(self, "Connection fail %s (%d)", strerror(err), err); close(sk); return FALSE; @@ -564,12 +561,18 @@ static gboolean gst_a2dp_sink_start(GstB self->server = g_io_channel_unix_new(sk); - g_io_add_watch(self->server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - server_callback, self); + self->watch_id = g_io_add_watch(self->server, G_IO_IN | G_IO_HUP | + G_IO_ERR | G_IO_NVAL, server_callback, self); self->data = g_new0(struct bluetooth_data, 1); memset(self->data, 0, sizeof(struct bluetooth_data)); + self->stream = NULL; + self->con_state = NOT_CONFIGURED; + self->total = 0; + + self->waiting_con_conf = FALSE; + return TRUE; } @@ -643,33 +646,30 @@ static GstFlowReturn gst_a2dp_sink_prero return GST_FLOW_OK; } -static int gst_a2dp_sink_avdtp_write(GstA2dpSink *sink) +static int gst_a2dp_sink_avdtp_write(GstA2dpSink *self) { int ret = 0; - struct bluetooth_data *data; + struct bluetooth_data *data = self->data; struct rtp_header *header; struct rtp_payload *payload; - struct bluetooth_a2dp *a2dp; GIOError err; - data = sink->data; - a2dp = &data->a2dp; - - header = (void *) a2dp->buffer; - payload = (void *) (a2dp->buffer + sizeof(*header)); + header = (void *) data->buffer; + payload = (void *) (data->buffer + sizeof(*header)); - memset(a2dp->buffer, 0, sizeof(*header) + sizeof(*payload)); + memset(data->buffer, 0, sizeof(*header) + sizeof(*payload)); - payload->frame_count = a2dp->frame_count; + payload->frame_count = data->frame_count; header->v = 2; header->pt = 1; - header->sequence_number = htons(a2dp->seq_num); - header->timestamp = htonl(a2dp->nsamples); + header->sequence_number = htons(data->seq_num); + header->timestamp = htonl(data->nsamples); header->ssrc = htonl(1); while (1) { - err = g_io_channel_write(sink->stream, (const char *) a2dp->buffer, - (gsize) a2dp->count, (gsize *) &ret); + err = g_io_channel_write(self->stream, data->buffer, + (gsize) data->count, + (gsize *) &ret); if (err == G_IO_ERROR_AGAIN) { usleep (100); @@ -680,10 +680,10 @@ static int gst_a2dp_sink_avdtp_write(Gst } /* Reset buffer of data to send */ - a2dp->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload); - a2dp->frame_count = 0; - a2dp->samples = 0; - a2dp->seq_num++; + data->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload); + data->frame_count = 0; + data->samples = 0; + data->seq_num++; return ret; } @@ -691,29 +691,22 @@ static int gst_a2dp_sink_avdtp_write(Gst static GstFlowReturn gst_a2dp_sink_render(GstBaseSink *basesink, GstBuffer *buffer) { - GstA2dpSink *sink; - struct bluetooth_data *data; - struct bluetooth_a2dp *a2dp; - gint encoded, frame_size=1024; - gint ret=0; - - sink = GST_A2DP_SINK(basesink); - data = (struct bluetooth_data*) sink->data; - a2dp = &data->a2dp; + GstA2dpSink *self = GST_A2DP_SINK(basesink); + struct bluetooth_data *data = self->data; + gint encoded = 0; + gint ret = 0; encoded = GST_BUFFER_SIZE(buffer); - if (a2dp->count + encoded >= data->cfg.pkt_len) { - ret = gst_a2dp_sink_avdtp_write(sink); + if (data->count + encoded >= data->cfg.pkt_len) { + ret = gst_a2dp_sink_avdtp_write(self); if (ret < 0) return GST_FLOW_ERROR; } - memcpy(a2dp->buffer + a2dp->count, GST_BUFFER_DATA(buffer), encoded); - a2dp->count += encoded; - a2dp->frame_count++; - a2dp->samples += encoded / frame_size; - a2dp->nsamples += encoded / frame_size; + memcpy(data->buffer + data->count, GST_BUFFER_DATA(buffer), encoded); + data->count += encoded; + data->frame_count++; return GST_FLOW_OK; } Index: gsta2dpsink.h =================================================================== RCS file: /cvsroot/bluez/utils/audio/gsta2dpsink.h,v retrieving revision 1.4 diff -u -3 -p -u -r1.4 gsta2dpsink.h --- gsta2dpsink.h 18 Oct 2007 21:50:00 -0000 1.4 +++ gsta2dpsink.h 23 Oct 2007 17:24:37 -0000 @@ -67,6 +67,7 @@ struct _GstA2dpSink { GMutex *sink_lock; gint total; + gint watch_id; }; Index: manager.c =================================================================== RCS file: /cvsroot/bluez/utils/audio/manager.c,v retrieving revision 1.75 diff -u -3 -p -u -r1.75 manager.c --- manager.c 9 Oct 2007 13:31:57 -0000 1.75 +++ manager.c 23 Oct 2007 17:24:37 -0000 @@ -1078,10 +1078,9 @@ static void register_devices_stored(cons bacpy(&default_src, BDADDR_ANY); dev_id = hci_get_route(&default_src); - if (dev_id < 0) + if (dev_id < 0 || hci_devba(dev_id, &default_src)) return; - hci_devba(dev_id, &default_src); if (bacmp(&default_src, &src) != 0) return;