~ubuntu-branches/ubuntu/precise/gst-plugins-bad0.10/precise-proposed

« back to all changes in this revision

Viewing changes to ext/ladspa/gstsignalprocessor.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2009-05-12 09:51:24 UTC
  • mto: (18.3.2 experimental) (1.3.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 31.
  • Revision ID: james.westby@ubuntu.com-20090512095124-ugy051q0n88kk9f8
Tags: upstream-0.10.11.2
Import upstream version 0.10.11.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * Boston, MA 02111-1307, USA.
22
22
 */
23
23
 
 
24
/*
 
25
 * SECTION:gstsignalprocessor
 
26
 *
 
27
 * This baseclass allows to write elements that need data on all pads before
 
28
 * their processing function can run.
 
29
 *
 
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
 
33
 *
 
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
 
37
 *    the buffer
 
38
 */
24
39
 
25
40
#include <stdlib.h>
26
41
 
71
86
  return type;
72
87
}
73
88
 
74
 
/* FIXME: better allow the caller to pass on the template, right now this can
75
 
 * only create mono pads */
 
89
/*
 
90
 * gst_signal_processor_class_add_pad_template:
 
91
 * @klass: element class
 
92
 * @name: pad name
 
93
 * @direction: pad direction (src/sink)
 
94
 * @index: index for the pad per direction (starting from 0)
 
95
 *
 
96
 */
76
97
void
77
98
gst_signal_processor_class_add_pad_template (GstSignalProcessorClass * klass,
78
99
    const gchar * name, GstPadDirection direction, guint index)
79
100
{
80
101
  GstPadTemplate *new;
 
102
  GstCaps *caps;
81
103
 
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);
85
107
 
 
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));
 
111
 
86
112
  new = g_object_new (gst_signal_processor_pad_template_get_type (),
87
 
      "name", name, NULL);
 
113
      "name", name, "name-template", name,
 
114
      "direction", direction, "presence", GST_PAD_ALWAYS, "caps", caps, NULL);
88
115
 
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
93
 
      (&template_caps));
94
116
  GST_SIGNAL_PROCESSOR_PAD_TEMPLATE (new)->index = index;
95
117
 
96
118
  gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), new);
110
132
 
111
133
  GstBuffer *pen;
112
134
 
 
135
  /* index for the pad per direction (starting from 0) */
113
136
  guint index;
114
137
 
115
138
  /* these are only used for sink pads */
116
 
  guint samples_avail;
117
 
  gfloat *data;
 
139
  guint samples_avail;          /* available mono sample frames */
 
140
  gfloat *data;                 /* data pointer to read from / write to */
118
141
};
119
142
 
120
143
static GType
140
163
 
141
164
 
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);
177
196
 
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);
183
198
 
184
199
  gstelement_class->change_state =
185
200
      GST_DEBUG_FUNCPTR (gst_signal_processor_change_state);
345
360
    klass->stop (self);
346
361
 
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);
350
365
 
351
366
  /* should also flush our buffers perhaps? */
449
464
      gst_signal_processor_cleanup (self);
450
465
 
451
466
    if (!gst_signal_processor_setup (self, sample_rate))
452
 
      goto start_failed;
 
467
      goto start_or_setup_failed;
453
468
 
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))
467
 
    goto start_failed;
 
482
    goto start_or_setup_failed;
468
483
  if (!GST_SIGNAL_PROCESSOR_IS_RUNNING (self)
469
484
      && !gst_signal_processor_start (self))
470
 
    goto start_failed;
 
485
    goto start_or_setup_failed;
471
486
 
472
487
  gst_object_unref (self);
473
488
 
474
489
  return TRUE;
475
490
 
476
 
start_failed:
 
491
start_or_setup_failed:
477
492
  {
478
493
    gst_object_unref (self);
479
494
    return FALSE;
501
516
  self = GST_SIGNAL_PROCESSOR (gst_pad_get_parent (pad));
502
517
  bclass = GST_SIGNAL_PROCESSOR_GET_CLASS (self);
503
518
 
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;
546
561
  }
547
562
 
 
563
  /* FIXME: return if samples_avail==0 ? */
 
564
 
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;
639
656
 
 
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);
642
660
 
643
661
  elem = GST_ELEMENT (self);
644
662
 
 
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))
647
666
    goto flow_error;
704
723
 
705
724
  GST_INFO_OBJECT (self, "flush()");
706
725
 
 
726
  /* release enqueued buffers */
707
727
  for (pads = GST_ELEMENT (self)->pads; pads; pads = pads->next) {
708
728
    GstSignalProcessorPad *spad = (GstSignalProcessorPad *) pads->data;
709
729
 
715
735
    }
716
736
  }
717
737
 
 
738
  /* no outputs prepared and inputs for each pad needed */
718
739
  self->pending_out = 0;
719
740
  self->pending_in = klass->num_audio_in;
720
741
}
863
884
  return self->flow_state;
864
885
}
865
886
 
866
 
static void
867
 
gst_signal_processor_set_property (GObject * object, guint prop_id,
868
 
    const GValue * value, GParamSpec * pspec)
869
 
{
870
 
  /* GstSignalProcessor *self = GST_SIGNAL_PROCESSOR (object); */
871
 
 
872
 
  switch (prop_id) {
873
 
    default:
874
 
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
875
 
      break;
876
 
  }
877
 
}
878
 
 
879
 
static void
880
 
gst_signal_processor_get_property (GObject * object, guint prop_id,
881
 
    GValue * value, GParamSpec * pspec)
882
 
{
883
 
  /* GstSignalProcessor *self = GST_SIGNAL_PROCESSOR (object); */
884
 
 
885
 
  switch (prop_id) {
886
 
    default:
887
 
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
888
 
      break;
889
 
  }
890
 
}
891
 
 
892
887
static gboolean
893
888
gst_signal_processor_sink_activate_push (GstPad * pad, gboolean active)
894
889
{