various code cleanups use gst/audio/audio.h more allow setting fixed set of audio format specs so that adder can work...

Original commit message from CVS:
various code cleanups
use gst/audio/audio.h more
allow setting fixed set of audio format specs so that adder can work as a
NULL src
adder ! fakesink works, but adder ! osssink not yet, due to some caps nego
that is failing.
Help is appreciated there.
This commit is contained in:
Thomas Vander Stichele 2002-09-09 09:26:23 +00:00
parent 4d5888a1f5
commit 76866a1a71
2 changed files with 243 additions and 72 deletions

View file

@ -22,6 +22,7 @@
*/ */
#include "gstadder.h" #include "gstadder.h"
#include <gst/audio/audio.h>
#include <string.h> /* strcmp */ #include <string.h> /* strcmp */
#define GST_ADDER_BUFFER_SIZE 4096 #define GST_ADDER_BUFFER_SIZE 4096
@ -33,7 +34,7 @@ GstElementDetails adder_details = {
"N-to-1 audio adder/mixer", "N-to-1 audio adder/mixer",
VERSION, VERSION,
"Thomas <thomas@apestaart.org>", "Thomas <thomas@apestaart.org>",
"(C) 2001", "(C) 2001, 2002",
}; };
/* Adder signals and args */ /* Adder signals and args */
@ -45,6 +46,10 @@ enum {
enum { enum {
ARG_0, ARG_0,
ARG_NUM_PADS, ARG_NUM_PADS,
ARG_FORMAT,
ARG_RATE,
ARG_WIDTH,
ARG_CHANNELS
/* FILL ME */ /* FILL ME */
}; };
@ -59,19 +64,23 @@ GST_PAD_TEMPLATE_FACTORY (gst_adder_src_template_factory,
"law", GST_PROPS_INT (0), "law", GST_PROPS_INT (0),
"endianness", GST_PROPS_INT (G_BYTE_ORDER), "endianness", GST_PROPS_INT (G_BYTE_ORDER),
"signed", GST_PROPS_BOOLEAN (TRUE), "signed", GST_PROPS_BOOLEAN (TRUE),
"width", GST_PROPS_LIST (GST_PROPS_INT (8), GST_PROPS_INT (16)), "width", GST_PROPS_LIST (GST_PROPS_INT (8),
"depth", GST_PROPS_LIST (GST_PROPS_INT (8), GST_PROPS_INT (16)), GST_PROPS_INT (16)),
"rate", GST_PROPS_INT_RANGE (4000, 48000), /* FIXME */ "depth", GST_PROPS_LIST (GST_PROPS_INT (8),
GST_PROPS_INT (16)),
"rate", GST_PROPS_INT_RANGE (GST_AUDIO_MIN_RATE,
GST_AUDIO_MAX_RATE),
"channels", GST_PROPS_INT_RANGE (1, 2) "channels", GST_PROPS_INT_RANGE (1, 2)
), ),
GST_CAPS_NEW ( GST_CAPS_NEW (
"float_src", "float_src",
"audio/raw", "audio/raw",
"format", GST_PROPS_STRING("float"), "format", GST_PROPS_STRING ("float"),
"layout", GST_PROPS_STRING ("gfloat"), "layout", GST_PROPS_STRING ("gfloat"),
"intercept", GST_PROPS_FLOAT (0.0), "intercept", GST_PROPS_FLOAT (0.0),
"slope", GST_PROPS_FLOAT (1.0), "slope", GST_PROPS_FLOAT (1.0),
"rate", GST_PROPS_INT_RANGE (4000, 96000), "rate", GST_PROPS_INT_RANGE (GST_AUDIO_MIN_RATE,
GST_AUDIO_MAX_RATE),
"channels", GST_PROPS_INT_RANGE (1, 2) "channels", GST_PROPS_INT_RANGE (1, 2)
) )
); );
@ -87,54 +96,60 @@ GST_PAD_TEMPLATE_FACTORY (gst_adder_sink_template_factory,
"law", GST_PROPS_INT (0), "law", GST_PROPS_INT (0),
"endianness", GST_PROPS_INT (G_BYTE_ORDER), "endianness", GST_PROPS_INT (G_BYTE_ORDER),
"signed", GST_PROPS_BOOLEAN (TRUE), "signed", GST_PROPS_BOOLEAN (TRUE),
"width", GST_PROPS_LIST (GST_PROPS_INT (8), GST_PROPS_INT (16)), "width", GST_PROPS_LIST (GST_PROPS_INT (8),
"depth", GST_PROPS_LIST (GST_PROPS_INT (8), GST_PROPS_INT (16)), GST_PROPS_INT (16)),
"rate", GST_PROPS_INT_RANGE (4000, 48000), /* FIXME */ "depth", GST_PROPS_LIST (GST_PROPS_INT (8),
GST_PROPS_INT (16)),
"rate", GST_PROPS_INT_RANGE (GST_AUDIO_MIN_RATE,
GST_AUDIO_MAX_RATE),
"channels", GST_PROPS_INT_RANGE (1, 2) "channels", GST_PROPS_INT_RANGE (1, 2)
), ),
GST_CAPS_NEW ( GST_CAPS_NEW (
"float_sink", "float_sink",
"audio/raw", "audio/raw",
"format", GST_PROPS_STRING("float"), "format", GST_PROPS_STRING ("float"),
"layout", GST_PROPS_STRING ("gfloat"), "layout", GST_PROPS_STRING ("gfloat"),
"intercept", GST_PROPS_FLOAT (0.0), "intercept", GST_PROPS_FLOAT (0.0),
"slope", GST_PROPS_FLOAT (1.0), "slope", GST_PROPS_FLOAT (1.0),
"rate", GST_PROPS_INT_RANGE (4000, 96000), "rate", GST_PROPS_INT_RANGE (GST_AUDIO_MIN_RATE,
GST_AUDIO_MAX_RATE),
"channels", GST_PROPS_INT_RANGE (1, 2) "channels", GST_PROPS_INT_RANGE (1, 2)
) )
); );
static void gst_adder_class_init (GstAdderClass *klass); static void gst_adder_class_init (GstAdderClass *klass);
static void gst_adder_init (GstAdder *adder); static void gst_adder_init (GstAdder *adder);
static void gst_adder_get_property (GObject *object, guint prop_id, static void gst_adder_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec); GValue *value, GParamSpec *pspec);
static void gst_adder_set_property (GObject *object, guint prop_id,
const GValue *value,
GParamSpec *pspec);
static GstPad* gst_adder_request_new_pad (GstElement *element, GstPadTemplate *temp, static GstPad* gst_adder_request_new_pad (GstElement *element,
const gchar *unused); GstPadTemplate *temp,
const gchar *unused);
/* we do need a loop function */ /* we do need a loop function */
static void gst_adder_loop (GstElement *element); static void gst_adder_loop (GstElement *element);
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
/* static guint gst_adder_signals[LAST_SIGNAL] = { 0 }; */ /* static guint gst_adder_signals[LAST_SIGNAL] = { 0 }; */
GType GType
gst_adder_get_type(void) { gst_adder_get_type (void) {
static GType adder_type = 0; static GType adder_type = 0;
if (!adder_type) { if (!adder_type) {
static const GTypeInfo adder_info = { static const GTypeInfo adder_info = {
sizeof(GstAdderClass), NULL, sizeof (GstAdderClass), NULL, NULL,
NULL, (GClassInitFunc) gst_adder_class_init, NULL, NULL,
(GClassInitFunc)gst_adder_class_init, sizeof (GstAdder),
NULL,
NULL,
sizeof(GstAdder),
0, 0,
(GInstanceInitFunc)gst_adder_init, (GInstanceInitFunc) gst_adder_init,
}; };
adder_type = g_type_register_static (GST_TYPE_ELEMENT, "GstAdder", &adder_info, 0); adder_type = g_type_register_static (GST_TYPE_ELEMENT, "GstAdder",
&adder_info, 0);
} }
return adder_type; return adder_type;
} }
@ -143,6 +158,7 @@ static gboolean
gst_adder_parse_caps (GstAdder *adder, GstCaps *caps) gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
{ {
const gchar *format; const gchar *format;
GstElement *el = GST_ELEMENT (adder);
gst_caps_get_string (caps, "format", &format); gst_caps_get_string (caps, "format", &format);
@ -150,6 +166,7 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
/* the caps haven't been set yet at all, so we need to go ahead and set all /* the caps haven't been set yet at all, so we need to go ahead and set all
the relevant values. */ the relevant values. */
if (strcmp (format, "int") == 0) { if (strcmp (format, "int") == 0) {
GST_DEBUG (GST_CAT_PLUGIN_INFO, "parse_caps sets adder to format int");
adder->format = GST_ADDER_FORMAT_INT; adder->format = GST_ADDER_FORMAT_INT;
gst_caps_get_int (caps, "width", &adder->width); gst_caps_get_int (caps, "width", &adder->width);
gst_caps_get_int (caps, "depth", &adder->depth); gst_caps_get_int (caps, "depth", &adder->depth);
@ -159,6 +176,7 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
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 if (strcmp (format, "float") == 0) { } else if (strcmp (format, "float") == 0) {
GST_DEBUG (GST_CAT_PLUGIN_INFO, "parse_caps sets adder to format float");
adder->format = GST_ADDER_FORMAT_FLOAT; adder->format = GST_ADDER_FORMAT_FLOAT;
gst_caps_get_string (caps, "layout", &adder->layout); gst_caps_get_string (caps, "layout", &adder->layout);
gst_caps_get_float (caps, "intercept", &adder->intercept); gst_caps_get_float (caps, "intercept", &adder->intercept);
@ -178,12 +196,34 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
gst_caps_get_boolean (caps, "signed", &is_signed); gst_caps_get_boolean (caps, "signed", &is_signed);
gst_caps_get_int (caps, "rate", &rate); gst_caps_get_int (caps, "rate", &rate);
if ((adder->format != GST_ADDER_FORMAT_INT) || /* provide an error message if we can't connect */
(adder->width != width) || if (adder->format != GST_ADDER_FORMAT_INT) {
(adder->channels != channels) || gst_element_error (el,
(adder->is_signed != is_signed) || "can't connect a non-int pad to an int adder");
(adder->rate != rate)) { return FALSE;
return FALSE; }
if (adder->channels != channels) {
gst_element_error (el,
"can't connect %d-channel pad with %d-channel adder",
channels, adder->channels);
return FALSE;
}
if (adder->rate != rate) {
gst_element_error (el, "can't connect %d Hz pad with %d Hz adder",
rate, adder->rate);
return FALSE;
}
if (adder->width != width) {
gst_element_error (el, "can't connect %d-bit pad with %d-bit adder",
width, adder->width);
return FALSE;
}
if (adder->is_signed != is_signed) {
gst_element_error (el,
"can't connect %ssigned pad with %ssigned adder",
adder->is_signed ? "" : "un",
is_signed ? "" : "un");
return FALSE;
} }
} else if (strcmp (format, "float") == 0) { } else if (strcmp (format, "float") == 0) {
gint channels, rate; gint channels, rate;
@ -191,13 +231,25 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
gst_caps_get_int (caps, "channels", &channels); gst_caps_get_int (caps, "channels", &channels);
gst_caps_get_int (caps, "rate", &rate); gst_caps_get_int (caps, "rate", &rate);
if ((adder->format != GST_ADDER_FORMAT_FLOAT) || if (adder->format != GST_ADDER_FORMAT_FLOAT) {
(adder->channels != channels) || gst_element_error (el,
(adder->rate != rate)) { "can't connect a non-float pad to a float adder");
return FALSE; return FALSE;
}
if (adder->channels != channels) {
gst_element_error (el,
"can't connect %d-channel pad with %d-channel adder",
channels, adder->channels);
return FALSE;
}
if (adder->rate != rate) {
gst_element_error (el, "can't connect %d Hz pad with %d Hz adder",
rate, adder->rate);
return FALSE;
} }
} else { } else {
/* whoa, we don't know what's trying to connect with us ! barf ! */ /* whoa, we don't know what's trying to connect with us ! barf ! */
gst_element_error (el, "can't connect unknown type of pad to adder");
return FALSE; return FALSE;
} }
} }
@ -227,8 +279,11 @@ gst_adder_connect (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)) { if (!gst_pad_try_set_caps (p, caps)) {
GST_DEBUG (0, "caps mismatch; disconnecting and removing pad %s:%s (peer %s:%s)", GST_DEBUG (GST_CAT_PLUGIN_INFO,
GST_DEBUG_PAD_NAME (p), GST_DEBUG_PAD_NAME (GST_PAD_PEER (p))); "caps mismatch; disconnecting and removing pad %s:%s "
"(peer %s:%s)",
GST_DEBUG_PAD_NAME (p),
GST_DEBUG_PAD_NAME (GST_PAD_PEER (p)));
gst_pad_disconnect (GST_PAD (GST_PAD_PEER (p)), p); gst_pad_disconnect (GST_PAD (GST_PAD_PEER (p)), p);
remove = g_list_prepend (remove, p); remove = g_list_prepend (remove, p);
} }
@ -236,14 +291,16 @@ gst_adder_connect (GstPad *pad, GstCaps *caps)
sinkpads = g_list_next (sinkpads); sinkpads = g_list_next (sinkpads);
} }
while (remove) { while (remove) {
gst_element_remove_pad (GST_ELEMENT (adder), GST_PAD_CAST (remove->data)); gst_element_remove_pad (GST_ELEMENT (adder),
GST_PAD_CAST (remove->data));
restart: restart:
channels = adder->input_channels; channels = adder->input_channels;
while (channels) { while (channels) {
GstAdderInputChannel *channel = (GstAdderInputChannel*) channels->data; GstAdderInputChannel *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, channels); adder->input_channels = g_slist_remove_link (adder->input_channels,
channels);
adder->numsinkpads--; adder->numsinkpads--;
goto restart; goto restart;
} }
@ -266,16 +323,32 @@ gst_adder_class_init (GstAdderClass *klass)
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstElementClass *gstelement_class; GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass; gobject_class = (GObjectClass*) klass;
gstelement_class = (GstElementClass*)klass; gstelement_class = (GstElementClass*) klass;
parent_class = g_type_class_ref(GST_TYPE_ELEMENT); parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NUM_PADS, g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_PADS,
g_param_spec_int("num_pads","num_pads","num_pads", g_param_spec_int ("num_pads", "number of pads", "Number Of Pads",
G_MININT, G_MAXINT, 0, G_PARAM_READABLE)); 0, G_MAXINT, 0, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FORMAT,
g_param_spec_string ("format", "data format", "Format of Data (int/float)",
"int", G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_RATE,
g_param_spec_int ("rate", "Rate", "Sample Rate (Hz)",
GST_AUDIO_MIN_RATE, GST_AUDIO_MAX_RATE,
GST_AUDIO_DEF_RATE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_WIDTH,
g_param_spec_int ("width", "Bit Width", "Bit Width",
8, 16,
16, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CHANNELS,
g_param_spec_int ("channels", "Channels", "Number of channels",
1, G_MAXINT,
2, G_PARAM_READWRITE));
gobject_class->get_property = gst_adder_get_property; gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_adder_get_property);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_adder_set_property);
gstelement_class->request_new_pad = gst_adder_request_new_pad; gstelement_class->request_new_pad = gst_adder_request_new_pad;
} }
@ -283,13 +356,20 @@ gst_adder_class_init (GstAdderClass *klass)
static void static void
gst_adder_init (GstAdder *adder) gst_adder_init (GstAdder *adder)
{ {
adder->srcpad = gst_pad_new_from_template (gst_adder_src_template_factory (), "src"); adder->srcpad = gst_pad_new_from_template (gst_adder_src_template_factory (),
"src");
gst_element_add_pad (GST_ELEMENT (adder), adder->srcpad); gst_element_add_pad (GST_ELEMENT (adder), adder->srcpad);
gst_element_set_loop_function (GST_ELEMENT (adder), gst_adder_loop); gst_element_set_loop_function (GST_ELEMENT (adder), gst_adder_loop);
gst_pad_set_connect_function (adder->srcpad, gst_adder_connect); gst_pad_set_connect_function (adder->srcpad, gst_adder_connect);
adder->format = GST_ADDER_FORMAT_UNSET; adder->format = GST_ADDER_FORMAT_UNSET;
/* defaults */
adder->rate = GST_AUDIO_DEF_RATE;
adder->channels = 1;
adder->width = 16;
adder->depth = 16;
/* keep track of the sinkpads requested */ /* keep track of the sinkpads requested */
adder->numsinkpads = 0; adder->numsinkpads = 0;
@ -297,7 +377,8 @@ gst_adder_init (GstAdder *adder)
} }
static GstPad* static GstPad*
gst_adder_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused) gst_adder_request_new_pad (GstElement *element, GstPadTemplate *templ,
const gchar *unused)
{ {
gchar *name; gchar *name;
GstAdder *adder; GstAdder *adder;
@ -338,7 +419,8 @@ gst_adder_request_new_pad (GstElement *element, GstPadTemplate *templ, const gch
} }
static void static void
gst_adder_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) gst_adder_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{ {
GstAdder *adder; GstAdder *adder;
@ -351,12 +433,88 @@ gst_adder_get_property (GObject *object, guint prop_id, GValue *value, GParamSpe
case ARG_NUM_PADS: case ARG_NUM_PADS:
g_value_set_int (value, adder->numsinkpads); g_value_set_int (value, adder->numsinkpads);
break; break;
case ARG_FORMAT:
/* FIXME: check if this causes memleaks */
if (adder->format == GST_ADDER_FORMAT_INT)
g_value_set_string (value, g_strdup ("int"));
else if (adder->format == GST_ADDER_FORMAT_FLOAT)
g_value_set_string (value, g_strdup ("float"));
else
g_value_set_string (value, g_strdup ("unknown"));
break;
case ARG_RATE:
g_value_set_int (value, adder->rate);
break;
case ARG_WIDTH:
g_value_set_int (value, adder->depth);
break;
case ARG_CHANNELS:
g_value_set_int (value, adder->channels);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
} }
} }
static void
gst_adder_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
GstAdder *adder;
GstElementState state;
g_return_if_fail (GST_IS_ADDER (object));
adder = GST_ADDER (object);
state = gst_element_get_state (GST_ELEMENT (adder));
/* none of these properties can be set when not in NULL */
if (state != GST_STATE_NULL)
{
gst_element_error (GST_ELEMENT (adder),
"trying to set properties on adder when not in NULL.");
return;
}
switch (prop_id) {
case ARG_NUM_PADS:
g_warning ("Trying to change read-only parameter num_pads\n");
break;
case ARG_FORMAT:
if (strcmp (g_value_get_string (value), "int") == 0)
{
GST_DEBUG (GST_CAT_PLUGIN_INFO, "adder: setting format to int\n");
adder->format = GST_ADDER_FORMAT_INT;
}
else if (strcmp (g_value_get_string (value), "float") == 0)
{
GST_DEBUG (GST_CAT_PLUGIN_INFO, "adder: setting format to float\n");
adder->format = GST_ADDER_FORMAT_FLOAT;
}
else
{
g_warning ("adder: unknown format %s specified\n",
g_value_get_string (value));
adder->format = GST_ADDER_FORMAT_UNSET;
}
break;
case ARG_RATE:
adder->rate = g_value_get_int (value);
break;
case ARG_WIDTH:
adder->width = g_value_get_int (value);
adder->depth = g_value_get_int (value);
break;
case ARG_CHANNELS:
adder->channels = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/* use this loop */ /* use this loop */
static void static void
gst_adder_loop (GstElement *element) gst_adder_loop (GstElement *element)
@ -393,7 +551,8 @@ gst_adder_loop (GstElement *element)
adder = GST_ADDER (element); adder = GST_ADDER (element);
adder->bufpool = gst_pad_get_bufferpool (adder->srcpad); adder->bufpool = gst_pad_get_bufferpool (adder->srcpad);
if (adder->bufpool == NULL) { if (adder->bufpool == NULL) {
adder->bufpool = gst_buffer_pool_get_default(GST_ADDER_BUFFER_SIZE, GST_ADDER_NUM_BUFFERS); adder->bufpool = gst_buffer_pool_get_default (GST_ADDER_BUFFER_SIZE,
GST_ADDER_NUM_BUFFERS);
} }
do { do {
@ -401,7 +560,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_ERROR (0, "could not get new output buffer !\n"); GST_ERROR (GST_ELEMENT (adder), "could not get new output buffer !");
/* initialize the output data to 0 */ /* initialize the output data to 0 */
zero_out = (gint8 *) GST_BUFFER_DATA (buf_out); zero_out = (gint8 *) GST_BUFFER_DATA (buf_out);
@ -411,37 +570,42 @@ gst_adder_loop (GstElement *element)
/* get data from all of the sinks */ /* get data from all of the sinks */
inputs = adder->input_channels; inputs = adder->input_channels;
GST_DEBUG (0, "starting to cycle through channels"); GST_DEBUG (GST_CAT_PLUGIN_INFO, "starting to cycle through channels");
while (inputs) { while (inputs) {
input = (GstAdderInputChannel *) inputs->data; input = (GstAdderInputChannel *) inputs->data;
GST_DEBUG (0, "looking into channel %p", input); GST_DEBUG (GST_CAT_PLUGIN_INFO, "looking into channel %p", input);
if (!GST_PAD_IS_USABLE (input->sinkpad)) { if (!GST_PAD_IS_USABLE (input->sinkpad)) {
GST_DEBUG (0, "adder ignoring pad %s:%s", GST_DEBUG_PAD_NAME (input->sinkpad)); GST_DEBUG (GST_CAT_PLUGIN_INFO, "adder ignoring pad %s:%s",
GST_DEBUG_PAD_NAME (input->sinkpad));
inputs = inputs->next; inputs = inputs->next;
continue; continue;
} }
/* get data from the bytestream of each input channel. we need to check for /* Get data from the bytestream of each input channel.
events before passing on the data to the output buffer. */ * We need to check for events before passing on the data to
got_bytes = gst_bytestream_peek_bytes (input->bytestream, &raw_in, GST_BUFFER_SIZE (buf_out)); * the output buffer. */
got_bytes = gst_bytestream_peek_bytes (input->bytestream, &raw_in,
GST_BUFFER_SIZE (buf_out));
/* FIXME we should do something with the data if got_bytes is more than zero */ /* FIXME we should do something with the data
if (got_bytes < GST_BUFFER_SIZE(buf_out)) { * if got_bytes is more than zero */
if (got_bytes < GST_BUFFER_SIZE (buf_out)) {
/* we need to check for an event. */ /* we need to check for an event. */
gst_bytestream_get_status (input->bytestream, &waiting, &event); gst_bytestream_get_status (input->bytestream, &waiting, &event);
if (event) { if (event) {
if (GST_EVENT_TYPE(event) == GST_EVENT_EOS) { if (GST_EVENT_TYPE (event) == 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. delete the bytestream, free up the pad's finished handling data. delete the bytestream, free up the
pad, and free up the memory associated with the input channel. */ pad, and free up the memory associated with the input channel. */
GST_DEBUG (0, "got an EOS event"); GST_DEBUG (GST_CAT_PLUGIN_INFO, "got an EOS event");
gst_bytestream_destroy (input->bytestream); gst_bytestream_destroy (input->bytestream);
/* gst_object_unref (GST_OBJECT (input->sinkpad)); this causes problems */ /* gst_object_unref (GST_OBJECT (input->sinkpad));
* this causes problems */
g_free (input); g_free (input);
adder->input_channels = g_slist_delete_link (inputs, inputs); adder->input_channels = g_slist_delete_link (inputs, inputs);
@ -454,8 +618,11 @@ gst_adder_loop (GstElement *element)
/* here's where the data gets copied. this is a little nasty looking /* here's where the data gets copied. this is a little nasty looking
because it's the same code pretty much 3 times, except each time uses because it's the same code pretty much 3 times, except each time uses
different data types and clamp limits. */ different data types and clamp limits. */
GST_DEBUG (0, "copying %d bytes from channel %p to output data %p in buffer %p", GST_DEBUG (GST_CAT_PLUGIN_INFO,
GST_BUFFER_SIZE (buf_out), input, GST_BUFFER_DATA (buf_out), buf_out); "copying %d bytes from channel %p to output data %p "
"in buffer %p",
GST_BUFFER_SIZE (buf_out), input,
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 == 16) {
@ -469,7 +636,9 @@ gst_adder_loop (GstElement *element)
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], -128, 127);
} else { } else {
GST_ERROR (0, "invalid width (%d) for int format in gstadder\n", adder->width); GST_ERROR (GST_ELEMENT (adder),
"invalid width (%d) for int format in gstadder\n",
adder->width);
} }
} else if (adder->format == GST_ADDER_FORMAT_FLOAT) { } else if (adder->format == GST_ADDER_FORMAT_FLOAT) {
gfloat *in = (gfloat *) raw_in; gfloat *in = (gfloat *) raw_in;
@ -477,12 +646,14 @@ gst_adder_loop (GstElement *element)
for (i = 0; i < GST_BUFFER_SIZE (buf_out) / sizeof (gfloat); i++) for (i = 0; i < GST_BUFFER_SIZE (buf_out) / sizeof (gfloat); i++)
out[i] += in[i]; out[i] += in[i];
} else { } else {
GST_ERROR (0, "invalid audio format (%d) in gstadder\n", adder->format); GST_ERROR (GST_ELEMENT (adder),
"invalid audio format (%d) in gstadder\n",
adder->format);
} }
gst_bytestream_flush (input->bytestream, GST_BUFFER_SIZE (buf_out)); gst_bytestream_flush (input->bytestream, GST_BUFFER_SIZE (buf_out));
GST_DEBUG (0, "done copying data"); GST_DEBUG (GST_CAT_PLUGIN_INFO, "done copying data");
} }
inputs = g_slist_next (inputs); inputs = g_slist_next (inputs);
@ -497,7 +668,7 @@ gst_adder_loop (GstElement *element)
/* send it out */ /* send it out */
GST_DEBUG (0, "pushing buf_out"); GST_DEBUG (GST_CAT_PLUGIN_INFO, "pushing buf_out");
gst_pad_push (adder->srcpad, buf_out); gst_pad_push (adder->srcpad, buf_out);
/* give another element a chance to do something */ /* give another element a chance to do something */

View file

@ -74,14 +74,14 @@ struct _GstAdder {
guint rate; guint rate;
guint channels; guint channels;
/* the next five are valid only for format == GST_PLAYONDEMAND_FORMAT_INT */ /* the next five are valid only for format == GST_ADDER_FORMAT_INT */
guint width; guint width;
guint depth; guint depth;
guint endianness; guint endianness;
guint law; guint law;
gboolean is_signed; gboolean is_signed;
/* the next three are valid only for format == GST_PLAYONDEMAND_FORMAT_FLOAT */ /* the next three are valid only for format == GST_ADDER_FORMAT_FLOAT */
const gchar *layout; const gchar *layout;
gfloat slope; gfloat slope;
gfloat intercept; gfloat intercept;