summaryrefslogtreecommitdiffstats
path: root/ext/ladspa
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2006-08-16 16:50:00 +0000
committerWim Taymans <wim.taymans@gmail.com>2006-08-16 16:50:00 +0000
commit4fb8a95581896e747efb6d6d8c9fa778670ec637 (patch)
tree43203f73ada42770559002ab8e50feb9df9b4c9d /ext/ladspa
parent1fd9e983f3007bc99d855b72dc4498da2b81478b (diff)
downloadgst-plugins-bad-4fb8a95581896e747efb6d6d8c9fa778670ec637.tar.gz
gst-plugins-bad-4fb8a95581896e747efb6d6d8c9fa778670ec637.tar.bz2
gst-plugins-bad-4fb8a95581896e747efb6d6d8c9fa778670ec637.zip
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.
Diffstat (limited to 'ext/ladspa')
-rw-r--r--ext/ladspa/gstsignalprocessor.c69
1 files changed, 57 insertions, 12 deletions
diff --git a/ext/ladspa/gstsignalprocessor.c b/ext/ladspa/gstsignalprocessor.c
index 41fe4e1e..12a0faff 100644
--- a/ext/ladspa/gstsignalprocessor.c
+++ b/ext/ladspa/gstsignalprocessor.c
@@ -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))