mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 02:15:31 +00:00
ext/ladspa/gstsignalprocessor.c (gst_signal_processor_setcaps) (gst_signal_processor_prepare) (gst_signal_processor_u...
Original commit message from CVS: 2006-08-04 Andy Wingo <wingo@pobox.com> * ext/ladspa/gstsignalprocessor.c (gst_signal_processor_setcaps) (gst_signal_processor_prepare) (gst_signal_processor_update_inputs) (gst_signal_processor_process, gst_signal_processor_pen_buffer) (gst_signal_processor_flush) (gst_signal_processor_sink_activate_push) (gst_signal_processor_src_activate_pull) (gst_signal_processor_change_state): Remove the last of the code that assumes that we process whole buffers at a time. Fix some debugging. Seems to work now in some cases.
This commit is contained in:
parent
9457674bc0
commit
6ea23316fd
2 changed files with 144 additions and 78 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2006-08-04 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
|
* ext/ladspa/gstsignalprocessor.c (gst_signal_processor_setcaps)
|
||||||
|
(gst_signal_processor_prepare)
|
||||||
|
(gst_signal_processor_update_inputs)
|
||||||
|
(gst_signal_processor_process, gst_signal_processor_pen_buffer)
|
||||||
|
(gst_signal_processor_flush)
|
||||||
|
(gst_signal_processor_sink_activate_push)
|
||||||
|
(gst_signal_processor_src_activate_pull)
|
||||||
|
(gst_signal_processor_change_state): Remove the last of the code
|
||||||
|
that assumes that we process whole buffers at a time. Fix some
|
||||||
|
debugging. Seems to work now in some cases.
|
||||||
|
|
||||||
2006-08-01 Andy Wingo <wingo@pobox.com>
|
2006-08-01 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
* ext/ladspa/gstsignalprocessor.c (gst_signal_processor_process):
|
* ext/ladspa/gstsignalprocessor.c (gst_signal_processor_process):
|
||||||
|
|
|
@ -110,6 +110,10 @@ struct _GstSignalProcessorPad
|
||||||
GstBuffer *pen;
|
GstBuffer *pen;
|
||||||
|
|
||||||
guint index;
|
guint index;
|
||||||
|
|
||||||
|
/* these are only used for sink pads */
|
||||||
|
guint samples_avail;
|
||||||
|
gfloat *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GType
|
static GType
|
||||||
|
@ -281,15 +285,17 @@ gst_signal_processor_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
GST_WARNING ("got no sample-rate");
|
GST_WARNING ("got no sample-rate");
|
||||||
goto impossible;
|
goto impossible;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("Got rate=%d", sample_rate);
|
GST_DEBUG_OBJECT (self, "Got rate=%d", sample_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!klass->setup (self, sample_rate))
|
if (!klass->setup (self, sample_rate)) {
|
||||||
goto setup_failed;
|
goto setup_failed;
|
||||||
else
|
} else {
|
||||||
self->sample_rate = sample_rate;
|
self->sample_rate = sample_rate;
|
||||||
|
gst_caps_replace (&self->caps, caps);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("skipping, have caps already");
|
GST_DEBUG_OBJECT (self, "skipping, have caps already");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: handle was_active, etc */
|
/* FIXME: handle was_active, etc */
|
||||||
|
@ -334,90 +340,138 @@ gst_signal_processor_event (GstPad * pad, GstEvent * event)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
gst_signal_processor_prepare (GstSignalProcessor * self)
|
||||||
|
{
|
||||||
|
GstElement *elem = (GstElement *) self;
|
||||||
|
GList *sinks, *srcs;
|
||||||
|
guint samples_avail = G_MAXUINT;
|
||||||
|
|
||||||
|
/* first, assign audio_in pointers, and determine the number of samples that
|
||||||
|
* we can process */
|
||||||
|
for (sinks = elem->sinkpads; sinks; sinks = sinks->next) {
|
||||||
|
GstSignalProcessorPad *sinkpad;
|
||||||
|
|
||||||
|
sinkpad = (GstSignalProcessorPad *) sinks->data;
|
||||||
|
g_assert (sinkpad->samples_avail > 0);
|
||||||
|
samples_avail = MIN (samples_avail, sinkpad->samples_avail);
|
||||||
|
self->audio_in[sinkpad->index] = sinkpad->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samples_avail == G_MAXUINT) {
|
||||||
|
/* we don't have any sink pads, just choose a size -- should fix this
|
||||||
|
* function to have a suggested number of samples in the case of
|
||||||
|
* gst_pad_pull_range */
|
||||||
|
samples_avail = 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
is the exact size of the number of samples we are processing. */
|
||||||
|
sinks = elem->sinkpads;
|
||||||
|
srcs = elem->srcpads;
|
||||||
|
while (sinks && srcs) {
|
||||||
|
GstSignalProcessorPad *sinkpad, *srcpad;
|
||||||
|
|
||||||
|
sinkpad = (GstSignalProcessorPad *) sinks->data;
|
||||||
|
srcpad = (GstSignalProcessorPad *) srcs->data;
|
||||||
|
|
||||||
|
if (GST_BUFFER_SIZE (sinkpad->pen) == samples_avail * sizeof (gfloat)) {
|
||||||
|
/* reusable, yay */
|
||||||
|
g_assert (sinkpad->samples_avail == samples_avail);
|
||||||
|
srcpad->pen = sinkpad->pen;
|
||||||
|
sinkpad->pen = NULL;
|
||||||
|
self->audio_out[srcpad->index] = sinkpad->data;
|
||||||
|
self->pending_out++;
|
||||||
|
|
||||||
|
srcs = srcs->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
sinks = sinks->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now allocate for any remaining outputs */
|
||||||
|
while (srcs) {
|
||||||
|
GstSignalProcessorPad *srcpad;
|
||||||
|
GstFlowReturn ret;
|
||||||
|
|
||||||
|
srcpad = (GstSignalProcessorPad *) srcs->data;
|
||||||
|
|
||||||
|
ret =
|
||||||
|
gst_pad_alloc_buffer_and_set_caps (GST_PAD (srcpad), -1,
|
||||||
|
samples_avail, GST_PAD_CAPS (srcpad), &srcpad->pen);
|
||||||
|
|
||||||
|
if (ret != GST_FLOW_OK) {
|
||||||
|
self->state = ret;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
self->audio_out[srcpad->index] = (gfloat *) GST_BUFFER_DATA (srcpad->pen);
|
||||||
|
self->pending_out++;
|
||||||
|
}
|
||||||
|
|
||||||
|
srcs = srcs->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return samples_avail;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_signal_processor_update_inputs (GstSignalProcessor * self, guint nprocessed)
|
||||||
|
{
|
||||||
|
GstElement *elem = (GstElement *) self;
|
||||||
|
GList *sinks;
|
||||||
|
|
||||||
|
for (sinks = elem->sinkpads; sinks; sinks = sinks->next) {
|
||||||
|
GstSignalProcessorPad *sinkpad;
|
||||||
|
|
||||||
|
sinkpad = (GstSignalProcessorPad *) sinks->data;
|
||||||
|
g_assert (sinkpad->samples_avail >= nprocessed);
|
||||||
|
|
||||||
|
if (sinkpad->pen && sinkpad->samples_avail == nprocessed) {
|
||||||
|
/* used up this buffer, unpen */
|
||||||
|
gst_buffer_unref (sinkpad->pen);
|
||||||
|
sinkpad->pen = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sinkpad->pen) {
|
||||||
|
/* this buffer was used up */
|
||||||
|
self->pending_in++;
|
||||||
|
sinkpad->data = NULL;
|
||||||
|
sinkpad->samples_avail = 0;
|
||||||
|
} else {
|
||||||
|
/* advance ->data pointers and decrement ->samples_avail, unreffing buffer
|
||||||
|
if no samples are left */
|
||||||
|
sinkpad->samples_avail -= nprocessed;
|
||||||
|
sinkpad->data += nprocessed; /* gfloat* arithmetic */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_signal_processor_process (GstSignalProcessor * self)
|
gst_signal_processor_process (GstSignalProcessor * self)
|
||||||
{
|
{
|
||||||
GstElement *elem;
|
GstElement *elem;
|
||||||
GList *l1, *l2;
|
|
||||||
GstSignalProcessorClass *klass;
|
GstSignalProcessorClass *klass;
|
||||||
guint nframes = G_MAXUINT;
|
guint nframes;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
/* arrange the output buffers */
|
nframes = gst_signal_processor_prepare (self);
|
||||||
for (l1 = elem->sinkpads, l2 = elem->srcpads; l1 || l2;
|
if (G_UNLIKELY (nframes == 0))
|
||||||
l1 = l1 ? l1->next : NULL, l2 = l2 ? l2->next : NULL) {
|
goto flow_error;
|
||||||
GstSignalProcessorPad *srcpad, *sinkpad;
|
|
||||||
|
|
||||||
if (l1) {
|
|
||||||
GstSignalProcessorPad *tmp = (GstSignalProcessorPad *) l1->data;
|
|
||||||
|
|
||||||
nframes = MIN (nframes, GST_BUFFER_SIZE (tmp->pen) / sizeof (gfloat));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!l2) {
|
|
||||||
/* the output buffers have been covered, yay -- just keep looping to check
|
|
||||||
available frames */
|
|
||||||
} else if (!l1) {
|
|
||||||
/* need to alloc some output buffers */
|
|
||||||
for (; l2; l2 = l2->next) {
|
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
srcpad = (GstSignalProcessorPad *) l2->data;
|
|
||||||
|
|
||||||
ret =
|
|
||||||
gst_pad_alloc_buffer_and_set_caps (GST_PAD (srcpad), -1,
|
|
||||||
nframes, GST_PAD_CAPS (srcpad), &srcpad->pen);
|
|
||||||
|
|
||||||
if (ret != GST_FLOW_OK) {
|
|
||||||
self->state = ret;
|
|
||||||
goto flow_error;
|
|
||||||
} else {
|
|
||||||
self->audio_out[srcpad->index] =
|
|
||||||
(gfloat *) GST_BUFFER_DATA (srcpad->pen);
|
|
||||||
self->pending_out++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the for condition should cut out because of this, but I assert to be
|
|
||||||
clear */
|
|
||||||
g_assert (l2 == NULL);
|
|
||||||
} else {
|
|
||||||
/* copy input to output */
|
|
||||||
sinkpad = (GstSignalProcessorPad *) l1->data;
|
|
||||||
srcpad = (GstSignalProcessorPad *) l2->data;
|
|
||||||
|
|
||||||
srcpad->pen = sinkpad->pen;
|
|
||||||
sinkpad->pen = NULL;
|
|
||||||
self->audio_out[srcpad->index] = (gfloat *) GST_BUFFER_DATA (srcpad->pen);
|
|
||||||
self->pending_out++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* will fail in the ladspa src case, need to check that :-/ */
|
|
||||||
g_assert (nframes < G_MAXUINT);
|
|
||||||
|
|
||||||
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
|
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
|
||||||
|
|
||||||
GST_INFO_OBJECT (self, "process(%u)", nframes);
|
GST_LOG_OBJECT (self, "process(%u)", nframes);
|
||||||
|
|
||||||
klass->process (self, nframes);
|
klass->process (self, nframes);
|
||||||
|
|
||||||
/* reset */
|
gst_signal_processor_update_inputs (self, nframes);
|
||||||
self->pending_in = klass->num_audio_in;
|
|
||||||
|
|
||||||
/* free unneeded input buffers */
|
return;
|
||||||
for (l1 = elem->sinkpads; l1; l1 = l1->next) {
|
|
||||||
GstSignalProcessorPad *sinkpad = (GstSignalProcessorPad *) l1->data;
|
|
||||||
|
|
||||||
if (sinkpad->pen) {
|
|
||||||
gst_buffer_unref (sinkpad->pen);
|
|
||||||
sinkpad->pen = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
flow_error:
|
flow_error:
|
||||||
{
|
{
|
||||||
|
@ -442,15 +496,12 @@ gst_signal_processor_pen_buffer (GstSignalProcessor * self, GstPad * pad,
|
||||||
|
|
||||||
/* keep the reference */
|
/* keep the reference */
|
||||||
spad->pen = buffer;
|
spad->pen = buffer;
|
||||||
self->audio_in[spad->index] = (gfloat *) GST_BUFFER_DATA (buffer);
|
spad->data = (gfloat *) GST_BUFFER_DATA (buffer);
|
||||||
|
spad->samples_avail = GST_BUFFER_SIZE (buffer) / sizeof (float);
|
||||||
|
|
||||||
g_assert (self->pending_in != 0);
|
g_assert (self->pending_in != 0);
|
||||||
|
|
||||||
self->pending_in--;
|
self->pending_in--;
|
||||||
|
|
||||||
if (self->pending_in == 0) {
|
|
||||||
gst_signal_processor_process (self);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -466,6 +517,8 @@ gst_signal_processor_flush (GstSignalProcessor * self)
|
||||||
if (spad->pen) {
|
if (spad->pen) {
|
||||||
gst_buffer_unref (spad->pen);
|
gst_buffer_unref (spad->pen);
|
||||||
spad->pen = NULL;
|
spad->pen = NULL;
|
||||||
|
spad->data = NULL;
|
||||||
|
spad->samples_avail = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -666,7 +719,7 @@ gst_signal_processor_sink_activate_push (GstPad * pad, gboolean active)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG ("result : %d", TRUE);
|
GST_DEBUG_OBJECT (self, "result : %d", result);
|
||||||
|
|
||||||
gst_object_unref (self);
|
gst_object_unref (self);
|
||||||
|
|
||||||
|
@ -714,7 +767,7 @@ gst_signal_processor_src_activate_pull (GstPad * pad, gboolean active)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG ("result : %d", TRUE);
|
GST_DEBUG_OBJECT ("result : %d", result);
|
||||||
|
|
||||||
gst_object_unref (self);
|
gst_object_unref (self);
|
||||||
|
|
||||||
|
@ -766,7 +819,7 @@ gst_signal_processor_change_state (GstElement * element,
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
failure:
|
failure:
|
||||||
{
|
{
|
||||||
GST_DEBUG ("parent failed state change");
|
GST_DEBUG_OBJECT (element, "parent failed state change");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue