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
next prev parent 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