From 5dee78747cac71ad970b513dc229712be1348290 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 18 Oct 2007 21:46:49 +0000 Subject: Fixes for gstsbcenc. --- audio/gstsbcenc.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++------ audio/gstsbcenc.h | 5 ++ 2 files changed, 146 insertions(+), 15 deletions(-) diff --git a/audio/gstsbcenc.c b/audio/gstsbcenc.c index 812c1193..ea97563e 100644 --- a/audio/gstsbcenc.c +++ b/audio/gstsbcenc.c @@ -28,6 +28,13 @@ #include #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 +59,31 @@ static GType gst_sbc_mode_get_type(void) 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 +114,81 @@ static GstStaticPadTemplate sbc_enc_src_factory = "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 +267,23 @@ static void gst_sbc_enc_set_property(GObject *object, guint prop_id, { 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,7 +299,15 @@ static void gst_sbc_enc_get_property(GObject *object, guint prop_id, 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; @@ -224,8 +327,24 @@ static void gst_sbc_enc_class_init(GstSbcEncClass *klass) 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 +353,16 @@ static void gst_sbc_enc_class_init(GstSbcEncClass *klass) 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; } diff --git a/audio/gstsbcenc.h b/audio/gstsbcenc.h index e7daf2d3..0a95bcef 100644 --- a/audio/gstsbcenc.h +++ b/audio/gstsbcenc.h @@ -24,6 +24,8 @@ #include #include "sbc.h" +#include "ipc.h" + G_BEGIN_DECLS @@ -48,6 +50,9 @@ struct _GstSbcEnc { GstPad *srcpad; gint mode; + gint blocks; + gint allocation; + gint subbands; sbc_t sbc; }; -- cgit