21
21
* Boston, MA 02111-1307, USA.
25
* SECTION:gstsignalprocessor
27
* This baseclass allows to write elements that need data on all pads before
28
* their processing function can run.
30
* In push mode (gst_signal_processor_chain) it operates as follows:
31
* 1. store each received buffer on the pad and decrement pending_in
32
* 2. when pending_in==0, process as much as we can and push outputs
34
* In pull mode (gst_signal_processor_getrange) is operates as follows:
35
* 1. if there is an output ready, deliver
36
* 2. otherwise pull from each sink-pad, process requested frames and deliver
25
40
#include <stdlib.h>
74
/* FIXME: better allow the caller to pass on the template, right now this can
75
* only create mono pads */
90
* gst_signal_processor_class_add_pad_template:
91
* @klass: element class
93
* @direction: pad direction (src/sink)
94
* @index: index for the pad per direction (starting from 0)
77
98
gst_signal_processor_class_add_pad_template (GstSignalProcessorClass * klass,
78
99
const gchar * name, GstPadDirection direction, guint index)
80
101
GstPadTemplate *new;
82
104
g_return_if_fail (GST_IS_SIGNAL_PROCESSOR_CLASS (klass));
83
105
g_return_if_fail (name != NULL);
84
106
g_return_if_fail (direction == GST_PAD_SRC || direction == GST_PAD_SINK);
108
/* FIXME: would be nice to have the template as a parameter, right now this can
109
* only create mono pads */
110
caps = gst_caps_copy (gst_static_caps_get (&template_caps));
86
112
new = g_object_new (gst_signal_processor_pad_template_get_type (),
113
"name", name, "name-template", name,
114
"direction", direction, "presence", GST_PAD_ALWAYS, "caps", caps, NULL);
89
GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = g_strdup (name);
90
GST_PAD_TEMPLATE_DIRECTION (new) = direction;
91
GST_PAD_TEMPLATE_PRESENCE (new) = GST_PAD_ALWAYS;
92
GST_PAD_TEMPLATE_CAPS (new) = gst_caps_copy (gst_static_caps_get
94
116
GST_SIGNAL_PROCESSOR_PAD_TEMPLATE (new)->index = index;
96
118
gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), new);
135
/* index for the pad per direction (starting from 0) */
115
138
/* these are only used for sink pads */
139
guint samples_avail; /* available mono sample frames */
140
gfloat *data; /* data pointer to read from / write to */
142
165
static void gst_signal_processor_finalize (GObject * object);
143
static void gst_signal_processor_set_property (GObject * object, guint prop_id,
144
const GValue * value, GParamSpec * pspec);
145
static void gst_signal_processor_get_property (GObject * object, guint prop_id,
146
GValue * value, GParamSpec * pspec);
147
166
static gboolean gst_signal_processor_src_activate_pull (GstPad * pad,
148
167
gboolean active);
149
168
static gboolean gst_signal_processor_sink_activate_push (GstPad * pad,
176
195
gstelement_class = GST_ELEMENT_CLASS (klass);
178
197
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_signal_processor_finalize);
179
gobject_class->set_property =
180
GST_DEBUG_FUNCPTR (gst_signal_processor_set_property);
181
gobject_class->get_property =
182
GST_DEBUG_FUNCPTR (gst_signal_processor_get_property);
184
199
gstelement_class->change_state =
185
200
GST_DEBUG_FUNCPTR (gst_signal_processor_change_state);
345
360
klass->stop (self);
347
362
for (sinks = elem->sinkpads; sinks; sinks = sinks->next)
348
/* force set_caps when going to RUNNING, see note in set_caps */
363
/* force set_caps when going to RUNNING, see note in _setcaps () */
349
364
gst_pad_set_caps (GST_PAD (sinks->data), NULL);
351
366
/* should also flush our buffers perhaps? */
449
464
gst_signal_processor_cleanup (self);
451
466
if (!gst_signal_processor_setup (self, sample_rate))
467
goto start_or_setup_failed;
454
469
self->sample_rate = sample_rate;
455
470
gst_caps_replace (&self->caps, caps);
464
479
when we leave that the processor is RUNNING. */
465
480
if (!GST_SIGNAL_PROCESSOR_IS_INITIALIZED (self)
466
481
&& !gst_signal_processor_setup (self, self->sample_rate))
482
goto start_or_setup_failed;
468
483
if (!GST_SIGNAL_PROCESSOR_IS_RUNNING (self)
469
484
&& !gst_signal_processor_start (self))
485
goto start_or_setup_failed;
472
487
gst_object_unref (self);
491
start_or_setup_failed:
478
493
gst_object_unref (self);
501
516
self = GST_SIGNAL_PROCESSOR (gst_pad_get_parent (pad));
502
517
bclass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
504
/* FIXME, this probably isn't the correct interface: what about return values, what
505
* about overriding event_default
519
/* FIXME, this probably isn't the correct interface: what about return values,
520
* what about overriding event_default
506
521
* Sync with GstBaseTransform::gst_base_transform_sink_event */
507
522
if (bclass->event)
508
523
bclass->event (self, event);
545
560
self->audio_in[sinkpad->index] = sinkpad->data;
563
/* FIXME: return if samples_avail==0 ? */
548
565
/* now assign output buffers. we can avoid allocation by reusing input
549
566
buffers, but only if process() can work in place, and if the input buffer
550
567
is the exact size of the number of samples we are processing. */
637
654
GstElement *elem;
638
655
GstSignalProcessorClass *klass;
657
/* check if we have buffers enqueued */
640
658
g_return_if_fail (self->pending_in == 0);
641
659
g_return_if_fail (self->pending_out == 0);
643
661
elem = GST_ELEMENT (self);
663
/* check how much input is available and prepare output buffers */
645
664
nframes = gst_signal_processor_prepare (self, nframes);
646
665
if (G_UNLIKELY (nframes == 0))
705
724
GST_INFO_OBJECT (self, "flush()");
726
/* release enqueued buffers */
707
727
for (pads = GST_ELEMENT (self)->pads; pads; pads = pads->next) {
708
728
GstSignalProcessorPad *spad = (GstSignalProcessorPad *) pads->data;
863
884
return self->flow_state;
867
gst_signal_processor_set_property (GObject * object, guint prop_id,
868
const GValue * value, GParamSpec * pspec)
870
/* GstSignalProcessor *self = GST_SIGNAL_PROCESSOR (object); */
874
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
880
gst_signal_processor_get_property (GObject * object, guint prop_id,
881
GValue * value, GParamSpec * pspec)
883
/* GstSignalProcessor *self = GST_SIGNAL_PROCESSOR (object); */
887
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
893
888
gst_signal_processor_sink_activate_push (GstPad * pad, gboolean active)