public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [Bluez-devel] patches fixing gstreamer plugins
@ 2007-09-25 14:18 thiagoss
  2007-09-25 15:51 ` thiagoss
  2007-09-26 22:10 ` Marcel Holtmann
  0 siblings, 2 replies; 4+ messages in thread
From: thiagoss @ 2007-09-25 14:18 UTC (permalink / raw)
  To: bluez-devel


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

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: 1080 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gstsbcenc.patch --]
[-- Type: text/x-patch; name="gstsbcenc.patch", Size: 7289 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 "gstsbc_util.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: 6270 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 "gstsbc_util.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: 7851 bytes --]

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	24 Sep 2007 19:07:24 -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 "gstsbc_util.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	24 Sep 2007 19:07:25 -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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-09-26 22:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-25 14:18 [Bluez-devel] patches fixing gstreamer plugins thiagoss
2007-09-25 15:51 ` thiagoss
2007-09-26 22:10 ` Marcel Holtmann
2007-09-26 22:19   ` thiagoss

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox