Commit 2207ced5 authored by Andy Wingo Wingo's avatar Andy Wingo Wingo Committed by Wim Taymans
Browse files

ext/ladspa/gstsignalprocessor.c: Make ladspa elements reusable. Fixes #350006.

Original commit message from CVS:
Patch by: Andy Wingo <wingo at pobox dot com>
* ext/ladspa/gstsignalprocessor.c: (gst_signal_processor_setup),
(gst_signal_processor_start), (gst_signal_processor_stop),
(gst_signal_processor_cleanup), (gst_signal_processor_setcaps),
(gst_signal_processor_pen_buffer), (gst_signal_processor_flush),
(gst_signal_processor_do_pulls), (gst_signal_processor_do_pushes),
(gst_signal_processor_change_state):
Make ladspa elements reusable. Fixes #350006.
parent 29161cb5
2006-08-16 Wim Taymans <wim@fluendo.com>
Patch by: Andy Wingo <wingo at pobox dot com>
* ext/ladspa/gstsignalprocessor.c: (gst_signal_processor_setup),
(gst_signal_processor_start), (gst_signal_processor_stop),
(gst_signal_processor_cleanup), (gst_signal_processor_setcaps),
(gst_signal_processor_pen_buffer), (gst_signal_processor_flush),
(gst_signal_processor_do_pulls), (gst_signal_processor_do_pushes),
(gst_signal_processor_change_state):
Make ladspa elements reusable. Fixes #350006.
2006-08-16 Wim Taymans <wim@fluendo.com>
* ext/ladspa/gstladspa.c: (gst_ladspa_base_init):
Convert ' ' into '_'. Try to keep as many characters in the padtemplate
names as possible.
names as possible. Fixes #349901.
2006-08-16 Wim Taymans <wim@fluendo.com>
......
......@@ -275,6 +275,8 @@ gst_signal_processor_setup (GstSignalProcessor * self, guint sample_rate)
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
GST_INFO_OBJECT (self, "setup()");
g_return_val_if_fail (self->state == GST_SIGNAL_PROCESSOR_STATE_NULL, FALSE);
if (klass->setup)
......@@ -305,6 +307,8 @@ gst_signal_processor_start (GstSignalProcessor * self)
g_return_val_if_fail (self->state == GST_SIGNAL_PROCESSOR_STATE_INITIALIZED,
FALSE);
GST_INFO_OBJECT (self, "start()");
if (klass->start)
ret = klass->start (self);
......@@ -326,14 +330,23 @@ static void
gst_signal_processor_stop (GstSignalProcessor * self)
{
GstSignalProcessorClass *klass;
GstElement *elem;
GList *sinks;
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
elem = GST_ELEMENT (self);
GST_INFO_OBJECT (self, "stop()");
g_return_if_fail (self->state == GST_SIGNAL_PROCESSOR_STATE_RUNNING);
if (klass->stop)
klass->stop (self);
for (sinks = elem->sinkpads; sinks; sinks = sinks->next)
/* force set_caps when going to RUNNING, see note in set_caps */
gst_pad_set_caps (GST_PAD (sinks->data), NULL);
/* should also flush our buffers perhaps? */
self->state = GST_SIGNAL_PROCESSOR_STATE_INITIALIZED;
......@@ -346,6 +359,8 @@ gst_signal_processor_cleanup (GstSignalProcessor * self)
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
GST_INFO_OBJECT (self, "cleanup()");
g_return_if_fail (self->state == GST_SIGNAL_PROCESSOR_STATE_INITIALIZED);
if (klass->cleanup)
......@@ -363,7 +378,7 @@ gst_signal_processor_setcaps (GstPad * pad, GstCaps * caps)
/* the whole processor has one caps; if the sample rate changes, let subclass
implementations know */
if (caps != self->caps) {
if (!gst_caps_is_equal (caps, self->caps)) {
GstStructure *s;
gint sample_rate;
......@@ -375,10 +390,13 @@ gst_signal_processor_setcaps (GstPad * pad, GstCaps * caps)
GST_DEBUG_OBJECT (self, "Got rate=%d", sample_rate);
}
if (GST_SIGNAL_PROCESSOR_IS_RUNNING (self))
gst_signal_processor_stop (self);
if (GST_SIGNAL_PROCESSOR_IS_INITIALIZED (self))
gst_signal_processor_cleanup (self);
if (!gst_signal_processor_setup (self, sample_rate)) {
goto start_failed;
} else if (!gst_signal_processor_start (self)) {
goto start_failed;
} else {
self->sample_rate = sample_rate;
gst_caps_replace (&self->caps, caps);
......@@ -387,7 +405,17 @@ gst_signal_processor_setcaps (GstPad * pad, GstCaps * caps)
GST_DEBUG_OBJECT (self, "skipping, have caps already");
}
/* FIXME: handle was_active, etc */
/* we use this method to manage the processor's state, hence the caps clearing
in stop(). so it can be that we enter here just to manage the processor's
state, to take it to RUNNING from already being INITIALIZED with the right
sample rate (e.g., when having gone PLAYING->READY->PLAYING). make sure
when we leave that the processor is RUNNING. */
if (!GST_SIGNAL_PROCESSOR_IS_INITIALIZED (self)
&& !gst_signal_processor_setup (self, self->sample_rate))
goto start_failed;
if (!GST_SIGNAL_PROCESSOR_IS_RUNNING (self)
&& !gst_signal_processor_start (self))
goto start_failed;
gst_object_unref (self);
......@@ -580,12 +608,8 @@ gst_signal_processor_pen_buffer (GstSignalProcessor * self, GstPad * pad,
{
GstSignalProcessorPad *spad = (GstSignalProcessorPad *) pad;
if (spad->pen) {
GST_WARNING ("Pad %s:%s already has penned buffer",
GST_DEBUG_PAD_NAME (pad));
gst_buffer_unref (buffer);
return;
}
if (spad->pen)
goto had_buffer;
/* keep the reference */
spad->pen = buffer;
......@@ -595,12 +619,28 @@ gst_signal_processor_pen_buffer (GstSignalProcessor * self, GstPad * pad,
g_assert (self->pending_in != 0);
self->pending_in--;
return;
/* ERRORS */
had_buffer:
{
GST_WARNING ("Pad %s:%s already has penned buffer",
GST_DEBUG_PAD_NAME (pad));
gst_buffer_unref (buffer);
return;
}
}
static void
gst_signal_processor_flush (GstSignalProcessor * self)
{
GList *pads;
GstSignalProcessorClass *klass;
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
GST_INFO_OBJECT (self, "flush()");
for (pads = GST_ELEMENT (self)->pads; pads; pads = pads->next) {
GstSignalProcessorPad *spad = (GstSignalProcessorPad *) pads->data;
......@@ -612,6 +652,9 @@ gst_signal_processor_flush (GstSignalProcessor * self)
spad->samples_avail = 0;
}
}
self->pending_out = 0;
self->pending_in = klass->num_audio_in;
}
static void
......@@ -637,8 +680,8 @@ gst_signal_processor_do_pulls (GstSignalProcessor * self, guint nframes)
ret = gst_pad_pull_range (GST_PAD (spad), -1, nframes, &buf);
if (ret != GST_FLOW_OK) {
self->flow_state = ret;
gst_signal_processor_flush (self);
self->flow_state = ret;
return;
} else if (!buf) {
g_critical ("Pull failed to make a buffer!");
......@@ -721,8 +764,8 @@ gst_signal_processor_do_pushes (GstSignalProcessor * self)
ret = gst_pad_push (GST_PAD (spad), buffer);
if (ret != GST_FLOW_OK) {
self->flow_state = ret;
gst_signal_processor_flush (self);
self->flow_state = ret;
return;
} else {
g_assert (self->pending_out > 0);
......@@ -882,6 +925,7 @@ gst_signal_processor_change_state (GstElement * element,
case GST_STATE_CHANGE_NULL_TO_READY:
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
self->flow_state = GST_FLOW_OK;
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
break;
......@@ -900,6 +944,7 @@ gst_signal_processor_change_state (GstElement * element,
case GST_STATE_CHANGE_PAUSED_TO_READY:
if (GST_SIGNAL_PROCESSOR_IS_RUNNING (self))
gst_signal_processor_stop (self);
gst_signal_processor_flush (self);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
if (GST_SIGNAL_PROCESSOR_IS_INITIALIZED (self))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment