sbc: Fixes gstreamer caps and code cleanup.

This commit is contained in:
Luiz Augusto von Dentz 2008-01-30 14:21:43 +00:00 committed by Tim-Philipp Müller
parent ad24bafb62
commit 2a5e58f44f
4 changed files with 38 additions and 109 deletions

View file

@ -79,23 +79,11 @@ sbc_dec_chain (GstPad * pad, GstBuffer * buffer)
while (offset < size) { while (offset < size) {
GstBuffer *output; GstBuffer *output;
GstPadTemplate *template; GstPadTemplate *template;
GstCaps *caps, *temp; GstCaps *caps;
int consumed; int consumed;
caps = gst_caps_new_simple ("audio/x-raw-int",
"rate", G_TYPE_INT, dec->sbc.rate,
"channels", G_TYPE_INT, dec->sbc.channels, NULL);
template = gst_static_pad_template_get (&sbc_dec_src_factory);
temp = gst_caps_intersect (caps, gst_pad_template_get_caps (template));
gst_caps_unref (caps);
res = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, res = gst_pad_alloc_buffer_and_set_caps (dec->srcpad,
GST_BUFFER_OFFSET_NONE, codesize, temp, &output); GST_BUFFER_OFFSET_NONE, codesize, NULL, &output);
gst_caps_unref (temp);
if (res != GST_FLOW_OK) if (res != GST_FLOW_OK)
goto done; goto done;
@ -105,7 +93,24 @@ sbc_dec_chain (GstPad * pad, GstBuffer * buffer)
if (consumed <= 0) if (consumed <= 0)
break; break;
GST_BUFFER_TIMESTAMP (output) = GST_BUFFER_TIMESTAMP (buffer); /* we will reuse the same caps object */
if (dec->outcaps == NULL) {
caps = gst_caps_new_simple ("audio/x-raw-int",
"rate", G_TYPE_INT, dec->sbc.rate,
"channels", G_TYPE_INT, dec->sbc.channels, NULL);
template = gst_static_pad_template_get (&sbc_dec_src_factory);
dec->outcaps = gst_caps_intersect (caps,
gst_pad_template_get_caps (template));
gst_caps_unref (caps);
}
gst_buffer_set_caps (output, dec->outcaps);
/* FIXME get a real timestamp */
GST_BUFFER_TIMESTAMP (output) = GST_CLOCK_TIME_NONE;
res = gst_pad_push (dec->srcpad, output); res = gst_pad_push (dec->srcpad, output);
if (res != GST_FLOW_OK) if (res != GST_FLOW_OK)
@ -137,6 +142,7 @@ sbc_dec_change_state (GstElement * element, GstStateChange transition)
dec->buffer = NULL; dec->buffer = NULL;
} }
sbc_init (&dec->sbc, 0); sbc_init (&dec->sbc, 0);
dec->outcaps = NULL;
break; break;
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:
@ -146,6 +152,10 @@ sbc_dec_change_state (GstElement * element, GstStateChange transition)
dec->buffer = NULL; dec->buffer = NULL;
} }
sbc_finish (&dec->sbc); sbc_finish (&dec->sbc);
if (dec->outcaps) {
gst_caps_unref (dec->outcaps);
dec->outcaps = NULL;
}
break; break;
default: default:
@ -191,6 +201,8 @@ gst_sbc_dec_init (GstSbcDec * self, GstSbcDecClass * klass)
self->srcpad = gst_pad_new_from_static_template (&sbc_dec_src_factory, "src"); self->srcpad = gst_pad_new_from_static_template (&sbc_dec_src_factory, "src");
gst_element_add_pad (GST_ELEMENT (self), self->srcpad); gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
self->outcaps = NULL;
} }
gboolean gboolean

View file

@ -49,6 +49,9 @@ struct _GstSbcDec {
GstBuffer *buffer; GstBuffer *buffer;
/* caps for outgoing buffers */
GstCaps *outcaps;
sbc_t sbc; sbc_t sbc;
}; };

View file

