mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
bluez: Compile fixes for avdtpsrc/a2dpsrc code against 1.x
This commit is contained in:
parent
adc9d39710
commit
a3713f7be1
3 changed files with 72 additions and 59 deletions
|
@ -33,7 +33,8 @@ enum
|
||||||
PROP_TRANSPORT
|
PROP_TRANSPORT
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_BOILERPLATE (GstA2dpSrc, gst_a2dp_src, GstBin, GST_TYPE_BIN);
|
#define parent_class gst_a2dp_src_parent_class
|
||||||
|
G_DEFINE_TYPE (GstA2dpSrc, gst_a2dp_src, GST_TYPE_BIN);
|
||||||
|
|
||||||
static void gst_a2dp_src_finalize (GObject * object);
|
static void gst_a2dp_src_finalize (GObject * object);
|
||||||
static void gst_a2dp_src_get_property (GObject * object, guint prop_id,
|
static void gst_a2dp_src_get_property (GObject * object, guint prop_id,
|
||||||
|
@ -53,25 +54,13 @@ GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
||||||
"allocation = (string) { \"snr\", \"loudness\" }, "
|
"allocation = (string) { \"snr\", \"loudness\" }, "
|
||||||
"bitpool = (int) [ 2, " TEMPLATE_MAX_BITPOOL_STR " ]"));
|
"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 <arun.raghavan@collabora.co.uk>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_a2dp_src_class_init (GstA2dpSrcClass * klass)
|
gst_a2dp_src_class_init (GstA2dpSrcClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
|
|
||||||
|
parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_a2dp_src_finalize);
|
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_a2dp_src_finalize);
|
||||||
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_a2dp_src_set_property);
|
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_a2dp_src_set_property);
|
||||||
|
@ -81,12 +70,21 @@ gst_a2dp_src_class_init (GstA2dpSrcClass * klass)
|
||||||
g_param_spec_string ("transport",
|
g_param_spec_string ("transport",
|
||||||
"Transport", "Use configured transport", NULL, G_PARAM_READWRITE));
|
"Transport", "Use configured transport", NULL, G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
gst_element_class_set_static_metadata (element_class,
|
||||||
|
"Bluetooth A2DP Source",
|
||||||
|
"Source/Audio/Network",
|
||||||
|
"Receives and depayloads audio from an A2DP device",
|
||||||
|
"Arun Raghavan <arun.raghavan@collabora.co.uk>");
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (a2dpsrc_debug, "a2dpsrc", 0,
|
GST_DEBUG_CATEGORY_INIT (a2dpsrc_debug, "a2dpsrc", 0,
|
||||||
"Bluetooth A2DP Source");
|
"Bluetooth A2DP Source");
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_static_pad_template_get (&gst_a2dp_src_template));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_a2dp_src_init (GstA2dpSrc * a2dpsrc, GstA2dpSrcClass * klass)
|
gst_a2dp_src_init (GstA2dpSrc * a2dpsrc)
|
||||||
{
|
{
|
||||||
GstBin *bin = GST_BIN (a2dpsrc);
|
GstBin *bin = GST_BIN (a2dpsrc);
|
||||||
GstElement *depay = NULL;
|
GstElement *depay = NULL;
|
||||||
|
|
|
@ -42,7 +42,8 @@ enum
|
||||||
PROP_TRANSPORT
|
PROP_TRANSPORT
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_BOILERPLATE (GstAvdtpSrc, gst_avdtp_src, GstBaseSrc, GST_TYPE_BASE_SRC);
|
#define parent_class gst_avdtp_src_parent_class
|
||||||
|
G_DEFINE_TYPE (GstAvdtpSrc, gst_avdtp_src, GST_TYPE_BASE_SRC);
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_avdtp_src_template =
|
static GstStaticPadTemplate gst_avdtp_src_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
||||||
|
@ -59,7 +60,7 @@ static void gst_avdtp_src_get_property (GObject * object, guint prop_id,
|
||||||
static void gst_avdtp_src_set_property (GObject * object, guint prop_id,
|
static void gst_avdtp_src_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec);
|
const GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static GstCaps *gst_avdtp_src_getcaps (GstPad * pad);
|
static GstCaps *gst_avdtp_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter);
|
||||||
static gboolean gst_avdtp_src_start (GstBaseSrc * bsrc);
|
static gboolean gst_avdtp_src_start (GstBaseSrc * bsrc);
|
||||||
static gboolean gst_avdtp_src_stop (GstBaseSrc * bsrc);
|
static gboolean gst_avdtp_src_stop (GstBaseSrc * bsrc);
|
||||||
static GstFlowReturn gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset,
|
static GstFlowReturn gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset,
|
||||||
|
@ -67,27 +68,15 @@ static GstFlowReturn gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset,
|
||||||
static gboolean gst_avdtp_src_unlock (GstBaseSrc * bsrc);
|
static gboolean gst_avdtp_src_unlock (GstBaseSrc * bsrc);
|
||||||
static gboolean gst_avdtp_src_unlock_stop (GstBaseSrc * bsrc);
|
static gboolean gst_avdtp_src_unlock_stop (GstBaseSrc * bsrc);
|
||||||
|
|
||||||
static void
|
|
||||||
gst_avdtp_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_avdtp_src_template));
|
|
||||||
|
|
||||||
gst_element_class_set_details_simple (element_class,
|
|
||||||
"Bluetooth AVDTP Source",
|
|
||||||
"Source/Audio/Network/RTP",
|
|
||||||
"Receives audio from an A2DP device",
|
|
||||||
"Arun Raghavan <arun.raghavan@collabora.co.uk>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_avdtp_src_class_init (GstAvdtpSrcClass * klass)
|
gst_avdtp_src_class_init (GstAvdtpSrcClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
GstBaseSrcClass *basesrc_class = GST_BASE_SRC_CLASS (klass);
|
GstBaseSrcClass *basesrc_class = GST_BASE_SRC_CLASS (klass);
|
||||||
|
|
||||||
|
parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avdtp_src_finalize);
|
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avdtp_src_finalize);
|
||||||
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avdtp_src_set_property);
|
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avdtp_src_set_property);
|
||||||
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avdtp_src_get_property);
|
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avdtp_src_get_property);
|
||||||
|
@ -97,26 +86,33 @@ gst_avdtp_src_class_init (GstAvdtpSrcClass * klass)
|
||||||
basesrc_class->create = GST_DEBUG_FUNCPTR (gst_avdtp_src_create);
|
basesrc_class->create = GST_DEBUG_FUNCPTR (gst_avdtp_src_create);
|
||||||
basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_avdtp_src_unlock);
|
basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_avdtp_src_unlock);
|
||||||
basesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_avdtp_src_unlock_stop);
|
basesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_avdtp_src_unlock_stop);
|
||||||
|
basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_avdtp_src_getcaps);
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_TRANSPORT,
|
g_object_class_install_property (gobject_class, PROP_TRANSPORT,
|
||||||
g_param_spec_string ("transport",
|
g_param_spec_string ("transport",
|
||||||
"Transport", "Use configured transport", NULL, G_PARAM_READWRITE));
|
"Transport", "Use configured transport", NULL, G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
gst_element_class_set_static_metadata (element_class,
|
||||||
|
"Bluetooth AVDTP Source",
|
||||||
|
"Source/Audio/Network/RTP",
|
||||||
|
"Receives audio from an A2DP device",
|
||||||
|
"Arun Raghavan <arun.raghavan@collabora.co.uk>");
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (avdtpsrc_debug, "avdtpsrc", 0,
|
GST_DEBUG_CATEGORY_INIT (avdtpsrc_debug, "avdtpsrc", 0,
|
||||||
"Bluetooth AVDTP Source");
|
"Bluetooth AVDTP Source");
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_static_pad_template_get (&gst_avdtp_src_template));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_avdtp_src_init (GstAvdtpSrc * avdtpsrc, GstAvdtpSrcClass * klass)
|
gst_avdtp_src_init (GstAvdtpSrc * avdtpsrc)
|
||||||
{
|
{
|
||||||
avdtpsrc->poll = gst_poll_new (TRUE);
|
avdtpsrc->poll = gst_poll_new (TRUE);
|
||||||
|
|
||||||
gst_base_src_set_format (GST_BASE_SRC (avdtpsrc), GST_FORMAT_TIME);
|
gst_base_src_set_format (GST_BASE_SRC (avdtpsrc), GST_FORMAT_TIME);
|
||||||
gst_base_src_set_live (GST_BASE_SRC (avdtpsrc), TRUE);
|
gst_base_src_set_live (GST_BASE_SRC (avdtpsrc), TRUE);
|
||||||
gst_base_src_set_do_timestamp (GST_BASE_SRC (avdtpsrc), TRUE);
|
gst_base_src_set_do_timestamp (GST_BASE_SRC (avdtpsrc), TRUE);
|
||||||
|
|
||||||
gst_pad_set_getcaps_function (GST_BASE_SRC_PAD (avdtpsrc),
|
|
||||||
GST_DEBUG_FUNCPTR (gst_avdtp_src_getcaps));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -167,10 +163,10 @@ gst_avdtp_src_set_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_avdtp_src_getcaps (GstPad * pad)
|
gst_avdtp_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
|
||||||
{
|
{
|
||||||
GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (gst_pad_get_parent_element (pad));
|
GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
|
||||||
GstCaps *ret = NULL;
|
GstCaps *caps = NULL, *ret = NULL;
|
||||||
|
|
||||||
if (avdtpsrc->dev_caps) {
|
if (avdtpsrc->dev_caps) {
|
||||||
const GValue *value;
|
const GValue *value;
|
||||||
|
@ -183,7 +179,7 @@ gst_avdtp_src_getcaps (GstPad * pad)
|
||||||
if (g_str_equal (format, "audio/x-sbc")) {
|
if (g_str_equal (format, "audio/x-sbc")) {
|
||||||
/* FIXME: we can return a fixed payload type once we
|
/* FIXME: we can return a fixed payload type once we
|
||||||
* are in PLAYING */
|
* are in PLAYING */
|
||||||
ret = gst_caps_new_simple ("application/x-rtp",
|
caps = gst_caps_new_simple ("application/x-rtp",
|
||||||
"media", G_TYPE_STRING, "audio",
|
"media", G_TYPE_STRING, "audio",
|
||||||
"payload", GST_TYPE_INT_RANGE, 96, 127,
|
"payload", GST_TYPE_INT_RANGE, 96, 127,
|
||||||
"encoding-name", G_TYPE_STRING, "SBC", NULL);
|
"encoding-name", G_TYPE_STRING, "SBC", NULL);
|
||||||
|
@ -198,9 +194,16 @@ gst_avdtp_src_getcaps (GstPad * pad)
|
||||||
}
|
}
|
||||||
rate = g_value_get_int (value);
|
rate = g_value_get_int (value);
|
||||||
|
|
||||||
gst_caps_set_simple (ret, "clock-rate", G_TYPE_INT, rate, NULL);
|
gst_caps_set_simple (caps, "clock-rate", G_TYPE_INT, rate, NULL);
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
ret = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
} else
|
||||||
|
ret = caps;
|
||||||
} else {
|
} else {
|
||||||
ret = gst_caps_ref (GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad)));
|
GST_DEBUG_OBJECT (avdtpsrc, "device not open, using template caps");
|
||||||
|
ret = GST_BASE_SRC_CLASS (parent_class)->get_caps (bsrc, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -282,22 +285,23 @@ gst_avdtp_src_stop (GstBaseSrc * bsrc)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset,
|
gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
|
||||||
guint length, GstBuffer ** outbuf)
|
GstBuffer ** outbuf)
|
||||||
{
|
{
|
||||||
GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
|
GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc);
|
||||||
GstBuffer *buf = NULL;
|
GstBuffer *buf = NULL;
|
||||||
|
GstMapInfo info;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (g_atomic_int_get (&avdtpsrc->unlocked))
|
if (g_atomic_int_get (&avdtpsrc->unlocked))
|
||||||
return GST_FLOW_WRONG_STATE;
|
return GST_FLOW_FLUSHING;
|
||||||
|
|
||||||
/* We don't operate in GST_FORMAT_BYTES, so offset is ignored */
|
/* We don't operate in GST_FORMAT_BYTES, so offset is ignored */
|
||||||
|
|
||||||
while ((ret = gst_poll_wait (avdtpsrc->poll, GST_CLOCK_TIME_NONE))) {
|
while ((ret = gst_poll_wait (avdtpsrc->poll, GST_CLOCK_TIME_NONE))) {
|
||||||
if (g_atomic_int_get (&avdtpsrc->unlocked))
|
if (g_atomic_int_get (&avdtpsrc->unlocked))
|
||||||
/* We're unlocked, time to gtfo */
|
/* We're unlocked, time to gtfo */
|
||||||
return GST_FLOW_WRONG_STATE;
|
return GST_FLOW_FLUSHING;
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
/* Something went wrong */
|
/* Something went wrong */
|
||||||
|
@ -308,8 +312,15 @@ gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = gst_buffer_new_and_alloc (length);
|
ret = GST_BASE_SRC_CLASS (parent_class)->alloc (bsrc, offset, length, outbuf);
|
||||||
ret = read (avdtpsrc->pfd.fd, GST_BUFFER_DATA (buf), length);
|
if (G_UNLIKELY (ret != GST_FLOW_OK))
|
||||||
|
goto alloc_failed;
|
||||||
|
|
||||||
|
buf = *outbuf;
|
||||||
|
|
||||||
|
gst_buffer_map (buf, &info, GST_MAP_WRITE);
|
||||||
|
|
||||||
|
ret = read (avdtpsrc->pfd.fd, info.data, length);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto read_error;
|
goto read_error;
|
||||||
|
@ -320,21 +331,25 @@ gst_avdtp_src_create (GstBaseSrc * bsrc, guint64 offset,
|
||||||
goto eof;
|
goto eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret < length)
|
||||||
|
gst_buffer_set_size (buf, ret);
|
||||||
|
|
||||||
GST_LOG_OBJECT (avdtpsrc, "Read %d bytes", ret);
|
GST_LOG_OBJECT (avdtpsrc, "Read %d bytes", ret);
|
||||||
|
|
||||||
if (ret < (gint) length) {
|
gst_buffer_unmap (buf, &info);
|
||||||
/* Create a subbuffer for as much as we've actually read */
|
*outbuf = buf;
|
||||||
*outbuf = gst_buffer_create_sub (buf, 0, ret);
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
} else
|
|
||||||
*outbuf = buf;
|
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
alloc_failed:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (bsrc, "alloc failed: %s", gst_flow_get_name (ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
read_error:
|
read_error:
|
||||||
GST_ERROR_OBJECT (avdtpsrc, "Error while reading audio data: %s",
|
GST_ERROR_OBJECT (avdtpsrc, "Error while reading audio data: %s",
|
||||||
strerror (errno));
|
strerror (errno));
|
||||||
|
|
||||||
eof:
|
eof:
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
|
|
|
@ -319,7 +319,7 @@ gst_avdtp_util_parse_sbc_raw (void *config)
|
||||||
GValue *list;
|
GValue *list;
|
||||||
gboolean mono, stereo;
|
gboolean mono, stereo;
|
||||||
|
|
||||||
structure = gst_structure_empty_new ("audio/x-sbc");
|
structure = gst_structure_new_empty ("audio/x-sbc");
|
||||||
value = g_value_init (g_new0 (GValue, 1), G_TYPE_STRING);
|
value = g_value_init (g_new0 (GValue, 1), G_TYPE_STRING);
|
||||||
list = g_value_init (g_new0 (GValue, 1), GST_TYPE_LIST);
|
list = g_value_init (g_new0 (GValue, 1), GST_TYPE_LIST);
|
||||||
|
|
||||||
|
@ -490,7 +490,7 @@ gst_avdtp_util_parse_mpeg_raw (void *config)
|
||||||
gboolean valid_layer = FALSE;
|
gboolean valid_layer = FALSE;
|
||||||
gboolean mono, stereo;
|
gboolean mono, stereo;
|
||||||
|
|
||||||
structure = gst_structure_empty_new ("audio/mpeg");
|
structure = gst_structure_new_empty ("audio/mpeg");
|
||||||
value = g_new0 (GValue, 1);
|
value = g_new0 (GValue, 1);
|
||||||
g_value_init (value, G_TYPE_INT);
|
g_value_init (value, G_TYPE_INT);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue