From: thiagoss <thiagossantos@gmail.com>
To: bluez-devel@lists.sourceforge.net
Subject: [Bluez-devel] patches fixing gstreamer plugins
Date: Tue, 25 Sep 2007 11:18:32 -0300 [thread overview]
Message-ID: <de4879e80709250718p592208cci7a9aef68408a22fb@mail.gmail.com> (raw)
[-- 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
next reply other threads:[~2007-09-25 14:18 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-25 14:18 thiagoss [this message]
2007-09-25 15:51 ` [Bluez-devel] patches fixing gstreamer plugins thiagoss
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=de4879e80709250718p592208cci7a9aef68408a22fb@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