@ -43,7 +43,7 @@ GST_ELEMENT_DETAILS ("Bluetooth SBC parser",
static GstStaticPadTemplate sbc_parse_sink_factory = static GstStaticPadTemplate sbc_parse_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-sbc")); GST_STATIC_CAPS ("audio/x-sbc," "parsed = (boolean) false"));
static GstStaticPadTemplate sbc_parse_src_factory = static GstStaticPadTemplate sbc_parse_src_factory =
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
@ -54,89 +54,7 @@ GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
"blocks = (int) { 4, 8, 12, 16 }, " "blocks = (int) { 4, 8, 12, 16 }, "
"subbands = (int) { 4, 8 }, " "subbands = (int) { 4, 8 }, "
"allocation = (string) { snr, loudness }," "allocation = (string) { snr, loudness },"
"bitpool = (int) [ 2, 64 ]")); "bitpool = (int) [ 2, 64 ]," "parsed = (boolean) true"));
static gboolean
sbc_parse_sink_setcaps (GstPad * pad, GstCaps * caps)
{
GstSbcParse *parse;
GstStructure *structure;
gint rate, channels;
parse = GST_SBC_PARSE (GST_PAD_PARENT (pad));
structure = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (structure, "rate", &rate))
return FALSE;
if (!gst_structure_get_int (structure, "channels", &channels))
return FALSE;
if (!(parse->rate == 0 || rate == parse->rate))
return FALSE;
if (!(parse->channels == 0 || channels == parse->channels))
return FALSE;
parse->rate = rate;
parse->channels = channels;
return gst_sbc_util_fill_sbc_params (&parse->sbc, caps);
}
static GstCaps *
sbc_parse_src_getcaps (GstPad * pad)
{
GstCaps *caps;
const GstCaps *allowed_caps;
GstStructure *structure;
GValue *value;
GstSbcParse *parse = GST_SBC_PARSE (GST_PAD_PARENT (pad));
allowed_caps = gst_pad_get_allowed_caps (pad);
if (allowed_caps == NULL)
allowed_caps = gst_pad_get_pad_template_caps (pad);
caps = gst_caps_copy (allowed_caps);
value = g_new0 (GValue, 1);
structure = gst_caps_get_structure (caps, 0);
if (parse->rate != 0)
gst_sbc_util_set_structure_int_param (structure, "rate",
parse->rate, value);
if (parse->channels != 0)
gst_sbc_util_set_structure_int_param (structure, "channels",
parse->channels, value);
g_free (value);
return caps;
}
static gboolean
sbc_parse_src_acceptcaps (GstPad * pad, GstCaps * caps)
{
GstStructure *structure;
GstSbcParse *parse;
gint rate, channels;
parse = GST_SBC_PARSE (GST_PAD_PARENT (pad));
structure = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (structure, "rate", &rate))
return FALSE;
if (!gst_structure_get_int (structure, "channels", &channels))
return FALSE;
if ((parse->rate == 0 || parse->rate == rate)
&& (parse->channels == 0 || parse->channels == channels))
return TRUE;
return FALSE;
}
static GstFlowReturn static GstFlowReturn
sbc_parse_chain (GstPad * pad, GstBuffer * buffer) sbc_parse_chain (GstPad * pad, GstBuffer * buffer)
@ -266,17 +184,10 @@ gst_sbc_parse_init (GstSbcParse * self, GstSbcParseClass * klass)
gst_pad_new_from_static_template (&sbc_parse_sink_factory, "sink"); gst_pad_new_from_static_template (&sbc_parse_sink_factory, "sink");
gst_pad_set_chain_function (self->sinkpad, gst_pad_set_chain_function (self->sinkpad,
GST_DEBUG_FUNCPTR (sbc_parse_chain)); 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); gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
self->srcpad = self->srcpad =
gst_pad_new_from_static_template (&sbc_parse_src_factory, "src"); gst_pad_new_from_static_template (&sbc_parse_src_factory, "src");
gst_pad_set_getcaps_function (self->srcpad,
GST_DEBUG_FUNCPTR (sbc_parse_src_getcaps));
gst_pad_set_acceptcaps_function (self->srcpad,
GST_DEBUG_FUNCPTR (sbc_parse_src_acceptcaps));
/* FIXME get encoding parameters on set caps */
gst_element_add_pad (GST_ELEMENT (self), self->srcpad); gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
} }

View file

@ -377,9 +377,12 @@ gst_sbc_util_caps_fixate (GstCaps * caps, gchar ** error_message)
goto error; goto error;
} else { } else {
value = gst_structure_get_value (structure, "mode"); value = gst_structure_get_value (structure, "mode");
if (GST_VALUE_HOLDS_LIST (value)) if (GST_VALUE_HOLDS_LIST (value)) {
mode = gst_sbc_get_mode_from_list (value); if (channels == 1)
mode = "mono";
else else
mode = gst_sbc_get_mode_from_list (value);
} else
mode = g_value_get_string (value); mode = g_value_get_string (value);
} }