public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
From: thiagoss <thiagossantos@gmail.com>
To: bluez-devel@lists.sourceforge.net
Subject: Re: [Bluez-devel] patches fixing gstreamer plugins
Date: Tue, 25 Sep 2007 12:51:32 -0300	[thread overview]
Message-ID: <de4879e80709250851l571b5b65q6100ff76204d5c5a@mail.gmail.com> (raw)
In-Reply-To: <de4879e80709250718p592208cci7a9aef68408a22fb@mail.gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 1180 bytes --]

Sorry, I attached the wrong versions from the patches, I'm attaching the
correct versions now.

On 9/25/07, thiagoss <thiagossantos@gmail.com> wrote:
>
> Patches for Bluez utils, modifying the sbcenc and sbcparse gstreamer
> plugins on utils/audio
>
>
> The problem:
> The pipeline "filesrc ! audioconvert ! sbcenc ! sbcparse ! fakesink" is
> not working
>
> The reason:
> The caps negotiation from both sbcenc and sbcparse was not working
> properly, it was not resulting in a "fixed caps" (that defines one and only
> one media type)
>
> The solution:
> Implement on both elements the setcaps for the sink pads.
>
>
> The patch gstsbc_util.patch has to be applied first, it creates 2 new
> files( a gstsbcutil.c and a gstsbcutil.h) that the other 2 patches use.
> Those files implement a set of functions that both sbcenc and sbcparse use,
> most of them are still to be improved,
>
> The gstsbcenc.patch and sbcparse.patch implement the sink setcaps function
> on the plugins, this function selects the better encoding parameters from
> the possible ones, resulting in a "fixed caps".
>
> I'll be waiting any questions and modification to the patches.
>
>
> []s
>
> Thiago
>
>

[-- Attachment #1.2: Type: text/html, Size: 1531 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gstsbcenc.patch --]
[-- Type: text/x-patch; name="gstsbcenc.patch", Size: 7288 bytes --]

Index: audio/gstsbcenc.c
===================================================================
RCS file: /cvsroot/bluez/utils/audio/gstsbcenc.c,v
retrieving revision 1.4
diff -u -r1.4 gstsbcenc.c
--- audio/gstsbcenc.c	27 Aug 2007 14:10:00 -0000	1.4
+++ audio/gstsbcenc.c	24 Sep 2007 19:40:30 -0000
@@ -28,6 +28,14 @@
 #include <string.h>
 
 #include "gstsbcenc.h"
+#include "gstsbcutil.h"
+
+
+#define SBC_ENC_DEFAULT_MODE CFG_MODE_AUTO
+#define	SBC_ENC_DEFAULT_BLOCKS 16
+#define	SBC_ENC_DEFAULT_SUB_BANDS 8
+#define	SBC_ENC_DEFAULT_ALLOCATION CFG_ALLOCATION_AUTO
+
 
 GST_DEBUG_CATEGORY_STATIC(sbc_enc_debug);
 #define GST_CAT_DEFAULT sbc_enc_debug
@@ -52,9 +60,31 @@
 	return sbc_mode_type;
 }
 
+#define GST_TYPE_SBC_ALLOCATION (gst_sbc_allocation_get_type())
+
+static GType gst_sbc_allocation_get_type(void)
+{
+	static GType sbc_allocation_type = 0;
+	static GEnumValue sbc_allocations[] = {
+		{ CFG_ALLOCATION_AUTO,		"Auto",		"auto" },
+		{ CFG_ALLOCATION_LOUDNESS,	"Loudness",	"loudness" },
+		{ CFG_ALLOCATION_SNR,		"SNR",		"snr" },
+		{ -1, NULL, NULL}
+	};
+
+	if (!sbc_allocation_type)
+		sbc_allocation_type = g_enum_register_static(
+				"GstSbcAllocation", sbc_allocations);
+
+	return sbc_allocation_type;
+}
+
 enum {
 	PROP_0,
 	PROP_MODE,
+	PROP_ALLOCATION,
+	PROP_BLOCKS,
+	PROP_SUB_BANDS
 };
 
 GST_BOILERPLATE(GstSbcEnc, gst_sbc_enc, GstElement, GST_TYPE_ELEMENT);
@@ -85,27 +115,94 @@
 				"subbands = (int) { 4, 8 }, "
 				"allocation = (string) { snr, loudness }"));
 
