diff --git a/sys/bluez/gsta2dpsink.c b/sys/bluez/gsta2dpsink.c index a1beb7db6c..a515fc8e3c 100644 --- a/sys/bluez/gsta2dpsink.c +++ b/sys/bluez/gsta2dpsink.c @@ -39,7 +39,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_a2dp_sink_debug); #define GST_CAT_DEFAULT gst_a2dp_sink_debug #define A2DP_SBC_RTP_PAYLOAD_TYPE 1 -#define TEMPLATE_MAX_BITPOOL_STR "64" #define DEFAULT_AUTOCONNECT TRUE diff --git a/sys/bluez/gsta2dpsrc.c b/sys/bluez/gsta2dpsrc.c new file mode 100644 index 0000000000..00a355eb1e --- /dev/null +++ b/sys/bluez/gsta2dpsrc.c @@ -0,0 +1,192 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Collabora Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "gsta2dpsrc.h" +#include "gstavdtputil.h" + +GST_DEBUG_CATEGORY (a2dpsrc_debug); +#define GST_CAT_DEFAULT (a2dpsrc_debug) + +enum +{ + PROP_0, + PROP_TRANSPORT +}; + +GST_BOILERPLATE (GstA2dpSrc, gst_a2dp_src, GstBin, GST_TYPE_BIN); + +static void gst_a2dp_src_finalize (GObject * object); +static void gst_a2dp_src_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static void gst_a2dp_src_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); + +static GstStaticPadTemplate gst_a2dp_src_template = +GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/x-sbc, " + "rate = (int) { 16000, 32000, 44100, 48000 }, " + "channels = (int) [ 1, 2 ], " + "mode = (string) { \"mono\", \"dual\", " + "\"stereo\", \"joint\" }, " + "blocks = (int) { 4, 8, 12, 16 }, " + "subbands = (int) { 4, 8 }, " + "allocation = (string) { \"snr\", \"loudness\" }, " + "bitpool = (int) [ 2, " TEMPLATE_MAX_BITPOOL_STR " ]")); + +static void +gst_a2dp_src_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_a2dp_src_template)); + + gst_element_class_set_details_simple (element_class, + "Bluetooth A2DP Source", + "Source/Audio/Network", + "Receives and depayloads audio from an A2DP device", + "Arun Raghavan "); +} + +static void +gst_a2dp_src_class_init (GstA2dpSrcClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_a2dp_src_finalize); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_a2dp_src_set_property); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_a2dp_src_get_property); + + g_object_class_install_property (gobject_class, PROP_TRANSPORT, + g_param_spec_string ("transport", + "Transport", "Use configured transport", NULL, G_PARAM_READWRITE)); + + GST_DEBUG_CATEGORY_INIT (a2dpsrc_debug, "a2dpsrc", 0, + "Bluetooth A2DP Source"); +} + +static void +gst_a2dp_src_init (GstA2dpSrc * a2dpsrc, GstA2dpSrcClass * klass) +{ + GstBin *bin = GST_BIN (a2dpsrc); + GstElement *depay = NULL; + GstPad *srcpad, *depay_srcpad; + + /* FIXME: We can set up the bin elements here since we only support + * SBC. When supporting more formats, we would need to only instantiate + * an avdtpsrc here, wait for it to get to READY, query its srcpad caps + * and attach the appropriate RTP depayloader. */ + + a2dpsrc->avdtpsrc = gst_element_factory_make ("avdtpsrc", NULL); + if (!a2dpsrc->avdtpsrc) { + GST_ERROR_OBJECT (a2dpsrc, "Unable to instantiate avdtpsrc"); + goto fail; + } + + depay = gst_element_factory_make ("rtpsbcdepay", NULL); + if (!depay) { + GST_ERROR_OBJECT (a2dpsrc, "Unable to instantiate rtpsbcdepay"); + goto fail; + } + + if (!gst_bin_add (bin, a2dpsrc->avdtpsrc) || !gst_bin_add (bin, depay) || + !gst_element_link (a2dpsrc->avdtpsrc, depay)) { + GST_ERROR_OBJECT (a2dpsrc, "Unable to add elements to bin"); + goto fail; + } + + depay_srcpad = gst_element_get_static_pad (depay, "src"); + srcpad = gst_ghost_pad_new ("sink", depay_srcpad); + gst_object_unref (depay_srcpad); + + if (!gst_element_add_pad (GST_ELEMENT (a2dpsrc), srcpad)) { + GST_ERROR_OBJECT (a2dpsrc, "Could not add srcpad"); + goto fail; + } + + /* We keep a copy for easy proxying of properties */ + gst_object_ref (a2dpsrc->avdtpsrc); + + return; + +fail: + if (a2dpsrc->avdtpsrc) + gst_object_unref (a2dpsrc->avdtpsrc); + if (depay) + gst_object_unref (depay); + if (srcpad) + gst_object_unref (srcpad); + + return; +} + +static void +gst_a2dp_src_finalize (GObject * object) +{ + GstA2dpSrc *a2dpsrc = GST_A2DP_SRC (object); + + gst_object_unref (a2dpsrc->avdtpsrc); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gst_a2dp_src_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstA2dpSrc *a2dpsrc = GST_A2DP_SRC (object); + + switch (prop_id) { + case PROP_TRANSPORT: + g_object_get_property (G_OBJECT (a2dpsrc->avdtpsrc), "transport", value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_a2dp_src_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstA2dpSrc *a2dpsrc = GST_A2DP_SRC (object); + + switch (prop_id) { + case PROP_TRANSPORT: + g_object_set_property (G_OBJECT (a2dpsrc->avdtpsrc), "transport", value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +gboolean +gst_a2dp_src_plugin_init (GstPlugin * plugin) +{ + return gst_element_register (plugin, "a2dpsrc", GST_RANK_NONE, + GST_TYPE_A2DP_SRC); +} diff --git a/sys/bluez/gsta2dpsrc.h b/sys/bluez/gsta2dpsrc.h new file mode 100644 index 0000000000..e6dcdd6982 --- /dev/null +++ b/sys/bluez/gsta2dpsrc.h @@ -0,0 +1,59 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Collabora Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GST_A2DP_SRC_H +#define __GST_A2DP_SRC_H + +#include + +G_BEGIN_DECLS +#define GST_TYPE_A2DP_SRC \ + (gst_a2dp_src_get_type()) +#define GST_A2DP_SRC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_A2DP_SRC, GstA2dpSrc)) +#define GST_A2DP_SRC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_A2DP_SRC, GstA2dpSrc)) +#define GST_IS_A2DP_SRC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_A2DP_SRC)) +#define GST_IS_A2DP_SRC_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_A2DP_SRC)) +typedef struct _GstA2dpSrc GstA2dpSrc; +typedef struct _GstA2dpSrcClass GstA2dpSrcClass; + +struct _GstA2dpSrcClass +{ + GstBinClass parentclass; +}; + +struct _GstA2dpSrc +{ + GstBin parent; + + GstElement *avdtpsrc; + GstPad *srcpad; +}; + +gboolean gst_a2dp_src_plugin_init (GstPlugin * plugin); + +G_END_DECLS +#endif diff --git a/sys/bluez/gstavdtputil.h b/sys/bluez/gstavdtputil.h index e75bdea333..33b7b14828 100644 --- a/sys/bluez/gstavdtputil.h +++ b/sys/bluez/gstavdtputil.h @@ -31,6 +31,7 @@ G_BEGIN_DECLS #define DEFAULT_CODEC_BUFFER_SIZE 2048 +#define TEMPLATE_MAX_BITPOOL_STR "64" struct bluetooth_data { guint link_mtu;