3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2012 Collabora Ltd.
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.
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.
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
32 #include <gst/rtp/gstrtppayloads.h>
33 #include "gstavdtpsrc.h"
35 GST_DEBUG_CATEGORY_STATIC (avdtpsrc_debug);
36 #define GST_CAT_DEFAULT (avdtpsrc_debug)
44 GST_BOILERPLATE (GstAvdtpSrc, gst_avdtp_src, GstBaseSrc, GST_TYPE_BASE_SRC);
46 static GstStaticPadTemplate gst_avdtp_src_template =
47 GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
48 GST_STATIC_CAPS ("application/x-rtp, "
49 "media = (string) \"audio\","
51 GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
52 "clock-rate = (int) { 16000, 32000, "
53 "44100, 48000 }, " "encoding-name = (string) \"SBC\"; "));
55 static void gst_avdtp_src_finalize (GObject * object);
56 static void gst_avdtp_src_get_property (GObject * object, guint prop_id,
57 GValue * value, GParamSpec * pspec);
58 static void gst_avdtp_src_set_property (GObject * object, guint prop_id,
59 const GValue * value, GParamSpec * pspec);
61 static GstCaps *gst_avdtp_src_getcaps (GstPad * pad);
62 static gboolean gst_avdtp_src_start (GstBaseSrc * bsrc);
63 static gboolean gst_avdtp_src_stop (GstBaseSrc * bsrc);
64 static GstFlowReturn gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset,
65 guint length, GstBuffer ** outbuf);
66 static gboolean gst_avdtp_src_unlock (GstBaseSrc * bsrc);
67 static gboolean gst_avdtp_src_unlock_stop (GstBaseSrc * bsrc);
70 gst_avdtp_src_base_init (gpointer klass)
72 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
74 gst_element_class_add_pad_template (element_class,
75 gst_static_pad_template_get (&gst_avdtp_src_template));
77 gst_element_class_set_details_simple (element_class,
78 "Bluetooth AVDTP Source",
79 "Source/Audio/Network/RTP",
80 "Receives audio from an A2DP device",
81 "Arun Raghavan <arun.raghavan@collabora.co.uk>");
85 gst_avdtp_src_class_init (GstAvdtpSrcClass * klass)
87 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
88 GstBaseSrcClass *basesrc_class = GST_BASE_SRC_CLASS (klass);
90 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avdtp_src_finalize);
91 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avdtp_src_set_property);
92 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avdtp_src_get_property);
94 basesrc_class->start = GST_DEBUG_FUNCPTR (gst_avdtp_src_start);
95 basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_avdtp_src_stop);
96 basesrc_class->create = GST_DEBUG_FUNCPTR (gst_avdtp_src_create);
97 basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_avdtp_src_unlock);
98 basesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_avdtp_src_unlock_stop);
100 g_object_class_install_property (gobject_class, PROP_TRANSPORT,
101 g_param_spec_string ("transport",
102 "Transport", "Use configured transport", NULL, G_PARAM_READWRITE));
104 GST_DEBUG_CATEGORY_INIT (avdtpsrc_debug, "avdtpsrc", 0,
105 "Bluetooth AVDTP Source");
109 gst_avdtp_src_init (GstAvdtpSrc * avdtpsrc, GstAvdtpSrcClass * klass)
111 avdtpsrc->poll = gst_poll_new (TRUE);
113 gst_base_src_set_format (GST_BASE_SRC (avdtpsrc), GST_FORMAT_DEFAULT);
114 gst_base_src_set_live (GST_BASE_SRC (avdtpsrc), TRUE);
115 gst_base_src_set_do_timestamp (GST_BASE_SRC (avdtpsrc), TRUE);
117 gst_pad_set_getcaps_function (GST_BASE_SRC_PAD (avdtpsrc),
118 GST_DEBUG_FUNCPTR (gst_avdtp_src_getcaps));
122 gst_avdtp_src_finalize (GObject * object)
124 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (object);
126 gst_poll_free (avdtpsrc->poll);
128 gst_avdtp_connection_reset (&avdtpsrc->conn);
130 G_OBJECT_CLASS (parent_class)->finalize (object);
134 gst_avdtp_src_get_property (GObject * object, guint prop_id,
135 GValue * value, GParamSpec * pspec)
137 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (object);
141 g_value_set_string (value, avdtpsrc->conn.transport);
145 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
151 gst_avdtp_src_set_property (GObject * object, guint prop_id,
152 const GValue * value, GParamSpec * pspec)
154 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (object);
158 gst_avdtp_connection_set_transport (&avdtpsrc->conn,
159 g_value_get_string (value));
163 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
169 gst_avdtp_src_getcaps (GstPad * pad)
171 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (gst_pad_get_parent_element (pad));
174 if (avdtpsrc->dev_caps) {
178 GstStructure *structure = gst_caps_get_structure (avdtpsrc->dev_caps, 0);
180 format = gst_structure_get_name (structure);
182 if (g_str_equal (format, "audio/x-sbc")) {
183 ret = gst_caps_new_simple ("application/x-rtp",
184 "encoding-name", G_TYPE_STRING, "SBC", NULL);
185 } else if (g_str_equal (format, "audio/mpeg")) {
186 GST_ERROR_OBJECT (avdtpsrc, "Only SBC is supported at " "the moment");
189 value = gst_structure_get_value (structure, "rate");
190 if (!value || !G_VALUE_HOLDS_INT (value)) {
191 GST_ERROR_OBJECT (avdtpsrc, "Failed to get sample rate");
194 rate = g_value_get_int (value);
196 gst_caps_set_simple (ret, "clock-rate", G_TYPE_INT, rate, NULL);
198 ret = gst_caps_ref (GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad)));
205 gst_caps_unref (ret);
211 gst_avdtp_src_start (GstBaseSrc * bsrc)
213 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
215 /* None of this can go into prepare() since we need to set up the
216 * connection to figure out what format the device is going to send us.
219 if (!gst_avdtp_connection_acquire (&avdtpsrc->conn)) {
220 GST_ERROR_OBJECT (avdtpsrc, "Failed to acquire connection");
224 if (!gst_avdtp_connection_get_properties (&avdtpsrc->conn)) {
225 GST_ERROR_OBJECT (avdtpsrc, "Failed to get transport properties");
229 if (!gst_avdtp_connection_conf_recv_stream_fd (&avdtpsrc->conn)) {
230 GST_ERROR_OBJECT (avdtpsrc, "Failed to configure stream fd");
234 GST_DEBUG_OBJECT (avdtpsrc, "Setting block size to link MTU (%d)",
235 avdtpsrc->conn.data.link_mtu);
236 gst_base_src_set_blocksize (GST_BASE_SRC (avdtpsrc),
237 avdtpsrc->conn.data.link_mtu);
239 avdtpsrc->dev_caps = gst_avdtp_connection_get_caps (&avdtpsrc->conn);
240 if (!avdtpsrc->dev_caps) {
241 GST_ERROR_OBJECT (avdtpsrc, "Failed to get device caps");
245 gst_poll_fd_init (&avdtpsrc->pfd);
246 avdtpsrc->pfd.fd = g_io_channel_unix_get_fd (avdtpsrc->conn.stream);
248 gst_poll_add_fd (avdtpsrc->poll, &avdtpsrc->pfd);
249 gst_poll_fd_ctl_read (avdtpsrc->poll, &avdtpsrc->pfd, TRUE);
250 gst_poll_set_flushing (avdtpsrc->poll, FALSE);
252 g_atomic_int_set (&avdtpsrc->unlocked, FALSE);
257 gst_avdtp_connection_release (&avdtpsrc->conn);
262 gst_avdtp_src_stop (GstBaseSrc * bsrc)
264 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
266 gst_poll_remove_fd (avdtpsrc->poll, &avdtpsrc->pfd);
267 gst_poll_set_flushing (avdtpsrc->poll, TRUE);
269 gst_avdtp_connection_release (&avdtpsrc->conn);
271 if (avdtpsrc->dev_caps) {
272 gst_caps_unref (avdtpsrc->dev_caps);
273 avdtpsrc->dev_caps = NULL;
280 gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset,
281 guint length, GstBuffer ** outbuf)
283 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
284 GstBuffer *buf = NULL;
287 if (g_atomic_int_get (&avdtpsrc->unlocked))
288 return GST_FLOW_WRONG_STATE;
290 /* We don't operate in GST_FORMAT_BYTES, so offset is ignored */
292 while ((ret = gst_poll_wait (avdtpsrc->poll, GST_CLOCK_TIME_NONE))) {
293 if (g_atomic_int_get (&avdtpsrc->unlocked))
294 /* We're unlocked, time to gtfo */
295 return GST_FLOW_WRONG_STATE;
298 /* Something went wrong */
306 buf = gst_buffer_new_and_alloc (length);
307 ret = read (avdtpsrc->pfd.fd, GST_BUFFER_DATA (buf), length);
312 GST_LOG_OBJECT (avdtpsrc, "Read %d bytes", ret);
315 /* Create a subbuffer for as much as we've actually read */
316 *outbuf = gst_buffer_create_sub (buf, 0, ret);
317 gst_buffer_unref (buf);
324 gst_buffer_unref (buf);
326 GST_ERROR_OBJECT (avdtpsrc, "Error while reading audio data: %s",
329 return GST_FLOW_ERROR;
333 gst_avdtp_src_unlock (GstBaseSrc * bsrc)
335 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
337 g_atomic_int_set (&avdtpsrc->unlocked, TRUE);
339 gst_poll_set_flushing (avdtpsrc->poll, TRUE);
343 gst_avdtp_src_unlock_stop (GstBaseSrc * bsrc)
345 GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
347 g_atomic_int_set (&avdtpsrc->unlocked, FALSE);
349 gst_poll_set_flushing (avdtpsrc->poll, FALSE);
351 /* Flush out any stale data that might be buffered */
352 gst_avdtp_connection_conf_recv_stream_fd (&avdtpsrc->conn);
356 gst_avdtp_src_plugin_init (GstPlugin * plugin)
358 return gst_element_register (plugin, "avdtpsrc", GST_RANK_NONE,