mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 05:59:10 +00:00
ladspa: comment signalprocessor class more and do minor code cleanups
This commit is contained in:
parent
6b2c55e254
commit
ebefc41614
2 changed files with 49 additions and 52 deletions
|
@ -21,6 +21,21 @@
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SECTION:gstsignalprocessor
|
||||||
|
*
|
||||||
|
* This baseclass allows to write elements that need data on all pads before
|
||||||
|
* their processing function can run.
|
||||||
|
*
|
||||||
|
* In push mode (gst_signal_processor_chain) it operates as follows:
|
||||||
|
* 1. store each received buffer on the pad and decrement pending_in
|
||||||
|
* 2. when pending_in==0, process as much as we can and push outputs
|
||||||
|
*
|
||||||
|
* In pull mode (gst_signal_processor_getrange) is operates as follows:
|
||||||
|
* 1. if there is an output ready, deliver
|
||||||
|
* 2. otherwise pull from each sink-pad, process requested frames and deliver
|
||||||
|
* the buffer
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -71,26 +86,33 @@ gst_signal_processor_pad_template_get_type (void)
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: better allow the caller to pass on the template, right now this can
|
/*
|
||||||
* only create mono pads */
|
* gst_signal_processor_class_add_pad_template:
|
||||||
|
* @klass: element class
|
||||||
|
* @name: pad name
|
||||||
|
* @direction: pad direction (src/sink)
|
||||||
|
* @index: index for the pad per direction (starting from 0)
|
||||||
|
*
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
gst_signal_processor_class_add_pad_template (GstSignalProcessorClass * klass,
|
gst_signal_processor_class_add_pad_template (GstSignalProcessorClass * klass,
|
||||||
const gchar * name, GstPadDirection direction, guint index)
|
const gchar * name, GstPadDirection direction, guint index)
|
||||||
{
|
{
|
||||||
GstPadTemplate *new;
|
GstPadTemplate *new;
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_SIGNAL_PROCESSOR_CLASS (klass));
|
g_return_if_fail (GST_IS_SIGNAL_PROCESSOR_CLASS (klass));
|
||||||
g_return_if_fail (name != NULL);
|
g_return_if_fail (name != NULL);
|
||||||
g_return_if_fail (direction == GST_PAD_SRC || direction == GST_PAD_SINK);
|
g_return_if_fail (direction == GST_PAD_SRC || direction == GST_PAD_SINK);
|
||||||
|
|
||||||
new = g_object_new (gst_signal_processor_pad_template_get_type (),
|
/* FIXME: would be nice to have the template as a parameter, right now this can
|
||||||
"name", name, NULL);
|
* only create mono pads */
|
||||||
|
caps = gst_caps_copy (gst_static_caps_get (&template_caps));
|
||||||
|
|
||||||
|
new = g_object_new (gst_signal_processor_pad_template_get_type (),
|
||||||
|
"name", name, "name-template", name,
|
||||||
|
"direction", direction, "presence", GST_PAD_ALWAYS, "caps", caps, NULL);
|
||||||
|
|
||||||
GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = g_strdup (name);
|
|
||||||
GST_PAD_TEMPLATE_DIRECTION (new) = direction;
|
|
||||||
GST_PAD_TEMPLATE_PRESENCE (new) = GST_PAD_ALWAYS;
|
|
||||||
GST_PAD_TEMPLATE_CAPS (new) = gst_caps_copy (gst_static_caps_get
|
|
||||||
(&template_caps));
|
|
||||||
GST_SIGNAL_PROCESSOR_PAD_TEMPLATE (new)->index = index;
|
GST_SIGNAL_PROCESSOR_PAD_TEMPLATE (new)->index = index;
|
||||||
|
|
||||||
gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), new);
|
gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), new);
|
||||||
|
@ -110,11 +132,12 @@ struct _GstSignalProcessorPad
|
||||||
|
|
||||||
GstBuffer *pen;
|
GstBuffer *pen;
|
||||||
|
|
||||||
|
/* index for the pad per direction (starting from 0) */
|
||||||
guint index;
|
guint index;
|
||||||
|
|
||||||
/* these are only used for sink pads */
|
/* these are only used for sink pads */
|
||||||
guint samples_avail;
|
guint samples_avail; /* available mono sample frames */
|
||||||
gfloat *data;
|
gfloat *data; /* data pointer to read from / write to */
|
||||||
};
|
};
|
||||||
|
|
||||||
static GType
|
static GType
|
||||||
|
@ -140,10 +163,6 @@ GST_BOILERPLATE (GstSignalProcessor, gst_signal_processor, GstElement,
|
||||||
|
|
||||||
|
|
||||||
static void gst_signal_processor_finalize (GObject * object);
|
static void gst_signal_processor_finalize (GObject * object);
|
||||||
static void gst_signal_processor_set_property (GObject * object, guint prop_id,
|
|
||||||
const GValue * value, GParamSpec * pspec);
|
|
||||||
static void gst_signal_processor_get_property (GObject * object, guint prop_id,
|
|
||||||
GValue * value, GParamSpec * pspec);
|
|
||||||
static gboolean gst_signal_processor_src_activate_pull (GstPad * pad,
|
static gboolean gst_signal_processor_src_activate_pull (GstPad * pad,
|
||||||
gboolean active);
|
gboolean active);
|
||||||
static gboolean gst_signal_processor_sink_activate_push (GstPad * pad,
|
static gboolean gst_signal_processor_sink_activate_push (GstPad * pad,
|
||||||
|
@ -176,10 +195,6 @@ gst_signal_processor_class_init (GstSignalProcessorClass * klass)
|
||||||
gstelement_class = GST_ELEMENT_CLASS (klass);
|
gstelement_class = GST_ELEMENT_CLASS (klass);
|
||||||
|
|
||||||
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_signal_processor_finalize);
|
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_signal_processor_finalize);
|
||||||
gobject_class->set_property =
|
|
||||||
GST_DEBUG_FUNCPTR (gst_signal_processor_set_property);
|
|
||||||
gobject_class->get_property =
|
|
||||||
GST_DEBUG_FUNCPTR (gst_signal_processor_get_property);
|
|
||||||
|
|
||||||
gstelement_class->change_state =
|
gstelement_class->change_state =
|
||||||
GST_DEBUG_FUNCPTR (gst_signal_processor_change_state);
|
GST_DEBUG_FUNCPTR (gst_signal_processor_change_state);
|
||||||
|
@ -345,7 +360,7 @@ gst_signal_processor_stop (GstSignalProcessor * self)
|
||||||
klass->stop (self);
|
klass->stop (self);
|
||||||
|
|
||||||
for (sinks = elem->sinkpads; sinks; sinks = sinks->next)
|
for (sinks = elem->sinkpads; sinks; sinks = sinks->next)
|
||||||
/* force set_caps when going to RUNNING, see note in set_caps */
|
/* force set_caps when going to RUNNING, see note in _setcaps () */
|
||||||
gst_pad_set_caps (GST_PAD (sinks->data), NULL);
|
gst_pad_set_caps (GST_PAD (sinks->data), NULL);
|
||||||
|
|
||||||
/* should also flush our buffers perhaps? */
|
/* should also flush our buffers perhaps? */
|
||||||
|
@ -449,7 +464,7 @@ gst_signal_processor_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
gst_signal_processor_cleanup (self);
|
gst_signal_processor_cleanup (self);
|
||||||
|
|
||||||
if (!gst_signal_processor_setup (self, sample_rate))
|
if (!gst_signal_processor_setup (self, sample_rate))
|
||||||
goto start_failed;
|
goto start_or_setup_failed;
|
||||||
|
|
||||||
self->sample_rate = sample_rate;
|
self->sample_rate = sample_rate;
|
||||||
gst_caps_replace (&self->caps, caps);
|
gst_caps_replace (&self->caps, caps);
|
||||||
|
@ -464,16 +479,16 @@ gst_signal_processor_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
when we leave that the processor is RUNNING. */
|
when we leave that the processor is RUNNING. */
|
||||||
if (!GST_SIGNAL_PROCESSOR_IS_INITIALIZED (self)
|
if (!GST_SIGNAL_PROCESSOR_IS_INITIALIZED (self)
|
||||||
&& !gst_signal_processor_setup (self, self->sample_rate))
|
&& !gst_signal_processor_setup (self, self->sample_rate))
|
||||||
goto start_failed;
|
goto start_or_setup_failed;
|
||||||
if (!GST_SIGNAL_PROCESSOR_IS_RUNNING (self)
|
if (!GST_SIGNAL_PROCESSOR_IS_RUNNING (self)
|
||||||
&& !gst_signal_processor_start (self))
|
&& !gst_signal_processor_start (self))
|
||||||
goto start_failed;
|
goto start_or_setup_failed;
|
||||||
|
|
||||||
gst_object_unref (self);
|
gst_object_unref (self);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
start_failed:
|
start_or_setup_failed:
|
||||||
{
|
{
|
||||||
gst_object_unref (self);
|
gst_object_unref (self);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -501,8 +516,8 @@ gst_signal_processor_event (GstPad * pad, GstEvent * event)
|
||||||
self = GST_SIGNAL_PROCESSOR (gst_pad_get_parent (pad));
|
self = GST_SIGNAL_PROCESSOR (gst_pad_get_parent (pad));
|
||||||
bclass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
|
bclass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
|
||||||
|
|
||||||
/* FIXME, this probably isn't the correct interface: what about return values, what
|
/* FIXME, this probably isn't the correct interface: what about return values,
|
||||||
* about overriding event_default
|
* what about overriding event_default
|
||||||
* Sync with GstBaseTransform::gst_base_transform_sink_event */
|
* Sync with GstBaseTransform::gst_base_transform_sink_event */
|
||||||
if (bclass->event)
|
if (bclass->event)
|
||||||
bclass->event (self, event);
|
bclass->event (self, event);
|
||||||
|
@ -545,6 +560,8 @@ gst_signal_processor_prepare (GstSignalProcessor * self, guint nframes)
|
||||||
self->audio_in[sinkpad->index] = sinkpad->data;
|
self->audio_in[sinkpad->index] = sinkpad->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: return if samples_avail==0 ? */
|
||||||
|
|
||||||
/* now assign output buffers. we can avoid allocation by reusing input
|
/* now assign output buffers. we can avoid allocation by reusing input
|
||||||
buffers, but only if process() can work in place, and if the input buffer
|
buffers, but only if process() can work in place, and if the input buffer
|
||||||
is the exact size of the number of samples we are processing. */
|
is the exact size of the number of samples we are processing. */
|
||||||
|
@ -637,11 +654,13 @@ gst_signal_processor_process (GstSignalProcessor * self, guint nframes)
|
||||||
GstElement *elem;
|
GstElement *elem;
|
||||||
GstSignalProcessorClass *klass;
|
GstSignalProcessorClass *klass;
|
||||||
|
|
||||||
|
/* check if we have buffers enqueued */
|
||||||
g_return_if_fail (self->pending_in == 0);
|
g_return_if_fail (self->pending_in == 0);
|
||||||
g_return_if_fail (self->pending_out == 0);
|
g_return_if_fail (self->pending_out == 0);
|
||||||
|
|
||||||
elem = GST_ELEMENT (self);
|
elem = GST_ELEMENT (self);
|
||||||
|
|
||||||
|
/* check how much input is available and prepare output buffers */
|
||||||
nframes = gst_signal_processor_prepare (self, nframes);
|
nframes = gst_signal_processor_prepare (self, nframes);
|
||||||
if (G_UNLIKELY (nframes == 0))
|
if (G_UNLIKELY (nframes == 0))
|
||||||
goto flow_error;
|
goto flow_error;
|
||||||
|
@ -704,6 +723,7 @@ gst_signal_processor_flush (GstSignalProcessor * self)
|
||||||
|
|
||||||
GST_INFO_OBJECT (self, "flush()");
|
GST_INFO_OBJECT (self, "flush()");
|
||||||
|
|
||||||
|
/* release enqueued buffers */
|
||||||
for (pads = GST_ELEMENT (self)->pads; pads; pads = pads->next) {
|
for (pads = GST_ELEMENT (self)->pads; pads; pads = pads->next) {
|
||||||
GstSignalProcessorPad *spad = (GstSignalProcessorPad *) pads->data;
|
GstSignalProcessorPad *spad = (GstSignalProcessorPad *) pads->data;
|
||||||
|
|
||||||
|
@ -715,6 +735,7 @@ gst_signal_processor_flush (GstSignalProcessor * self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* no outputs prepared and inputs for each pad needed */
|
||||||
self->pending_out = 0;
|
self->pending_out = 0;
|
||||||
self->pending_in = klass->num_audio_in;
|
self->pending_in = klass->num_audio_in;
|
||||||
}
|
}
|
||||||
|
@ -863,32 +884,6 @@ gst_signal_processor_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
return self->flow_state;
|
return self->flow_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_signal_processor_set_property (GObject * object, guint prop_id,
|
|
||||||
const GValue * value, GParamSpec * pspec)
|
|
||||||
{
|
|
||||||
/* GstSignalProcessor *self = GST_SIGNAL_PROCESSOR (object); */
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_signal_processor_get_property (GObject * object, guint prop_id,
|
|
||||||
GValue * value, GParamSpec * pspec)
|
|
||||||
{
|
|
||||||
/* GstSignalProcessor *self = GST_SIGNAL_PROCESSOR (object); */
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_signal_processor_sink_activate_push (GstPad * pad, gboolean active)
|
gst_signal_processor_sink_activate_push (GstPad * pad, gboolean active)
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,7 +79,9 @@ struct _GstSignalProcessor {
|
||||||
|
|
||||||
GstActivateMode mode;
|
GstActivateMode mode;
|
||||||
|
|
||||||
|
/* pending inputs before processing can take place */
|
||||||
guint pending_in;
|
guint pending_in;
|
||||||
|
/* panding outputs to be filled */
|
||||||
guint pending_out;
|
guint pending_out;
|
||||||
|
|
||||||
gfloat *control_in;
|
gfloat *control_in;
|
||||||
|
|
Loading…
Reference in a new issue