1 /*
2 *
3 * BlueZ - Bluetooth protocol stack for Linux
4 *
5 * Copyright (C) 2012 Collabora Ltd.
6 *
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <unistd.h>
29 #include <stdint.h>
30 #include <string.h>
31 #include <poll.h>
32
33 #include <gst/rtp/gstrtppayloads.h>
34 #include "gstbluezelements.h"
35 #include "gstavdtpsrc.h"
36
37 GST_DEBUG_CATEGORY_STATIC (avdtpsrc_debug);
38 #define GST_CAT_DEFAULT (avdtpsrc_debug)
39
40 #define DEFAULT_VOLUME 127
41
42 enum
43 {
44 PROP_0,
45 PROP_TRANSPORT,
46 PROP_TRANSPORT_VOLUME,
47 };
48
49 #define parent_class gst_avdtp_src_parent_class
50 G_DEFINE_TYPE (GstAvdtpSrc, gst_avdtp_src, GST_TYPE_BASE_SRC);
51 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (avdtpsrc, "avdtpsrc", GST_RANK_NONE,
52 GST_TYPE_AVDTP_SRC, bluez_element_init (plugin));
53
54 static GstStaticPadTemplate gst_avdtp_src_template =
55 GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
56 GST_STATIC_CAPS ("application/x-rtp, "
57 "media = (string) \"audio\","
58 "payload = (int) "
59 GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
60 "clock-rate = (int) { 16000, 32000, "
61 "44100, 48000 }, " "encoding-name = (string) \"SBC\"; "
62 "application/x-rtp, "
63 "media = (string) \"audio\","
64 "payload = (int) "
65 GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
66 "clock-rate = (int) { 8000, 11025, 12000, 16000, "
67 "22050, 2400, 32000, 44100, 48000, 64000, 88200, 96000 }, "
68 "encoding-name = (string) \"MP4A-LATM\"; "));
69
70 static void gst_avdtp_src_finalize (GObject * object);
71 static void gst_avdtp_src_get_property (GObject * object, guint prop_id,
72 GValue * value, GParamSpec * pspec);
73 static void gst_avdtp_src_set_property (GObject * object, guint prop_id,
74 const GValue * value, GParamSpec * pspec);
75
76 static GstCaps *gst_avdtp_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter);
77 static gboolean gst_avdtp_src_query (GstBaseSrc * bsrc, GstQuery * query);
78 static gboolean gst_avdtp_src_start (GstBaseSrc * bsrc);
79 static gboolean gst_avdtp_src_stop (GstBaseSrc * bsrc);
80 static GstFlowReturn gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset,
81 guint length, GstBuffer ** outbuf);
82 static gboolean gst_avdtp_src_unlock (GstBaseSrc * bsrc);
83 static gboolean gst_avdtp_src_unlock_stop (GstBaseSrc * bsrc);
84
85 static void
gst_avdtp_src_class_init(GstAvdtpSrcClass * klass)86 gst_avdtp_src_class_init (GstAvdtpSrcClass * klass)
87 {
88 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
89 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
90 GstBaseSrcClass *basesrc_class = GST_BASE_SRC_CLASS (klass);
91
92 parent_class = g_type_class_peek_parent (klass);
93
94 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avdtp_src_finalize);
95 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avdtp_src_set_property);
96 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avdtp_src_get_property);
97
98 basesrc_class->start = GST_DEBUG_FUNCPTR (gst_avdtp_src_start);
99 basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_avdtp_src_stop);
100 basesrc_class->create = GST_DEBUG_FUNCPTR (gst_avdtp_src_create);
101 basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_avdtp_src_unlock);
102 basesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_avdtp_src_unlock_stop);
103 basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_avdtp_src_getcaps);
104 basesrc_class->query = GST_DEBUG_FUNCPTR (gst_avdtp_src_query);
105
106 g_object_class_install_property (gobject_class, PROP_TRANSPORT,
107 g_param_spec_string ("transport",
108 "Transport", "Use configured transport", NULL, G_PARAM_READWRITE));
109
110 g_object_class_install_property (gobject_class, PROP_TRANSPORT_VOLUME,
111 g_param_spec_uint ("transport-volume",
112 "Transport volume",
113 "Volume of the transport (only valid if transport is acquired)",
114 0, 127, DEFAULT_VOLUME, G_PARAM_READWRITE));
115
116 gst_element_class_set_static_metadata (element_class,
117 "Bluetooth AVDTP Source",
118 "Source/Audio/Network/RTP",
119 "Receives audio from an A2DP device",
120 "Arun Raghavan <arun.raghavan@collabora.co.uk>");
121
122 GST_DEBUG_CATEGORY_INIT (avdtpsrc_debug, "avdtpsrc", 0,
123 "Bluetooth AVDTP Source");
124
125 gst_element_class_add_static_pad_template (element_class,
126 &gst_avdtp_src_template);
127 }
128
129 static void
gst_avdtp_src_init(GstAvdtpSrc * avdtpsrc)130 gst_avdtp_src_init (GstAvdtpSrc * avdtpsrc)
131 {
132 avdtpsrc->poll = gst_poll_new (TRUE);
133
134 avdtpsrc->duration = GST_CLOCK_TIME_NONE;
135 avdtpsrc->transport_volume = DEFAULT_VOLUME;
136
137 gst_base_src_set_format (GST_BASE_SRC (avdtpsrc), GST_FORMAT_TIME);
138 gst_base_src_set_live (GST_BASE_SRC (avdtpsrc), TRUE);
139 gst_base_src_set_do_timestamp (GST_BASE_SRC (avdtpsrc), TRUE);
140 }
141
142 static void
gst_avdtp_src_finalize(GObject * object)143 gst_avdtp_src_finalize (GObject * object)
144 {
145 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (object);
146
147 gst_poll_free (avdtpsrc->poll);
148
149 gst_avdtp_connection_reset (&avdtpsrc->conn);
150
151 G_OBJECT_CLASS (parent_class)->finalize (object);
152 }
153
154 static void
gst_avdtp_src_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)155 gst_avdtp_src_get_property (GObject * object, guint prop_id,
156 GValue * value, GParamSpec * pspec)
157 {
158 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (object);
159
160 switch (prop_id) {
161 case PROP_TRANSPORT:
162 g_value_set_string (value, avdtpsrc->conn.transport);
163 break;
164
165 case PROP_TRANSPORT_VOLUME:
166 g_value_set_uint (value, avdtpsrc->transport_volume);
167 break;
168
169 default:
170 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
171 break;
172 }
173 }
174
175 static void
gst_avdtp_src_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)176 gst_avdtp_src_set_property (GObject * object, guint prop_id,
177 const GValue * value, GParamSpec * pspec)
178 {
179 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (object);
180
181 switch (prop_id) {
182 case PROP_TRANSPORT:
183 gst_avdtp_connection_set_transport (&avdtpsrc->conn,
184 g_value_get_string (value));
185 break;
186
187 case PROP_TRANSPORT_VOLUME:
188 avdtpsrc->transport_volume = g_value_get_uint (value);
189 break;
190
191 default:
192 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
193 break;
194 }
195 }
196
197 static gboolean
gst_avdtp_src_query(GstBaseSrc * bsrc,GstQuery * query)198 gst_avdtp_src_query (GstBaseSrc * bsrc, GstQuery * query)
199 {
200 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
201 gboolean ret = FALSE;
202
203 switch (GST_QUERY_TYPE (query)) {
204 case GST_QUERY_DURATION:{
205 GstFormat format;
206
207 if (avdtpsrc->duration != GST_CLOCK_TIME_NONE) {
208 gst_query_parse_duration (query, &format, NULL);
209
210 if (format == GST_FORMAT_TIME) {
211 gst_query_set_duration (query, format, (gint64) avdtpsrc->duration);
212 ret = TRUE;
213 }
214 }
215
216 break;
217 }
218
219 default:
220 ret = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
221 }
222
223 return ret;
224 }
225
226 static GstCaps *
gst_avdtp_src_getcaps(GstBaseSrc * bsrc,GstCaps * filter)227 gst_avdtp_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
228 {
229 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
230 GstCaps *caps = NULL, *ret = NULL;
231
232 if (avdtpsrc->dev_caps) {
233 const GValue *value;
234 const char *format;
235 int rate;
236 GstStructure *structure = gst_caps_get_structure (avdtpsrc->dev_caps, 0);
237
238 format = gst_structure_get_name (structure);
239
240 if (g_str_equal (format, "audio/x-sbc")) {
241 /* FIXME: we can return a fixed payload type once we
242 * are in PLAYING */
243 caps = gst_caps_new_simple ("application/x-rtp",
244 "media", G_TYPE_STRING, "audio",
245 "payload", GST_TYPE_INT_RANGE, 96, 127,
246 "encoding-name", G_TYPE_STRING, "SBC", NULL);
247 } else if (g_str_equal (format, "audio/mpeg")) {
248 caps = gst_caps_new_simple ("application/x-rtp",
249 "media", G_TYPE_STRING, "audio",
250 "payload", GST_TYPE_INT_RANGE, 96, 127,
251 "encoding-name", G_TYPE_STRING, "MP4A-LATM", NULL);
252
253 value = gst_structure_get_value (structure, "mpegversion");
254 if (!value || !G_VALUE_HOLDS_INT (value)) {
255 GST_ERROR_OBJECT (avdtpsrc, "Failed to get mpegversion");
256 gst_caps_unref (caps);
257 return NULL;
258 }
259 gst_caps_set_simple (caps, "mpegversion", G_TYPE_INT,
260 g_value_get_int (value), NULL);
261
262 value = gst_structure_get_value (structure, "channels");
263 if (!value || !G_VALUE_HOLDS_INT (value)) {
264 GST_ERROR_OBJECT (avdtpsrc, "Failed to get channels");
265 gst_caps_unref (caps);
266 return NULL;
267 }
268 gst_caps_set_simple (caps, "channels", G_TYPE_INT,
269 g_value_get_int (value), NULL);
270
271 value = gst_structure_get_value (structure, "base-profile");
272 if (!value || !G_VALUE_HOLDS_STRING (value)) {
273 GST_ERROR_OBJECT (avdtpsrc, "Failed to get base-profile");
274 gst_caps_unref (caps);
275 return NULL;
276 }
277 gst_caps_set_simple (caps, "base-profile", G_TYPE_STRING,
278 g_value_get_string (value), NULL);
279
280 } else {
281 GST_ERROR_OBJECT (avdtpsrc,
282 "Only SBC and MPEG-2/4 are supported at the moment");
283 }
284
285 value = gst_structure_get_value (structure, "rate");
286 if (!value || !G_VALUE_HOLDS_INT (value)) {
287 GST_ERROR_OBJECT (avdtpsrc, "Failed to get sample rate");
288 gst_caps_unref (caps);
289 return NULL;
290 }
291 rate = g_value_get_int (value);
292
293 gst_caps_set_simple (caps, "clock-rate", G_TYPE_INT, rate, NULL);
294
295 if (filter) {
296 ret = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
297 gst_caps_unref (caps);
298 } else
299 ret = caps;
300 } else {
301 GST_DEBUG_OBJECT (avdtpsrc, "device not open, using template caps");
302 ret = GST_BASE_SRC_CLASS (parent_class)->get_caps (bsrc, filter);
303 }
304
305 return ret;
306 }
307
308 static void
avrcp_metadata_cb(GstAvrcpConnection * avrcp,GstTagList * taglist,gpointer user_data)309 avrcp_metadata_cb (GstAvrcpConnection * avrcp, GstTagList * taglist,
310 gpointer user_data)
311 {
312 GstAvdtpSrc *src = GST_AVDTP_SRC (user_data);
313 guint64 duration;
314
315 if (gst_tag_list_get_uint64 (taglist, GST_TAG_DURATION, &duration)) {
316 src->duration = duration;
317 gst_element_post_message (GST_ELEMENT (src),
318 gst_message_new_duration_changed (GST_OBJECT (src)));
319 }
320
321 gst_pad_push_event (GST_BASE_SRC_PAD (src),
322 gst_event_new_tag (gst_tag_list_copy (taglist)));
323 gst_element_post_message (GST_ELEMENT (src),
324 gst_message_new_tag (GST_OBJECT (src), taglist));
325 }
326
327 static void
gst_avdtp_src_start_avrcp(GstAvdtpSrc * src)328 gst_avdtp_src_start_avrcp (GstAvdtpSrc * src)
329 {
330 gchar *path, **strv;
331 int i;
332
333 /* Strip out the /fdX in /org/bluez/dev_.../fdX */
334 strv = g_strsplit (src->conn.transport, "/", -1);
335
336 for (i = 0; strv[i]; i++);
337 g_return_if_fail (i > 0);
338
339 g_free (strv[i - 1]);
340 strv[i - 1] = NULL;
341
342 path = g_strjoinv ("/", strv);
343 g_strfreev (strv);
344
345 src->avrcp = gst_avrcp_connection_new (path, avrcp_metadata_cb, src, NULL);
346
347 g_free (path);
348 }
349
350 static void
gst_avdtp_src_stop_avrcp(GstAvdtpSrc * src)351 gst_avdtp_src_stop_avrcp (GstAvdtpSrc * src)
352 {
353 gst_avrcp_connection_free (src->avrcp);
354 }
355
356 static gboolean
gst_avdtp_src_start(GstBaseSrc * bsrc)357 gst_avdtp_src_start (GstBaseSrc * bsrc)
358 {
359 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
360
361 /* None of this can go into prepare() since we need to set up the
362 * connection to figure out what format the device is going to send us.
363 */
364
365 if (!gst_avdtp_connection_acquire (&avdtpsrc->conn, FALSE)) {
366 GST_ERROR_OBJECT (avdtpsrc, "Failed to acquire connection");
367 return FALSE;
368 }
369
370 if (!gst_avdtp_connection_get_properties (&avdtpsrc->conn)) {
371 GST_ERROR_OBJECT (avdtpsrc, "Failed to get transport properties");
372 goto fail;
373 }
374
375 if (!gst_avdtp_connection_conf_recv_stream_fd (&avdtpsrc->conn)) {
376 GST_ERROR_OBJECT (avdtpsrc, "Failed to configure stream fd");
377 goto fail;
378 }
379
380 GST_DEBUG_OBJECT (avdtpsrc, "Setting block size to link MTU (%d)",
381 avdtpsrc->conn.data.link_mtu);
382 gst_base_src_set_blocksize (GST_BASE_SRC (avdtpsrc),
383 avdtpsrc->conn.data.link_mtu);
384
385 avdtpsrc->dev_caps = gst_avdtp_connection_get_caps (&avdtpsrc->conn);
386 if (!avdtpsrc->dev_caps) {
387 GST_ERROR_OBJECT (avdtpsrc, "Failed to get device caps");
388 goto fail;
389 }
390
391 gst_poll_fd_init (&avdtpsrc->pfd);
392 avdtpsrc->pfd.fd = g_io_channel_unix_get_fd (avdtpsrc->conn.stream);
393
394 gst_poll_add_fd (avdtpsrc->poll, &avdtpsrc->pfd);
395 gst_poll_fd_ctl_read (avdtpsrc->poll, &avdtpsrc->pfd, TRUE);
396 gst_poll_set_flushing (avdtpsrc->poll, FALSE);
397
398 g_atomic_int_set (&avdtpsrc->unlocked, FALSE);
399
400 /* The life time of the connection is shorter than the src object, so we
401 * don't need to worry about memory management */
402 gst_avdtp_connection_notify_volume (&avdtpsrc->conn, G_OBJECT (avdtpsrc),
403 "transport-volume");
404
405 gst_avdtp_src_start_avrcp (avdtpsrc);
406
407 return TRUE;
408
409 fail:
410 gst_avdtp_connection_release (&avdtpsrc->conn);
411 return FALSE;
412 }
413
414 static gboolean
gst_avdtp_src_stop(GstBaseSrc * bsrc)415 gst_avdtp_src_stop (GstBaseSrc * bsrc)
416 {
417 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
418
419 gst_poll_remove_fd (avdtpsrc->poll, &avdtpsrc->pfd);
420 gst_poll_set_flushing (avdtpsrc->poll, TRUE);
421
422 gst_avdtp_src_stop_avrcp (avdtpsrc);
423 gst_avdtp_connection_release (&avdtpsrc->conn);
424
425 if (avdtpsrc->dev_caps) {
426 gst_caps_unref (avdtpsrc->dev_caps);
427 avdtpsrc->dev_caps = NULL;
428 }
429
430 return TRUE;
431 }
432
433 static GstFlowReturn
gst_avdtp_src_create(GstBaseSrc * bsrc,guint64 offset,guint length,GstBuffer ** outbuf)434 gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
435 GstBuffer ** outbuf)
436 {
437 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
438 GstBuffer *buf = NULL;
439 GstMapInfo info;
440 int ret;
441
442 if (g_atomic_int_get (&avdtpsrc->unlocked))
443 return GST_FLOW_FLUSHING;
444
445 /* We don't operate in GST_FORMAT_BYTES, so offset is ignored */
446
447 while ((ret = gst_poll_wait (avdtpsrc->poll, GST_CLOCK_TIME_NONE))) {
448 if (g_atomic_int_get (&avdtpsrc->unlocked))
449 /* We're unlocked, time to gtfo */
450 return GST_FLOW_FLUSHING;
451
452 if (ret < 0)
453 /* Something went wrong */
454 goto read_error;
455
456 if (ret > 0)
457 /* Got some data */
458 break;
459 }
460
461 ret = GST_BASE_SRC_CLASS (parent_class)->alloc (bsrc, offset, length, outbuf);
462 if (G_UNLIKELY (ret != GST_FLOW_OK))
463 goto alloc_failed;
464
465 buf = *outbuf;
466
467 gst_buffer_map (buf, &info, GST_MAP_WRITE);
468
469 ret = read (avdtpsrc->pfd.fd, info.data, length);
470
471 if (ret < 0)
472 goto read_error;
473 else if (ret == 0) {
474 GST_INFO_OBJECT (avdtpsrc, "Got EOF on the transport fd");
475 goto eof;
476 }
477
478 if (ret < length)
479 gst_buffer_set_size (buf, ret);
480
481 GST_LOG_OBJECT (avdtpsrc, "Read %d bytes", ret);
482
483 gst_buffer_unmap (buf, &info);
484 *outbuf = buf;
485
486 return GST_FLOW_OK;
487
488 alloc_failed:
489 {
490 GST_DEBUG_OBJECT (bsrc, "alloc failed: %s", gst_flow_get_name (ret));
491 return ret;
492 }
493
494 read_error:
495 GST_ERROR_OBJECT (avdtpsrc, "Error while reading audio data: %s",
496 strerror (errno));
497 gst_buffer_unref (buf);
498 return GST_FLOW_ERROR;
499
500 eof:
501 gst_buffer_unref (buf);
502 return GST_FLOW_EOS;
503 }
504
505 static gboolean
gst_avdtp_src_unlock(GstBaseSrc * bsrc)506 gst_avdtp_src_unlock (GstBaseSrc * bsrc)
507 {
508 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
509
510 g_atomic_int_set (&avdtpsrc->unlocked, TRUE);
511
512 gst_poll_set_flushing (avdtpsrc->poll, TRUE);
513
514 return TRUE;
515 }
516
517 static gboolean
gst_avdtp_src_unlock_stop(GstBaseSrc * bsrc)518 gst_avdtp_src_unlock_stop (GstBaseSrc * bsrc)
519 {
520 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
521
522 g_atomic_int_set (&avdtpsrc->unlocked, FALSE);
523
524 gst_poll_set_flushing (avdtpsrc->poll, FALSE);
525
526 /* Flush out any stale data that might be buffered */
527 gst_avdtp_connection_conf_recv_stream_fd (&avdtpsrc->conn);
528
529 return TRUE;
530 }
531