mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
ext/ladspa/gstsignalprocessor.h: Add infrastructure for storing whether a processor can work in place or not, and for...
Original commit message from CVS: 2006-08-04 Andy Wingo <wingo@pobox.com> * ext/ladspa/gstsignalprocessor.h: Add infrastructure for storing whether a processor can work in place or not, and for keeping track of its state. Change the FlowReturn instance variable from "state" to "flow_state", all callers changed. * ext/ladspa/gstsignalprocessor.c (gst_signal_processor_setup) (gst_signal_processor_start, gst_signal_processor_stop) (gst_signal_processor_cleanup): New functions to manage the processor's state. (gst_signal_processor_setcaps): start() as well as setup() here. (gst_signal_processor_prepare): Respect CAN_PROCESS_IN_PLACE. (gst_signal_processor_change_state): Stop and cleanup the processor as we go to NULL. * ext/ladspa/gstladspa.c (gst_ladspa_base_init): Reuse buffers if INPLACE_BROKEN is not set. * ext/ladspa/gstsignalprocessor.c (gst_signal_processor_prepare): Do the alloc_buffer in bytes, not frames.
This commit is contained in:
parent
71cad18c5e
commit
9bf2b5e3db
3 changed files with 161 additions and 37 deletions
|
@ -132,6 +132,9 @@ gst_ladspa_base_init (gpointer g_class)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!LADSPA_IS_INPLACE_BROKEN (desc->Properties))
|
||||||
|
GST_SIGNAL_PROCESSOR_CLASS_SET_CAN_PROCESS_IN_PLACE (klass);
|
||||||
|
|
||||||
klass->descriptor = desc;
|
klass->descriptor = desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -236,6 +236,8 @@ gst_signal_processor_init (GstSignalProcessor * self,
|
||||||
templates = templates->next;
|
templates = templates->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->state = GST_SIGNAL_PROCESSOR_STATE_NULL;
|
||||||
|
|
||||||
self->audio_in = g_new0 (gfloat *, klass->num_audio_in);
|
self->audio_in = g_new0 (gfloat *, klass->num_audio_in);
|
||||||
self->control_in = g_new0 (gfloat, klass->num_control_in);
|
self->control_in = g_new0 (gfloat, klass->num_control_in);
|
||||||
self->audio_out = g_new0 (gfloat *, klass->num_audio_out);
|
self->audio_out = g_new0 (gfloat *, klass->num_audio_out);
|
||||||
|
@ -265,14 +267,99 @@ gst_signal_processor_finalize (GObject * object)
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_signal_processor_setup (GstSignalProcessor * self, guint sample_rate)
|
||||||
|
{
|
||||||
|
GstSignalProcessorClass *klass;
|
||||||
|
gboolean ret = TRUE;
|
||||||
|
|
||||||
|
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
|
||||||
|
|
||||||
|
g_return_val_if_fail (self->state == GST_SIGNAL_PROCESSOR_STATE_NULL, FALSE);
|
||||||
|
|
||||||
|
if (klass->setup)
|
||||||
|
ret = klass->setup (self, sample_rate);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
goto setup_failed;
|
||||||
|
|
||||||
|
self->state = GST_SIGNAL_PROCESSOR_STATE_INITIALIZED;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
setup_failed:
|
||||||
|
{
|
||||||
|
GST_INFO_OBJECT (self, "setup() failed at %u Hz", sample_rate);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_signal_processor_start (GstSignalProcessor * self)
|
||||||
|
{
|
||||||
|
GstSignalProcessorClass *klass;
|
||||||
|
gboolean ret = TRUE;
|
||||||
|
|
||||||
|
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
|
||||||
|
|
||||||
|
g_return_val_if_fail (self->state == GST_SIGNAL_PROCESSOR_STATE_INITIALIZED,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
if (klass->start)
|
||||||
|
ret = klass->start (self);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
goto start_failed;
|
||||||
|
|
||||||
|
self->state = GST_SIGNAL_PROCESSOR_STATE_RUNNING;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
start_failed:
|
||||||
|
{
|
||||||
|
GST_INFO_OBJECT (self, "start() failed");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_signal_processor_stop (GstSignalProcessor * self)
|
||||||
|
{
|
||||||
|
GstSignalProcessorClass *klass;
|
||||||
|
|
||||||
|
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
|
||||||
|
|
||||||
|
g_return_if_fail (self->state == GST_SIGNAL_PROCESSOR_STATE_RUNNING);
|
||||||
|
|
||||||
|
if (klass->stop)
|
||||||
|
klass->stop (self);
|
||||||
|
|
||||||
|
/* should also flush our buffers perhaps? */
|
||||||
|
|
||||||
|
self->state = GST_SIGNAL_PROCESSOR_STATE_INITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_signal_processor_cleanup (GstSignalProcessor * self)
|
||||||
|
{
|
||||||
|
GstSignalProcessorClass *klass;
|
||||||
|
|
||||||
|
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
|
||||||
|
|
||||||
|
g_return_if_fail (self->state == GST_SIGNAL_PROCESSOR_STATE_INITIALIZED);
|
||||||
|
|
||||||
|
if (klass->cleanup)
|
||||||
|
klass->cleanup (self);
|
||||||
|
|
||||||
|
self->state = GST_SIGNAL_PROCESSOR_STATE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_signal_processor_setcaps (GstPad * pad, GstCaps * caps)
|
gst_signal_processor_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstSignalProcessor *self;
|
GstSignalProcessor *self;
|
||||||
GstSignalProcessorClass *klass;
|
|
||||||
|
|
||||||
self = GST_SIGNAL_PROCESSOR (gst_pad_get_parent (pad));
|
self = GST_SIGNAL_PROCESSOR (gst_pad_get_parent (pad));
|
||||||
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
|
|
||||||
|
|
||||||
/* the whole processor has one caps; if the sample rate changes, let subclass
|
/* the whole processor has one caps; if the sample rate changes, let subclass
|
||||||
implementations know */
|
implementations know */
|
||||||
|
@ -288,8 +375,10 @@ gst_signal_processor_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
GST_DEBUG_OBJECT (self, "Got rate=%d", sample_rate);
|
GST_DEBUG_OBJECT (self, "Got rate=%d", sample_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!klass->setup (self, sample_rate)) {
|
if (!gst_signal_processor_setup (self, sample_rate)) {
|
||||||
goto setup_failed;
|
goto start_failed;
|
||||||
|
} else if (!gst_signal_processor_start (self)) {
|
||||||
|
goto start_failed;
|
||||||
} else {
|
} else {
|
||||||
self->sample_rate = sample_rate;
|
self->sample_rate = sample_rate;
|
||||||
gst_caps_replace (&self->caps, caps);
|
gst_caps_replace (&self->caps, caps);
|
||||||
|
@ -304,9 +393,8 @@ gst_signal_processor_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
setup_failed:
|
start_failed:
|
||||||
{
|
{
|
||||||
GST_INFO_OBJECT (self, "setup() failed");
|
|
||||||
gst_object_unref (self);
|
gst_object_unref (self);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -344,9 +432,12 @@ static guint
|
||||||
gst_signal_processor_prepare (GstSignalProcessor * self)
|
gst_signal_processor_prepare (GstSignalProcessor * self)
|
||||||
{
|
{
|
||||||
GstElement *elem = (GstElement *) self;
|
GstElement *elem = (GstElement *) self;
|
||||||
|
GstSignalProcessorClass *klass;
|
||||||
GList *sinks, *srcs;
|
GList *sinks, *srcs;
|
||||||
guint samples_avail = G_MAXUINT;
|
guint samples_avail = G_MAXUINT;
|
||||||
|
|
||||||
|
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
|
||||||
|
|
||||||
/* first, assign audio_in pointers, and determine the number of samples that
|
/* first, assign audio_in pointers, and determine the number of samples that
|
||||||
* we can process */
|
* we can process */
|
||||||
for (sinks = elem->sinkpads; sinks; sinks = sinks->next) {
|
for (sinks = elem->sinkpads; sinks; sinks = sinks->next) {
|
||||||
|
@ -370,6 +461,7 @@ gst_signal_processor_prepare (GstSignalProcessor * self)
|
||||||
is the exact size of the number of samples we are processing. */
|
is the exact size of the number of samples we are processing. */
|
||||||
sinks = elem->sinkpads;
|
sinks = elem->sinkpads;
|
||||||
srcs = elem->srcpads;
|
srcs = elem->srcpads;
|
||||||
|
if (GST_SIGNAL_PROCESSOR_CLASS_CAN_PROCESS_IN_PLACE (klass)) {
|
||||||
while (sinks && srcs) {
|
while (sinks && srcs) {
|
||||||
GstSignalProcessorPad *sinkpad, *srcpad;
|
GstSignalProcessorPad *sinkpad, *srcpad;
|
||||||
|
|
||||||
|
@ -389,6 +481,7 @@ gst_signal_processor_prepare (GstSignalProcessor * self)
|
||||||
|
|
||||||
sinks = sinks->next;
|
sinks = sinks->next;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* now allocate for any remaining outputs */
|
/* now allocate for any remaining outputs */
|
||||||
while (srcs) {
|
while (srcs) {
|
||||||
|
@ -399,10 +492,10 @@ gst_signal_processor_prepare (GstSignalProcessor * self)
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
gst_pad_alloc_buffer_and_set_caps (GST_PAD (srcpad), -1,
|
gst_pad_alloc_buffer_and_set_caps (GST_PAD (srcpad), -1,
|
||||||
samples_avail, GST_PAD_CAPS (srcpad), &srcpad->pen);
|
samples_avail * sizeof (gfloat), GST_PAD_CAPS (srcpad), &srcpad->pen);
|
||||||
|
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
self->state = ret;
|
self->flow_state = ret;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
self->audio_out[srcpad->index] = (gfloat *) GST_BUFFER_DATA (srcpad->pen);
|
self->audio_out[srcpad->index] = (gfloat *) GST_BUFFER_DATA (srcpad->pen);
|
||||||
|
@ -476,7 +569,7 @@ gst_signal_processor_process (GstSignalProcessor * self)
|
||||||
flow_error:
|
flow_error:
|
||||||
{
|
{
|
||||||
GST_WARNING ("gst_pad_alloc_buffer_and_set_caps() returned %d",
|
GST_WARNING ("gst_pad_alloc_buffer_and_set_caps() returned %d",
|
||||||
self->state);
|
self->flow_state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,12 +639,12 @@ gst_signal_processor_do_pulls (GstSignalProcessor * self, guint nframes)
|
||||||
ret = gst_pad_pull_range (GST_PAD (spad), -1, nframes, &buf);
|
ret = gst_pad_pull_range (GST_PAD (spad), -1, nframes, &buf);
|
||||||
|
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
self->state = ret;
|
self->flow_state = ret;
|
||||||
gst_signal_processor_flush (self);
|
gst_signal_processor_flush (self);
|
||||||
return;
|
return;
|
||||||
} else if (!buf) {
|
} else if (!buf) {
|
||||||
g_critical ("Pull failed to make a buffer!");
|
g_critical ("Pull failed to make a buffer!");
|
||||||
self->state = GST_FLOW_ERROR;
|
self->flow_state = GST_FLOW_ERROR;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
gst_signal_processor_pen_buffer (self, GST_PAD (spad), buf);
|
gst_signal_processor_pen_buffer (self, GST_PAD (spad), buf);
|
||||||
|
@ -560,7 +653,7 @@ gst_signal_processor_do_pulls (GstSignalProcessor * self, guint nframes)
|
||||||
|
|
||||||
if (self->pending_in != 0) {
|
if (self->pending_in != 0) {
|
||||||
g_critical ("Something wierd happened...");
|
g_critical ("Something wierd happened...");
|
||||||
self->state = GST_FLOW_ERROR;
|
self->flow_state = GST_FLOW_ERROR;
|
||||||
} else {
|
} else {
|
||||||
gst_signal_processor_process (self);
|
gst_signal_processor_process (self);
|
||||||
}
|
}
|
||||||
|
@ -587,7 +680,7 @@ gst_signal_processor_getrange (GstPad * pad, guint64 offset,
|
||||||
if (!spad->pen) {
|
if (!spad->pen) {
|
||||||
/* this is an error condition */
|
/* this is an error condition */
|
||||||
*buffer = NULL;
|
*buffer = NULL;
|
||||||
ret = self->state;
|
ret = self->flow_state;
|
||||||
} else {
|
} else {
|
||||||
*buffer = spad->pen;
|
*buffer = spad->pen;
|
||||||
spad->pen = NULL;
|
spad->pen = NULL;
|
||||||
|
@ -625,7 +718,7 @@ gst_signal_processor_do_pushes (GstSignalProcessor * self)
|
||||||
ret = gst_pad_push (GST_PAD (spad), spad->pen);
|
ret = gst_pad_push (GST_PAD (spad), spad->pen);
|
||||||
|
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
self->state = ret;
|
self->flow_state = ret;
|
||||||
gst_signal_processor_flush (self);
|
gst_signal_processor_flush (self);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -637,7 +730,7 @@ gst_signal_processor_do_pushes (GstSignalProcessor * self)
|
||||||
|
|
||||||
if (self->pending_out != 0) {
|
if (self->pending_out != 0) {
|
||||||
g_critical ("Something wierd happened...");
|
g_critical ("Something wierd happened...");
|
||||||
self->state = GST_FLOW_ERROR;
|
self->flow_state = GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,7 +751,7 @@ gst_signal_processor_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
|
|
||||||
gst_object_unref (self);
|
gst_object_unref (self);
|
||||||
|
|
||||||
return self->state;
|
return self->flow_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -778,13 +871,10 @@ static GstStateChangeReturn
|
||||||
gst_signal_processor_change_state (GstElement * element,
|
gst_signal_processor_change_state (GstElement * element,
|
||||||
GstStateChange transition)
|
GstStateChange transition)
|
||||||
{
|
{
|
||||||
/* GstSignalProcessor *self;
|
GstSignalProcessor *self;
|
||||||
GstSignalProcessorClass *klass; */
|
|
||||||
GstStateChangeReturn result;
|
GstStateChangeReturn result;
|
||||||
|
|
||||||
/* self = GST_SIGNAL_PROCESSOR (element);
|
self = GST_SIGNAL_PROCESSOR (element);
|
||||||
klass = GST_SIGNAL_PROCESSOR_GET_CLASS (self); */
|
|
||||||
|
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
|
@ -806,9 +896,12 @@ gst_signal_processor_change_state (GstElement * element,
|
||||||
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
|
if (GST_SIGNAL_PROCESSOR_IS_RUNNING (self))
|
||||||
|
gst_signal_processor_stop (self);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
/* gst_signal_processor_cleanup (self); */
|
if (GST_SIGNAL_PROCESSOR_IS_INITIALIZED (self))
|
||||||
|
gst_signal_processor_cleanup (self);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -29,6 +29,26 @@
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_SIGNAL_PROCESSOR_CLASS_FLAG_CAN_PROCESS_IN_PLACE = 1<<0
|
||||||
|
} GstSignalProcessorClassFlags;
|
||||||
|
|
||||||
|
#define GST_SIGNAL_PROCESSOR_CLASS_CAN_PROCESS_IN_PLACE(klass) \
|
||||||
|
(GST_SIGNAL_PROCESSOR_CLASS (klass)->flags & \
|
||||||
|
GST_SIGNAL_PROCESSOR_CLASS_FLAG_CAN_PROCESS_IN_PLACE)
|
||||||
|
#define GST_SIGNAL_PROCESSOR_CLASS_SET_CAN_PROCESS_IN_PLACE(klass) \
|
||||||
|
GST_SIGNAL_PROCESSOR_CLASS (klass)->flags |= \
|
||||||
|
GST_SIGNAL_PROCESSOR_CLASS_FLAG_CAN_PROCESS_IN_PLACE
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_SIGNAL_PROCESSOR_STATE_NULL,
|
||||||
|
GST_SIGNAL_PROCESSOR_STATE_INITIALIZED,
|
||||||
|
GST_SIGNAL_PROCESSOR_STATE_RUNNING
|
||||||
|
} GstSignalProcessorState;
|
||||||
|
|
||||||
|
|
||||||
#define GST_TYPE_SIGNAL_PROCESSOR (gst_signal_processor_get_type())
|
#define GST_TYPE_SIGNAL_PROCESSOR (gst_signal_processor_get_type())
|
||||||
#define GST_SIGNAL_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SIGNAL_PROCESSOR,GstSignalProcessor))
|
#define GST_SIGNAL_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SIGNAL_PROCESSOR,GstSignalProcessor))
|
||||||
#define GST_SIGNAL_PROCESSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SIGNAL_PROCESSOR,GstSignalProcessorClass))
|
#define GST_SIGNAL_PROCESSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SIGNAL_PROCESSOR,GstSignalProcessorClass))
|
||||||
|
@ -37,6 +57,10 @@ G_BEGIN_DECLS
|
||||||
#define GST_IS_SIGNAL_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SIGNAL_PROCESSOR))
|
#define GST_IS_SIGNAL_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SIGNAL_PROCESSOR))
|
||||||
#define GST_IS_SIGNAL_PROCESSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SIGNAL_PROCESSOR))
|
#define GST_IS_SIGNAL_PROCESSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SIGNAL_PROCESSOR))
|
||||||
|
|
||||||
|
#define GST_SIGNAL_PROCESSOR_IS_INITIALIZED(obj) \
|
||||||
|
(GST_SIGNAL_PROCESSOR (obj)->state >= GST_SIGNAL_PROCESSOR_STATE_INITIALIZED)
|
||||||
|
#define GST_SIGNAL_PROCESSOR_IS_RUNNING(obj) \
|
||||||
|
(GST_SIGNAL_PROCESSOR (obj)->state == GST_SIGNAL_PROCESSOR_STATE_RUNNING)
|
||||||
|
|
||||||
typedef struct _GstSignalProcessor GstSignalProcessor;
|
typedef struct _GstSignalProcessor GstSignalProcessor;
|
||||||
typedef struct _GstSignalProcessorClass GstSignalProcessorClass;
|
typedef struct _GstSignalProcessorClass GstSignalProcessorClass;
|
||||||
|
@ -49,7 +73,9 @@ struct _GstSignalProcessor {
|
||||||
|
|
||||||
guint sample_rate;
|
guint sample_rate;
|
||||||
|
|
||||||
GstFlowReturn state;
|
GstSignalProcessorState state;
|
||||||
|
|
||||||
|
GstFlowReturn flow_state;
|
||||||
|
|
||||||
GstActivateMode mode;
|
GstActivateMode mode;
|
||||||
|
|
||||||
|
@ -71,6 +97,8 @@ struct _GstSignalProcessorClass {
|
||||||
guint num_control_out;
|
guint num_control_out;
|
||||||
guint num_audio_out;
|
guint num_audio_out;
|
||||||
|
|
||||||
|
guint flags;
|
||||||
|
|
||||||
/* virtual methods for subclasses */
|
/* virtual methods for subclasses */
|
||||||
|
|
||||||
gboolean (*setup) (GstSignalProcessor *self, guint sample_rate);
|
gboolean (*setup) (GstSignalProcessor *self, guint sample_rate);
|
||||||
|
|
Loading…
Reference in a new issue