+
+
+
+
+static GstCaps* sbc_enc_generate_srcpad_caps(GstSbcEnc *enc, GstCaps *caps)
+{
+	gint rate;
+	gint channels;
+	GstCaps* src_caps;
+	GstStructure *structure;
+
+	structure = gst_caps_get_structure(caps, 0);
+
+	if (!gst_structure_get_int (structure, "rate", &rate))
+		return NULL;
+	if (!gst_structure_get_int (structure, "channels", &channels))
+		return NULL;
+
+	enc->sbc.rate = rate;
+	enc->sbc.channels = channels;
+
+	if (enc->mode == 0)
+		enc->sbc.joint = CFG_MODE_JOINT_STEREO;
+	else
+		enc->sbc.joint = enc->mode;
+
+	enc->sbc.blocks = enc->blocks;
+	enc->sbc.subbands = enc->subbands;
+	if (enc->allocation == 0)
+		enc->sbc.allocation = CFG_ALLOCATION_LOUDNESS;
+	else
+		enc->sbc.allocation = enc->allocation;
+
+	src_caps = gst_caps_new_simple(
+			"audio/x-sbc", 
+			"rate", G_TYPE_INT, enc->sbc.rate,
+			"channels", G_TYPE_INT, enc->sbc.channels,
+			"mode", G_TYPE_STRING, 
+				gst_sbc_get_mode_string(enc->sbc.joint),
+			"subbands", G_TYPE_INT, enc->sbc.subbands,
+			"blocks", G_TYPE_INT, enc->sbc.blocks,
+			"allocation", G_TYPE_STRING, 
+				gst_sbc_get_allocation_string(
+					enc->sbc.allocation),
+			NULL);
+
+
+	return src_caps;
+
+}
+
+static gboolean sbc_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
+{
+
+	GstSbcEnc *enc;
+	GstStructure *structure;
+	GstCaps *othercaps;
+
+	enc = GST_SBC_ENC(GST_PAD_PARENT (pad));
+	structure = gst_caps_get_structure(caps, 0);
+
+	othercaps = sbc_enc_generate_srcpad_caps(enc, caps);
+	if (othercaps == NULL)
+		goto error;
+
+	gst_pad_set_caps (enc->srcpad, othercaps);
+	gst_caps_unref(othercaps);
+
+	return TRUE;
+
+error:
+{
+	GST_ERROR_OBJECT (enc, "invalid input caps");
+	return FALSE;
+}
+
+}
+
 static GstFlowReturn sbc_enc_chain(GstPad *pad, GstBuffer *buffer)
 {
 	GstSbcEnc *enc = GST_SBC_ENC(gst_pad_get_parent(pad));
 	GstFlowReturn res = GST_FLOW_OK;
-	GstStructure *structure;
-	gint rate, channels;
 	guint size, offset = 0;
 	guint8 *data;
 
 	data = GST_BUFFER_DATA(buffer);
 	size = GST_BUFFER_SIZE(buffer);
 
-	structure = gst_caps_get_structure(GST_PAD_CAPS(pad), 0);
-	gst_structure_get_int(structure, "rate", &rate);
-	gst_structure_get_int(structure, "channels", &channels);
-
-	enc->sbc.rate = rate;
-	enc->sbc.channels = channels;
-	enc->sbc.subbands = 8;
-	enc->sbc.joint = 0;
-
 	while (offset < size) {
 		GstBuffer *output;
 		GstCaps *caps;
@@ -184,11 +281,23 @@
 {
 	GstSbcEnc *enc = GST_SBC_ENC(object);
 
+	/* TODO - CAN ONLY BE CHANGED ON READY AND BELOW */
+
 	switch (prop_id) {
 	case PROP_MODE:
 		enc->mode = g_value_get_enum(value);
 		break;
-
+	case PROP_ALLOCATION:
+		enc->allocation = g_value_get_enum(value);
+		break;
+	case PROP_BLOCKS:
+		/* TODO - verify consistency */
+		enc->blocks = g_value_get_int(value);
+		break;
+	case PROP_SUB_BANDS:
+		/* TODO - verify consistency */
+		enc->subbands = g_value_get_int(value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 		break;
@@ -204,13 +313,23 @@
 	case PROP_MODE:
 		g_value_set_enum(value, enc->mode);
 		break;
-
+	case PROP_ALLOCATION:
+		g_value_set_enum(value, enc->allocation);
+		break;
+	case PROP_BLOCKS:
+		g_value_set_int(value, enc->blocks);
+		break;
+	case PROP_SUB_BANDS:
+		g_value_set_int(value, enc->subbands);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 		break;
 	}
 }
 
+
+
 static void gst_sbc_enc_class_init(GstSbcEncClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS(klass);
@@ -224,8 +343,24 @@
 	element_class->change_state = GST_DEBUG_FUNCPTR(sbc_enc_change_state);
 
 	g_object_class_install_property(object_class, PROP_MODE,
-			g_param_spec_enum("mode", "Mode", "Encoding mode",
-				GST_TYPE_SBC_MODE, 0, G_PARAM_READWRITE));
+			g_param_spec_enum("mode", "Mode",
+				"Encoding mode", GST_TYPE_SBC_MODE,
+				SBC_ENC_DEFAULT_MODE, G_PARAM_READWRITE));
+
+	g_object_class_install_property(object_class, PROP_ALLOCATION,
+			g_param_spec_enum("allocation", "Allocation", 
+				"Allocation mode", GST_TYPE_SBC_ALLOCATION,
+				SBC_ENC_DEFAULT_ALLOCATION, G_PARAM_READWRITE));
+
+	g_object_class_install_property(object_class, PROP_BLOCKS,
+			g_param_spec_int("blocks", "Blocks",
+				"Blocks", 0, G_MAXINT,
+				SBC_ENC_DEFAULT_BLOCKS,	G_PARAM_READWRITE));
+
+	g_object_class_install_property(object_class, PROP_SUB_BANDS,
+			g_param_spec_int("subbands", "Sub Bands",
+				"Sub Bands", 0, G_MAXINT,
+				SBC_ENC_DEFAULT_SUB_BANDS, G_PARAM_READWRITE));
 
 	GST_DEBUG_CATEGORY_INIT(sbc_enc_debug, "sbcenc", 0,
 						"SBC encoding element");
@@ -234,9 +369,17 @@
 static void gst_sbc_enc_init(GstSbcEnc *self, GstSbcEncClass *klass)
 {
 	self->sinkpad = gst_pad_new_from_static_template(&sbc_enc_sink_factory, "sink");
+	gst_pad_set_setcaps_function (self->sinkpad, 
+			GST_DEBUG_FUNCPTR (sbc_enc_sink_setcaps));
 	gst_element_add_pad(GST_ELEMENT(self), self->sinkpad);
 
 	self->srcpad = gst_pad_new_from_static_template(&sbc_enc_src_factory, "src");
 	gst_pad_set_chain_function(self->sinkpad, GST_DEBUG_FUNCPTR(sbc_enc_chain));
 	gst_element_add_pad(GST_ELEMENT(self), self->srcpad);
+
+	self->subbands = SBC_ENC_DEFAULT_SUB_BANDS;
+	self->blocks = SBC_ENC_DEFAULT_BLOCKS;
+	self->mode = SBC_ENC_DEFAULT_MODE;
+	self->allocation = SBC_ENC_DEFAULT_ALLOCATION;
+
 }
Index: audio/gstsbcenc.h
===================================================================
RCS file: /cvsroot/bluez/utils/audio/gstsbcenc.h,v
retrieving revision 1.3
diff -u -r1.3 gstsbcenc.h
--- audio/gstsbcenc.h	26 Aug 2007 13:12:47 -0000	1.3
+++ audio/gstsbcenc.h	24 Sep 2007 19:40:32 -0000
@@ -24,6 +24,8 @@
 #include <gst/gst.h>
 
 #include "sbc.h"
+#include "ipc.h"
+
 
 G_BEGIN_DECLS
 
@@ -48,6 +50,9 @@
 	GstPad *srcpad;
 
 	gint mode;
+	gint blocks;
+	gint allocation;
+	gint subbands;
 
 	sbc_t sbc;
 };

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: gstsbcparse.patch --]
[-- Type: text/x-patch; name="gstsbcparse.patch", Size: 6269 bytes --]

Index: audio/gstsbcparse.c
===================================================================
RCS file: /cvsroot/bluez/utils/audio/gstsbcparse.c,v
retrieving revision 1.1
diff -u -r1.1 gstsbcparse.c
--- audio/gstsbcparse.c	26 Aug 2007 13:59:05 -0000	1.1
+++ audio/gstsbcparse.c	24 Sep 2007 19:22:59 -0000
@@ -28,6 +28,7 @@
 #include <string.h>
 
 #include "gstsbcparse.h"
+#include "gstsbcutil.h"
 
 GST_DEBUG_CATEGORY_STATIC(sbc_parse_debug);
 #define GST_CAT_DEFAULT sbc_parse_debug
@@ -54,6 +55,173 @@
 				"subbands = (int) { 4, 8 }, "
 				"allocation = (string) { snr, loudness }"));
 
