mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
+ alterations to the adder for changed float caps
Original commit message from CVS: + alterations to the adder for changed float caps
This commit is contained in:
parent
2ad6bd23cf
commit
e6f278e065
2 changed files with 95 additions and 92 deletions
|
@ -36,7 +36,7 @@ GstElementDetails adder_details = {
|
||||||
"Adder",
|
"Adder",
|
||||||
"Filter/Audio",
|
"Filter/Audio",
|
||||||
"LGPL",
|
"LGPL",
|
||||||
"N-to-1 audio adder/mixer",
|
"Add N audio channels together",
|
||||||
VERSION,
|
VERSION,
|
||||||
"Thomas <thomas@apestaart.org>",
|
"Thomas <thomas@apestaart.org>",
|
||||||
"(C) 2001, 2002",
|
"(C) 2001, 2002",
|
||||||
|
@ -61,7 +61,7 @@ GST_PAD_TEMPLATE_FACTORY (gst_adder_src_template_factory,
|
||||||
gst_caps_new ("int_src", "audio/x-raw-int",
|
gst_caps_new ("int_src", "audio/x-raw-int",
|
||||||
GST_AUDIO_INT_PAD_TEMPLATE_PROPS),
|
GST_AUDIO_INT_PAD_TEMPLATE_PROPS),
|
||||||
gst_caps_new ("float_src", "audio/x-raw-float",
|
gst_caps_new ("float_src", "audio/x-raw-float",
|
||||||
GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS)
|
GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS)
|
||||||
);
|
);
|
||||||
|
|
||||||
GST_PAD_TEMPLATE_FACTORY (gst_adder_sink_template_factory,
|
GST_PAD_TEMPLATE_FACTORY (gst_adder_sink_template_factory,
|
||||||
|
@ -71,7 +71,7 @@ GST_PAD_TEMPLATE_FACTORY (gst_adder_sink_template_factory,
|
||||||
gst_caps_new ("int_sink", "audio/x-raw-int",
|
gst_caps_new ("int_sink", "audio/x-raw-int",
|
||||||
GST_AUDIO_INT_PAD_TEMPLATE_PROPS),
|
GST_AUDIO_INT_PAD_TEMPLATE_PROPS),
|
||||||
gst_caps_new ("float_sink", "audio/x-raw-float",
|
gst_caps_new ("float_sink", "audio/x-raw-float",
|
||||||
GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS)
|
GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS)
|
||||||
);
|
);
|
||||||
|
|
||||||
static void gst_adder_class_init (GstAdderClass *klass);
|
static void gst_adder_class_init (GstAdderClass *klass);
|
||||||
|
@ -117,8 +117,7 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
|
||||||
mimetype = gst_caps_get_mime (caps);
|
mimetype = gst_caps_get_mime (caps);
|
||||||
|
|
||||||
if (adder->format == GST_ADDER_FORMAT_UNSET) {
|
if (adder->format == GST_ADDER_FORMAT_UNSET) {
|
||||||
/* the caps haven't been set yet at all,
|
/* the caps haven't been set yet at all, so we need to go ahead and set all
|
||||||
* so we need to go ahead and set all
|
|
||||||
the relevant values. */
|
the relevant values. */
|
||||||
if (strcmp (mimetype, "audio/x-raw-int") == 0) {
|
if (strcmp (mimetype, "audio/x-raw-int") == 0) {
|
||||||
GST_DEBUG ("parse_caps sets adder to format int");
|
GST_DEBUG ("parse_caps sets adder to format int");
|
||||||
|
@ -132,14 +131,13 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
|
||||||
} else if (strcmp (mimetype, "audio/x-raw-float") == 0) {
|
} else if (strcmp (mimetype, "audio/x-raw-float") == 0) {
|
||||||
GST_DEBUG ("parse_caps sets adder to format float");
|
GST_DEBUG ("parse_caps sets adder to format float");
|
||||||
adder->format = GST_ADDER_FORMAT_FLOAT;
|
adder->format = GST_ADDER_FORMAT_FLOAT;
|
||||||
gst_caps_get_float (caps, "intercept", &adder->intercept);
|
gst_caps_get_int (caps, "width", &adder->width);
|
||||||
gst_caps_get_float (caps, "slope", &adder->slope);
|
|
||||||
gst_caps_get_int (caps, "channels", &adder->channels);
|
gst_caps_get_int (caps, "channels", &adder->channels);
|
||||||
gst_caps_get_int (caps, "rate", &adder->rate);
|
gst_caps_get_int (caps, "rate", &adder->rate);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* otherwise, a previously-linked pad has set all the values. we should
|
/* otherwise, a previously-linked pad has set all the values. we should barf
|
||||||
barf if some of the attempted new values don't match. */
|
if some of the attempted new values don't match. */
|
||||||
if (strcmp (mimetype, "audio/x-raw-int") == 0) {
|
if (strcmp (mimetype, "audio/x-raw-int") == 0) {
|
||||||
gint width, channels, rate;
|
gint width, channels, rate;
|
||||||
gboolean is_signed;
|
gboolean is_signed;
|
||||||
|
@ -171,21 +169,20 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (adder->is_signed != is_signed) {
|
if (adder->is_signed != is_signed) {
|
||||||
gst_element_error (el,
|
gst_element_error (el, "can't link %ssigned pad with %ssigned adder",
|
||||||
"can't link %ssigned pad with %ssigned adder",
|
|
||||||
adder->is_signed ? "" : "un",
|
adder->is_signed ? "" : "un",
|
||||||
is_signed ? "" : "un");
|
is_signed ? "" : "un");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
} else if (strcmp (mimetype, "audio/x-raw-float") == 0) {
|
} else if (strcmp (mimetype, "audio/x-raw-float") == 0) {
|
||||||
gint channels, rate;
|
gint channels, rate, width;
|
||||||
|
|
||||||
gst_caps_get_int (caps, "channels", &channels);
|
gst_caps_get_int (caps, "width", &width);
|
||||||
gst_caps_get_int (caps, "rate", &rate);
|
gst_caps_get_int (caps, "channels", &channels);
|
||||||
|
gst_caps_get_int (caps, "rate", &rate);
|
||||||
|
|
||||||
if (adder->format != GST_ADDER_FORMAT_FLOAT) {
|
if (adder->format != GST_ADDER_FORMAT_FLOAT) {
|
||||||
gst_element_error (el,
|
gst_element_error (el, "can't link a non-float pad to a float adder");
|
||||||
"can't link a non-float pad to a float adder");
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (adder->channels != channels) {
|
if (adder->channels != channels) {
|
||||||
|
@ -199,6 +196,11 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
|
||||||
rate, adder->rate);
|
rate, adder->rate);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
if (adder->width != width) {
|
||||||
|
gst_element_error (el, "can't link %d bit float pad with %d bit adder",
|
||||||
|
width, adder->width);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -228,11 +230,10 @@ gst_adder_link (GstPad *pad, GstCaps *caps)
|
||||||
p = (GstPad *) sinkpads->data;
|
p = (GstPad *) sinkpads->data;
|
||||||
if (p != pad && p != adder->srcpad) {
|
if (p != pad && p != adder->srcpad) {
|
||||||
if (gst_pad_try_set_caps (p, caps) <= 0) {
|
if (gst_pad_try_set_caps (p, caps) <= 0) {
|
||||||
GST_DEBUG (
|
GST_DEBUG ("caps mismatch; unlinking and removing pad %s:%s "
|
||||||
"caps mismatch; unlinking and removing pad %s:%s "
|
|
||||||
"(peer %s:%s)",
|
"(peer %s:%s)",
|
||||||
GST_DEBUG_PAD_NAME (p),
|
GST_DEBUG_PAD_NAME (p),
|
||||||
GST_DEBUG_PAD_NAME (GST_PAD_PEER (p)));
|
GST_DEBUG_PAD_NAME (GST_PAD_PEER (p)));
|
||||||
gst_pad_unlink (GST_PAD (GST_PAD_PEER (p)), p);
|
gst_pad_unlink (GST_PAD (GST_PAD_PEER (p)), p);
|
||||||
remove = g_list_prepend (remove, p);
|
remove = g_list_prepend (remove, p);
|
||||||
}
|
}
|
||||||
|
@ -241,7 +242,7 @@ gst_adder_link (GstPad *pad, GstCaps *caps)
|
||||||
}
|
}
|
||||||
while (remove) {
|
while (remove) {
|
||||||
gst_element_remove_pad (GST_ELEMENT (adder),
|
gst_element_remove_pad (GST_ELEMENT (adder),
|
||||||
GST_PAD_CAST (remove->data));
|
GST_PAD_CAST (remove->data));
|
||||||
restart:
|
restart:
|
||||||
channels = adder->input_channels;
|
channels = adder->input_channels;
|
||||||
while (channels) {
|
while (channels) {
|
||||||
|
@ -249,8 +250,8 @@ gst_adder_link (GstPad *pad, GstCaps *caps)
|
||||||
channel = (GstAdderInputChannel*) channels->data;
|
channel = (GstAdderInputChannel*) channels->data;
|
||||||
if (channel->sinkpad == GST_PAD_CAST (remove->data)) {
|
if (channel->sinkpad == GST_PAD_CAST (remove->data)) {
|
||||||
gst_bytestream_destroy (channel->bytestream);
|
gst_bytestream_destroy (channel->bytestream);
|
||||||
adder->input_channels = g_slist_remove_link (adder->input_channels,
|
adder->input_channels =
|
||||||
channels);
|
g_slist_remove_link (adder->input_channels, channels);
|
||||||
adder->numsinkpads--;
|
adder->numsinkpads--;
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
@ -406,8 +407,7 @@ gst_adder_loop (GstElement *element)
|
||||||
buf_out = gst_buffer_new_from_pool (adder->bufpool, 0, 0);
|
buf_out = gst_buffer_new_from_pool (adder->bufpool, 0, 0);
|
||||||
|
|
||||||
if (buf_out == NULL) {
|
if (buf_out == NULL) {
|
||||||
gst_element_error (GST_ELEMENT (adder),
|
gst_element_error (GST_ELEMENT (adder), "could not get new output buffer");
|
||||||
"could not get new output buffer !\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,14 +436,12 @@ gst_adder_loop (GstElement *element)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get data from the bytestream of each input channel.
|
/* Get data from the bytestream of each input channel. We need to check for
|
||||||
* We need to check for events before passing on the data
|
events before passing on the data to the output buffer. */
|
||||||
* to the output buffer. */
|
|
||||||
got_bytes = gst_bytestream_peek_bytes (input->bytestream, &raw_in,
|
got_bytes = gst_bytestream_peek_bytes (input->bytestream, &raw_in,
|
||||||
GST_BUFFER_SIZE (buf_out));
|
GST_BUFFER_SIZE (buf_out));
|
||||||
|
|
||||||
/* FIXME we should do something with the data if
|
/* FIXME we should do something with the data if got_bytes > 0 */
|
||||||
* got_bytes is more than zero */
|
|
||||||
if (got_bytes < GST_BUFFER_SIZE(buf_out)) {
|
if (got_bytes < GST_BUFFER_SIZE(buf_out)) {
|
||||||
GstEvent *event = NULL;
|
GstEvent *event = NULL;
|
||||||
guint32 waiting;
|
guint32 waiting;
|
||||||
|
@ -455,15 +453,15 @@ gst_adder_loop (GstElement *element)
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
/* if we get an EOS event from one of our sink pads, we assume that
|
/* if we get an EOS event from one of our sink pads, we assume that
|
||||||
pad's finished handling data. just skip this pad */
|
pad's finished handling data. just skip this pad. */
|
||||||
GST_DEBUG ("got an EOS event");
|
GST_DEBUG ("got an EOS event");
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
continue;
|
continue;
|
||||||
case GST_EVENT_INTERRUPT:
|
case GST_EVENT_INTERRUPT:
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
GST_DEBUG ("got an interrupt event");
|
GST_DEBUG ("got an interrupt event");
|
||||||
/* we have to call interrupt here, the scheduler will switch out this
|
/* we have to call interrupt here, the scheduler will switch out
|
||||||
* element ASAP or returns TRUE if we need to exit the loop */
|
this element ASAP or returns TRUE if we need to exit the loop */
|
||||||
if (gst_element_interrupt (GST_ELEMENT (adder))) {
|
if (gst_element_interrupt (GST_ELEMENT (adder))) {
|
||||||
gst_buffer_unref (buf_out);
|
gst_buffer_unref (buf_out);
|
||||||
return;
|
return;
|
||||||
|
@ -473,40 +471,55 @@ gst_adder_loop (GstElement *element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* here's where the data gets copied. this is a little nasty looking
|
/* here's where the data gets copied. */
|
||||||
because it's the same code pretty much 3 times, except each time uses
|
|
||||||
different data types and clamp limits. */
|
GST_DEBUG ("copying %d bytes from channel %p to output data %p "
|
||||||
GST_DEBUG (
|
|
||||||
"copying %d bytes from channel %p to output data %p "
|
|
||||||
"in buffer %p",
|
"in buffer %p",
|
||||||
GST_BUFFER_SIZE (buf_out), input,
|
GST_BUFFER_SIZE (buf_out), input,
|
||||||
GST_BUFFER_DATA (buf_out), buf_out);
|
GST_BUFFER_DATA (buf_out), buf_out);
|
||||||
|
|
||||||
if (adder->format == GST_ADDER_FORMAT_INT) {
|
if (adder->format == GST_ADDER_FORMAT_INT) {
|
||||||
if (adder->width == 16) {
|
if (adder->width == 32) {
|
||||||
|
gint32 *in = (gint32 *) raw_in;
|
||||||
|
gint32 *out = (gint32 *) GST_BUFFER_DATA (buf_out);
|
||||||
|
for (i = 0; i < GST_BUFFER_SIZE (buf_out) / 4; i++)
|
||||||
|
out[i] = CLAMP(out[i] + in[i], 0x80000000, 0x7fffffff);
|
||||||
|
} else if (adder->width == 16) {
|
||||||
gint16 *in = (gint16 *) raw_in;
|
gint16 *in = (gint16 *) raw_in;
|
||||||
gint16 *out = (gint16 *) GST_BUFFER_DATA (buf_out);
|
gint16 *out = (gint16 *) GST_BUFFER_DATA (buf_out);
|
||||||
for (i = 0; i < GST_BUFFER_SIZE (buf_out) / 2; i++)
|
for (i = 0; i < GST_BUFFER_SIZE (buf_out) / 2; i++)
|
||||||
out[i] = CLAMP(out[i] + in[i], -32768, 32767);
|
out[i] = CLAMP(out[i] + in[i], 0x8000, 0x7fff);
|
||||||
} else if (adder->width == 8) {
|
} else if (adder->width == 8) {
|
||||||
gint8 *in = (gint8 *) raw_in;
|
gint8 *in = (gint8 *) raw_in;
|
||||||
gint8 *out = (gint8 *) GST_BUFFER_DATA (buf_out);
|
gint8 *out = (gint8 *) GST_BUFFER_DATA (buf_out);
|
||||||
for (i = 0; i < GST_BUFFER_SIZE (buf_out); i++)
|
for (i = 0; i < GST_BUFFER_SIZE (buf_out); i++)
|
||||||
out[i] = CLAMP(out[i] + in[i], -128, 127);
|
out[i] = CLAMP(out[i] + in[i], 0x80, 0x7f);
|
||||||
} else {
|
} else {
|
||||||
gst_element_error (GST_ELEMENT (adder),
|
gst_element_error (GST_ELEMENT (adder),
|
||||||
"invalid width (%u) for int format in gstadder\n",
|
"invalid width (%u) for integer audio in gstadder",
|
||||||
adder->width);
|
adder->width);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (adder->format == GST_ADDER_FORMAT_FLOAT) {
|
} else if (adder->format == GST_ADDER_FORMAT_FLOAT) {
|
||||||
gfloat *in = (gfloat *) raw_in;
|
if (adder->width == 64) {
|
||||||
gfloat *out = (gfloat *) GST_BUFFER_DATA (buf_out);
|
gdouble *in = (gdouble *) raw_in;
|
||||||
for (i = 0; i < GST_BUFFER_SIZE (buf_out) / sizeof (gfloat); i++)
|
gdouble *out = (gdouble *) GST_BUFFER_DATA (buf_out);
|
||||||
out[i] += in[i];
|
for (i = 0; i < GST_BUFFER_SIZE (buf_out) / sizeof (gdouble); i++)
|
||||||
|
out[i] = CLAMP(out[i] + in[i], -1.0, 1.0);
|
||||||
|
} else if (adder->width == 32) {
|
||||||
|
gfloat *in = (gfloat *) raw_in;
|
||||||
|
gfloat *out = (gfloat *) GST_BUFFER_DATA (buf_out);
|
||||||
|
for (i = 0; i < GST_BUFFER_SIZE (buf_out) / sizeof (gfloat); i++)
|
||||||
|
out[i] = CLAMP(out[i] + in[i], -1.0, 1.0);
|
||||||
|
} else {
|
||||||
|
gst_element_error (GST_ELEMENT (adder),
|
||||||
|
"invalid width (%u) for float audio in gstadder",
|
||||||
|
adder->width);
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
gst_element_error (GST_ELEMENT (adder),
|
gst_element_error (GST_ELEMENT (adder),
|
||||||
"invalid audio format (%d) in gstadder\n",
|
"invalid audio format (%d) in gstadder",
|
||||||
adder->format);
|
adder->format);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -519,23 +532,17 @@ gst_adder_loop (GstElement *element)
|
||||||
|
|
||||||
if (adder->format == GST_ADDER_FORMAT_UNSET) {
|
if (adder->format == GST_ADDER_FORMAT_UNSET) {
|
||||||
GstCaps *caps =
|
GstCaps *caps =
|
||||||
|
gst_caps_new ("default_adder_caps",
|
||||||
gst_caps_new ("default_adder_caps",
|
"audio/x-raw-int",
|
||||||
"audio/x-raw-int",
|
GST_AUDIO_INT_PAD_TEMPLATE_PROPS);
|
||||||
gst_props_new ("width", GST_PROPS_INT (16),
|
|
||||||
"depth", GST_PROPS_INT (16),
|
|
||||||
"rate", GST_PROPS_INT (44100),
|
|
||||||
"channels", GST_PROPS_INT (2),
|
|
||||||
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
|
|
||||||
"signed", GST_PROPS_BOOLEAN (TRUE),
|
|
||||||
NULL));
|
|
||||||
|
|
||||||
if (gst_pad_try_set_caps (adder->srcpad, caps) < 0) {
|
if (gst_pad_try_set_caps (adder->srcpad, caps) < 0) {
|
||||||
gst_element_error (GST_ELEMENT (adder),
|
gst_element_error (GST_ELEMENT (adder),
|
||||||
"Couldn't set the default caps, "
|
"Couldn't set the default caps, "
|
||||||
"use link_filtered instead");
|
"use link_filtered instead");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_adder_parse_caps (adder, caps);
|
gst_adder_parse_caps (adder, caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,6 +559,7 @@ gst_adder_loop (GstElement *element)
|
||||||
gst_pad_push (adder->srcpad, buf_out);
|
gst_pad_push (adder->srcpad, buf_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static GstElementStateReturn
|
static GstElementStateReturn
|
||||||
gst_adder_change_state (GstElement *element)
|
gst_adder_change_state (GstElement *element)
|
||||||
{
|
{
|
||||||
|
@ -589,6 +597,7 @@ gst_adder_change_state (GstElement *element)
|
||||||
return GST_STATE_SUCCESS;
|
return GST_STATE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_init (GModule *module, GstPlugin *plugin)
|
plugin_init (GModule *module, GstPlugin *plugin)
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,22 +69,16 @@ struct _GstAdder {
|
||||||
guint numsinkpads;
|
guint numsinkpads;
|
||||||
GSList *input_channels;
|
GSList *input_channels;
|
||||||
|
|
||||||
/* the next three are valid for both int and float */
|
/* the next are valid for both int and float */
|
||||||
GstAdderFormat format;
|
GstAdderFormat format;
|
||||||
guint rate;
|
guint rate;
|
||||||
guint channels;
|
guint channels;
|
||||||
|
|
||||||
/* the next five are valid only for format == GST_ADDER_FORMAT_INT */
|
|
||||||
guint width;
|
guint width;
|
||||||
guint depth;
|
|
||||||
guint endianness;
|
guint endianness;
|
||||||
guint law;
|
|
||||||
gboolean is_signed;
|
|
||||||
|
|
||||||
/* the next three are valid only for format == GST_ADDER_FORMAT_FLOAT */
|
/* the next are valid only for format == GST_ADDER_FORMAT_INT */
|
||||||
const gchar *layout;
|
guint depth;
|
||||||
gfloat slope;
|
gboolean is_signed;
|
||||||
gfloat intercept;
|
|
||||||
|
|
||||||
/* counters to keep track of timestamps */
|
/* counters to keep track of timestamps */
|
||||||
gint64 timestamp;
|
gint64 timestamp;
|
||||||
|
|
Loading…
Reference in a new issue