+/*
+	Creates a fixed caps from the caps given.
+
+*/
+static GstCaps* sbc_parse_select_caps(GstSbcParse *parse, GstCaps *caps)
+{
+
+	GstCaps *result;
+	GstStructure *structure;
+	const GValue *value;
+	gboolean error = FALSE;
+	gint temp, rate, channels, blocks, subbands;
+	const gchar* allocation = NULL;
+	const gchar* mode = NULL;
+	const gchar* error_message = NULL;
+
+	structure = gst_caps_get_structure(caps, 0);
+
+	/* rate */
+	if (!gst_structure_has_field(structure, "rate")) {
+		error = TRUE;
+		error_message = "no rate.";
+		goto error;
+	} else {
+		value = gst_structure_get_value(structure, "rate");
+		if (GST_VALUE_HOLDS_LIST(value)) {
+			temp = gst_sbc_select_rate_from_list(value);
+		} else if (GST_VALUE_HOLDS_INT_RANGE(value)) {
+			temp = gst_sbc_select_rate_from_range(value);
+		} else {
+			temp = g_value_get_int(value);
+		}
+		rate = temp;
+	}
+
+	/* channels */
+	if (!gst_structure_has_field(structure, "channels")) {
+		error = TRUE;
+		error_message = "no channels.";
+		goto error;
+	} else {
+		value = gst_structure_get_value(structure, "channels");
+		if (GST_VALUE_HOLDS_LIST(value)) {
+			temp = gst_sbc_select_channels_from_list(value);
+		} else if (GST_VALUE_HOLDS_INT_RANGE(value)) {
+			temp = gst_sbc_select_channels_from_range(value);
+		} else {
+			temp = g_value_get_int(value);
+		}
+		channels = temp;
+	}
+
+	/* blocks */
+	if (!gst_structure_has_field(structure, "blocks")) {
+		error = TRUE;
+		error_message = "no blocks.";
+		goto error;
+	} else {
+		value = gst_structure_get_value(structure, "blocks");
+		if (GST_VALUE_HOLDS_LIST(value)) {
+			temp = gst_sbc_select_blocks_from_list(value);
+		} else if (GST_VALUE_HOLDS_INT_RANGE(value)) {
+			temp = gst_sbc_select_blocks_from_range(value);
+		} else {
+			temp = g_value_get_int(value);
+		}
+		blocks = temp;
+	}
+
+	/* subbands */
+	if (!gst_structure_has_field(structure, "subbands")) {
+		error = TRUE;
+		error_message = "no subbands.";
+		goto error;
+	} else {
+		value = gst_structure_get_value(structure, "subbands");
+		if (GST_VALUE_HOLDS_LIST(value)) {
+			temp = gst_sbc_select_subbands_from_list(value);
+		} else if (GST_VALUE_HOLDS_INT_RANGE(value)) {
+			temp = gst_sbc_select_subbands_from_range(value);
+		} else {
+			temp = g_value_get_int(value);
+		}
+		subbands = temp;
+	}
+
+	/* allocation */
+	if (!gst_structure_has_field(structure, "allocation")) {
+		error = TRUE;
+		error_message = "no allocation.";
+		goto error;
+	} else {
+		value = gst_structure_get_value(structure, "allocation");
+		if (GST_VALUE_HOLDS_LIST(value)) {
+			allocation = gst_sbc_get_allocation_from_list(value);
+		} else {
+			allocation = g_value_get_string(value);
+		}
+	}
+
+
+	/* mode */
+	if (!gst_structure_has_field(structure, "mode")) {
+		error = TRUE;
+		error_message = "no mode.";
+		goto error;
+	} else {
+		value = gst_structure_get_value(structure, "mode");
+		if (GST_VALUE_HOLDS_LIST(value)) {
+			mode = gst_sbc_get_mode_from_list(value);
+		} else {
+			mode = g_value_get_string(value);
+		}
+	}
+
+error:
+	if (error) {
+		GST_ERROR_OBJECT (parse, "Invalid input caps: %s",
+				error_message);
+		return NULL;
+	}
+
+
+	result = gst_caps_new_simple("audio/x-sbc",
+					"rate", G_TYPE_INT, rate,
+					"channels", G_TYPE_INT, channels,
+					"mode", G_TYPE_STRING, mode,
+					"blocks", G_TYPE_INT, blocks,
+					"subbands", G_TYPE_INT, subbands,
+					"allocation", G_TYPE_STRING, allocation,
+					NULL
+			);
+	parse->sbc.rate = rate;
+	parse->sbc.channels = channels;
+	parse->sbc.blocks = blocks;
+	parse->sbc.subbands = subbands;
+	parse->sbc.joint = gst_sbc_get_mode_int(mode);
+	parse->sbc.allocation = gst_sbc_get_allocation_mode_int(allocation);
+
+	return result;
+}
+
+static gboolean sbc_parse_sink_setcaps(GstPad * pad, GstCaps * caps)
+{
+	GstSbcParse *parse;
+	GstCaps *inter, *other, *srccaps;
+
+	parse = GST_SBC_PARSE(GST_PAD_PARENT(pad));
+
+	other = gst_pad_peer_get_caps(parse->srcpad);
+	if (other == NULL)
+		other = gst_caps_new_any();
+
+	inter = gst_caps_intersect(caps, other);
+	srccaps = sbc_parse_select_caps(parse, inter);
+	if (srccaps == NULL)
+		return FALSE;
+
+	gst_pad_set_caps(parse->srcpad, srccaps);
+
+	gst_caps_unref(inter);
+	gst_caps_unref(other);
+	gst_caps_unref(srccaps);
+
+	return TRUE;
+}
+
 static GstFlowReturn sbc_parse_chain(GstPad *pad, GstBuffer *buffer)
 {
 	GstSbcParse *parse = GST_SBC_PARSE(gst_pad_get_parent(pad));
@@ -78,31 +246,20 @@
 
 	while (offset < size) {
 		GstBuffer *output;
-		GstPadTemplate *template;
-		GstCaps *caps, *temp;
+		GstCaps *temp;
 		int consumed;
 
 		consumed = sbc_parse(&parse->sbc, data + offset, size - offset);
 		if (consumed <= 0)
 			break;
 
-		caps = gst_caps_new_simple("audio/x-sbc",
-				"rate", G_TYPE_INT, parse->sbc.rate,
-				"channels", G_TYPE_INT, parse->sbc.channels,
-				NULL);
-
-		template = gst_static_pad_template_get(&sbc_parse_src_factory);
-
-		temp = gst_caps_intersect(caps,
-					gst_pad_template_get_caps(template));
 
-		gst_caps_unref(caps);
+		temp = GST_PAD_CAPS(parse->srcpad);
 
 		res = gst_pad_alloc_buffer_and_set_caps(parse->srcpad,
 						GST_BUFFER_OFFSET_NONE,
 						consumed, temp, &output);
 
-		gst_caps_unref(temp);
 
 		if (res != GST_FLOW_OK)
 			goto done;
@@ -187,6 +344,8 @@
 {
 	self->sinkpad = gst_pad_new_from_static_template(&sbc_parse_sink_factory, "sink");
 	gst_pad_set_chain_function(self->sinkpad, GST_DEBUG_FUNCPTR(sbc_parse_chain));
+	gst_pad_set_setcaps_function (self->sinkpad, 
+		GST_DEBUG_FUNCPTR (sbc_parse_sink_setcaps));
 	gst_element_add_pad(GST_ELEMENT(self), self->sinkpad);
 
 	self->srcpad = gst_pad_new_from_static_template(&sbc_parse_src_factory, "src");

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: gstsbcutil.patch --]
[-- Type: text/x-patch; name="gstsbcutil.patch", Size: 8588 bytes --]

Index: audio/Makefile.am
===================================================================
RCS file: /cvsroot/bluez/utils/audio/Makefile.am,v
retrieving revision 1.37
diff -u -r1.37 Makefile.am
--- audio/Makefile.am	29 Aug 2007 11:30:47 -0000	1.37
+++ audio/Makefile.am	25 Sep 2007 15:39:35 -0000
@@ -43,7 +43,8 @@
 				gstsbcenc.h gstsbcenc.c \
 				gstsbcdec.h gstsbcdec.c \
 				gstsbcparse.h gstsbcparse.c \
-				gsta2dpsink.h gsta2dpsink.c
+				gsta2dpsink.h gsta2dpsink.c \
+				gstsbcutil.h gstsbcutil.c
 libgstbluetooth_la_LDFLAGS = -module -avoid-version -export-symbols-regex gst_plugin_desc
 libgstbluetooth_la_LIBADD = @SBC_LIBS@ @GSTREAMER_LIBS@ -lgstaudio-0.10
 libgstbluetooth_la_CFLAGS = @GSTREAMER_CFLAGS@ @SBC_CFLAGS@
Index: audio/gstsbcutil.c
===================================================================
RCS file: audio/gstsbcutil.c
diff -N audio/gstsbcutil.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ audio/gstsbcutil.c	25 Sep 2007 15:39:35 -0000
@@ -0,0 +1,197 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  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
+ *
+ */
+
+
+/* common functions for gstreamer sbc related plugins */
+
+
+#include "gstsbcutil.h"
+#include "ipc.h"
+
+/*
+ * Selects one rate from a list of possible rates
+ * TODO - use a better approach to this (it is selecting the last element)
+ */
+gint gst_sbc_select_rate_from_list(const GValue *value)
+{
+	guint size = gst_value_list_get_size(value);
+	return g_value_get_int(gst_value_list_get_value(value, size-1));
+}
+
+/*
+ * Selects one rate from a range of possible rates
+ * TODO - use a better approach to this (it is selecting the maximum value)
+ */
+gint gst_sbc_select_rate_from_range(const GValue *value)
+{
+	return gst_value_get_int_range_max(value);
+}
+
+
+
+/*
+ * Selects one number of channels from a list of possible numbers
+ * TODO - use a better approach to this (it is selecting the last element)
+ */
+gint gst_sbc_select_channels_from_list(const GValue *value)
+{
+	guint size = gst_value_list_get_size(value);
+	return g_value_get_int(gst_value_list_get_value(value, size-1));
+}
+
+/*
+ * Selects one number of channels option from a range of possible numbers
+ * TODO - use a better approach to this (it is selecting the maximum value)
+ */
+gint gst_sbc_select_channels_from_range(const GValue *value)
+{
+	return gst_value_get_int_range_max(value);
+}
+
+/*
+ * Selects one number of blocks from a list of possible blocks
+ * TODO - use a better approach to this (it is selecting the last element)
+ */
+gint gst_sbc_select_blocks_from_list(const GValue *value)
+{
+	guint size = gst_value_list_get_size(value);
+	return g_value_get_int(gst_value_list_get_value(value, size-1));
+}
+
+/*
+ * Selects one blocks option from a range of possible blocks
+ * TODO - use a better approach to this (it is selecting the maximum value)
+ */
+gint gst_sbc_select_blocks_from_range(const GValue *value)
+{
+	return gst_value_get_int_range_max(value);
+}
+
+
+/*
+ * Selects one number of subbands from a list
+ * TODO - use a better approach to this (it is selecting the last element)
+ */
+gint gst_sbc_select_subbands_from_list(const GValue *value)
+{
+	guint size = gst_value_list_get_size(value);
+	return g_value_get_int(gst_value_list_get_value(value, size-1));
+}
+
+/*
+ * Selects one subbands option from a range
+ * TODO - use a better approach to this (it is selecting the maximum value)
+ */
+gint gst_sbc_select_subbands_from_range(const GValue *value)
+{
+	return gst_value_get_int_range_max(value);
+}
+
+/*
+ * Selects one allocation mode from the ones on the list
+ * TODO - use a better approach
+ */
+const gchar* gst_sbc_get_allocation_from_list(const GValue *value)
+{
+	guint size = gst_value_list_get_size(value);
+	return g_value_get_string(gst_value_list_get_value(value, size-1));
+}
+
+
+/*
+ * Selects one mode from the ones on the list
+ * TODO - use a better aproach
+ */
+const gchar* gst_sbc_get_mode_from_list(const GValue *value)
+{
+	guint size = gst_value_list_get_size(value);
+	return g_value_get_string(gst_value_list_get_value(value, size-1));
+}
+
+gint gst_sbc_get_allocation_mode_int(const gchar* allocation)
+{
+	if (g_ascii_strcasecmp(allocation, "loudness") == 0) {
+		return CFG_ALLOCATION_LOUDNESS;
+	} else if (g_ascii_strcasecmp(allocation, "snr") == 0) {
+		return CFG_ALLOCATION_SNR;
+	} else if (g_ascii_strcasecmp(allocation, "auto") == 0) {
+		return CFG_ALLOCATION_AUTO;
+	} else {
+		return -1;
+	}	
+}
+
+
+
+gint gst_sbc_get_mode_int(const gchar* mode)
+{
+	if (g_ascii_strcasecmp(mode, "joint") == 0) {
+		return CFG_MODE_JOINT_STEREO;
+	} else if (g_ascii_strcasecmp(mode, "stereo") == 0) {
+		return CFG_MODE_STEREO;
+	} else if (g_ascii_strcasecmp(mode, "dual") == 0) {
+		return CFG_MODE_DUAL_CHANNEL;
+	} else if (g_ascii_strcasecmp(mode, "mono") == 0) {
+		return CFG_MODE_MONO;
+	} else if (g_ascii_strcasecmp(mode, "auto") == 0) {
+		return CFG_MODE_AUTO;
+	} else {
+		return -1;
+	}
+}
+
+const gchar* gst_sbc_get_mode_string(int joint)
+{
+	switch (joint) {
+		case CFG_MODE_MONO:
+			return "mono";
+		case CFG_MODE_DUAL_CHANNEL:
+			return "dual";
+		case CFG_MODE_STEREO:
+			return "stereo";
+		case CFG_MODE_JOINT_STEREO:
+			return "joint";
+		case CFG_MODE_AUTO:
+			return NULL; /* TODO what should be selected here? */
+		default:
+			return NULL;
+	}
+}
+
+const gchar* gst_sbc_get_allocation_string(int alloc)
+{
+	switch (alloc) {
+		case CFG_ALLOCATION_LOUDNESS:
+			return "loudness";
+		case CFG_ALLOCATION_SNR:
+			return "snr";
+		case CFG_ALLOCATION_AUTO:
+			return NULL; /* TODO what should be selected here? */
+		default:
+			return NULL;
+	}
+
+}
+
+
+
Index: audio/gstsbcutil.h
===================================================================
RCS file: audio/gstsbcutil.h
diff -N audio/gstsbcutil.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ audio/gstsbcutil.h	25 Sep 2007 15:39:35 -0000
@@ -0,0 +1,55 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  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
+ *
+ */
+
+
+/* common functions for gstreamer sbc related plugins */
+
+#include <gst/gst.h>
+
+
+
+gint gst_sbc_select_rate_from_list(const GValue *value);
+gint gst_sbc_select_rate_from_range(const GValue *value);
+
+gint gst_sbc_select_channels_from_list(const GValue *value);
+gint gst_sbc_select_channels_from_range(const GValue *value);
+
+gint gst_sbc_select_blocks_from_list(const GValue *value);
+gint gst_sbc_select_blocks_from_range(const GValue *value);
+
+gint gst_sbc_select_subbands_from_list(const GValue *value);
+gint gst_sbc_select_subbands_from_range(const GValue *value);
+
+const gchar* gst_sbc_get_allocation_from_list(const GValue *value);
+gint gst_sbc_get_allocation_mode_int(const gchar* allocation);
+const gchar* gst_sbc_get_allocation_string(int alloc);
+
+const gchar* gst_sbc_get_mode_from_list(const GValue *value);
+gint gst_sbc_get_mode_int(const gchar* mode);
+const gchar* gst_sbc_get_mode_string(int joint);
+
+
+
+
+
+

[-- Attachment #5: Type: text/plain, Size: 228 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

[-- Attachment #6: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

  reply	other threads:[~2007-09-25 15:51 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-25 14:18 [Bluez-devel] patches fixing gstreamer plugins thiagoss
2007-09-25 15:51 ` thiagoss [this message]
2007-09-26 22:10 ` Marcel Holtmann
2007-09-26 22:19   ` thiagoss

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=de4879e80709250851l571b5b65q6100ff76204d5c5a@mail.gmail.com \
    --to=thiagossantos@gmail.com \
    --cc=bluez-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox