gstaudiofilter.c 9.42 KB
Newer Older
David Schleef's avatar
David Schleef committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) <2003> David Schleef <ds@schleef.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/*#define DEBUG_ENABLED */
Steve Lhomme Lhomme's avatar
Steve Lhomme Lhomme committed
26
#include "gstaudiofilter.h"
David Schleef's avatar
David Schleef committed
27
28
29
30

#include <string.h>


Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
31
/* GstAudioFilter signals and args */
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
32
33
enum
{
David Schleef's avatar
David Schleef committed
34
35
36
37
  /* FILL ME */
  LAST_SIGNAL
};

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
38
39
enum
{
David Schleef's avatar
David Schleef committed
40
  ARG_0,
41
42
  ARG_METHOD
      /* FILL ME */
David Schleef's avatar
David Schleef committed
43
44
};

45
46
47
static void gst_audio_filter_base_init (gpointer g_class);
static void gst_audio_filter_class_init (gpointer g_class, gpointer class_data);
static void gst_audio_filter_init (GTypeInstance * instance, gpointer g_class);
David Schleef's avatar
David Schleef committed
48

49
static void gst_audio_filter_set_property (GObject * object, guint prop_id,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
50
    const GValue * value, GParamSpec * pspec);
51
static void gst_audio_filter_get_property (GObject * object, guint prop_id,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
52
    GValue * value, GParamSpec * pspec);
David Schleef's avatar
David Schleef committed
53

54
static GstFlowReturn gst_audio_filter_chain (GstPad * pad, GstBuffer * buffer);
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
55
GstCaps *gst_audio_filter_class_get_capslist (GstAudioFilterClass * klass);
David Schleef's avatar
David Schleef committed
56
57
58
59

static GstElementClass *parent_class = NULL;

GType
60
gst_audio_filter_get_type (void)
David Schleef's avatar
David Schleef committed
61
{
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
62
  static GType audio_filter_type = 0;
David Schleef's avatar
David Schleef committed
63

Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
64
65
66
  if (!audio_filter_type) {
    static const GTypeInfo audio_filter_info = {
      sizeof (GstAudioFilterClass),
67
      gst_audio_filter_base_init,
David Schleef's avatar
David Schleef committed
68
      NULL,
69
      gst_audio_filter_class_init,
David Schleef's avatar
David Schleef committed
70
71
      NULL,
      NULL,
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
72
      sizeof (GstAudioFilter),
David Schleef's avatar
David Schleef committed
73
      0,
74
      gst_audio_filter_init,
David Schleef's avatar
David Schleef committed
75
    };
76

Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
77
78
    audio_filter_type = g_type_register_static (GST_TYPE_ELEMENT,
        "GstAudioFilter", &audio_filter_info, G_TYPE_FLAG_ABSTRACT);
David Schleef's avatar
David Schleef committed
79
  }
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
80
  return audio_filter_type;
David Schleef's avatar
David Schleef committed
81
82
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
83
static void
84
gst_audio_filter_base_init (gpointer g_class)
David Schleef's avatar
David Schleef committed
85
{
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
86
  static GstElementDetails audio_filter_details = {
David Schleef's avatar
David Schleef committed
87
88
89
90
91
    "Audio filter base class",
    "Filter/Effect/Audio",
    "Filters audio",
    "David Schleef <ds@schleef.org>"
  };
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
92
  GstAudioFilterClass *klass = (GstAudioFilterClass *) g_class;
David Schleef's avatar
David Schleef committed
93
94
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
95
  gst_element_class_set_details (element_class, &audio_filter_details);
David Schleef's avatar
David Schleef committed
96
97
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
98
static void
99
gst_audio_filter_class_init (gpointer g_class, gpointer class_data)
David Schleef's avatar
David Schleef committed
100
101
102
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
103
  GstAudioFilterClass *klass;
David Schleef's avatar
David Schleef committed
104

Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
105
  klass = (GstAudioFilterClass *) g_class;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
106
107
  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
David Schleef's avatar
David Schleef committed
108

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
109
  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
David Schleef's avatar
David Schleef committed
110

111
112
  gobject_class->set_property = gst_audio_filter_set_property;
  gobject_class->get_property = gst_audio_filter_get_property;
David Schleef's avatar
David Schleef committed
113
114
115
}

static GstPadLinkReturn
116
gst_audio_filter_link (GstPad * pad, GstPad * peer)
David Schleef's avatar
David Schleef committed
117
{
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
118
  GstAudioFilter *audiofilter;
119
120
121
122

  //GstPadLinkReturn ret;
  //GstPadLinkReturn link_ret;
  //GstStructure *structure;
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
123
  GstAudioFilterClass *audio_filter_class;
David Schleef's avatar
David Schleef committed
124

125
126
  GST_DEBUG ("gst_audio_filter_link");
  audiofilter = GST_AUDIO_FILTER (gst_pad_get_parent (pad));
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
127
128
  audio_filter_class =
      GST_AUDIO_FILTER_CLASS (G_OBJECT_GET_CLASS (audiofilter));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
129

130
#if 0
131
  ret = GST_PAD_LINK_DELAYED;   /* intialise with dummy value */
David Schleef's avatar
David Schleef committed
132
133
134
135
136
137
  if (pad == audiofilter->srcpad) {
    link_ret = gst_pad_try_set_caps (audiofilter->sinkpad, caps);
  } else {
    link_ret = gst_pad_try_set_caps (audiofilter->srcpad, caps);
  }

David Schleef's avatar
David Schleef committed
138
  if (GST_PAD_LINK_FAILED (link_ret)) {
139
    gst_object_unref (audiofilter);
David Schleef's avatar
David Schleef committed
140
141
    return link_ret;
  }
David Schleef's avatar
David Schleef committed
142
143
144
145
146
147
148
149

  structure = gst_caps_get_structure (caps, 0);

  if (strcmp (gst_structure_get_name (structure), "audio/x-raw-int") == 0) {
    ret = gst_structure_get_int (structure, "depth", &audiofilter->depth);
    ret &= gst_structure_get_int (structure, "width", &audiofilter->width);
  } else if (strcmp (gst_structure_get_name (structure), "audio/x-raw-float")
      == 0) {
150
    ret &= gst_structure_get_int (structure, "width", &audiofilter->width);
David Schleef's avatar
David Schleef committed
151
  } else {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
152
    g_assert_not_reached ();
David Schleef's avatar
David Schleef committed
153
154
  }
  ret &= gst_structure_get_int (structure, "rate", &audiofilter->rate);
155
156
  ret &= gst_structure_get_int (structure, "channels", &audiofilter->channels);

157
158
  if (!ret) {
    gst_object_unref (audiofilter);
159
    return GST_PAD_LINK_REFUSED;
160
  }
David Schleef's avatar
David Schleef committed
161

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
162
163
  audiofilter->bytes_per_sample = (audiofilter->width / 8) *
      audiofilter->channels;
164

Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
165
166
  if (audio_filter_class->setup)
    (audio_filter_class->setup) (audiofilter);
167
#endif
David Schleef's avatar
David Schleef committed
168

169
  gst_object_unref (audiofilter);
David Schleef's avatar
David Schleef committed
170
171
172
173
  return GST_PAD_LINK_OK;
}

static void
174
gst_audio_filter_init (GTypeInstance * instance, gpointer g_class)
David Schleef's avatar
David Schleef committed
175
{
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
176
  GstAudioFilter *audiofilter = GST_AUDIO_FILTER (instance);
David Schleef's avatar
David Schleef committed
177
178
  GstPadTemplate *pad_template;

179
  GST_DEBUG ("gst_audio_filter_init");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
180
181
182
183
184
185

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
  g_return_if_fail (pad_template != NULL);
  audiofilter->sinkpad = gst_pad_new_from_template (pad_template, "sink");
  gst_element_add_pad (GST_ELEMENT (audiofilter), audiofilter->sinkpad);
186
187
  gst_pad_set_chain_function (audiofilter->sinkpad, gst_audio_filter_chain);
  gst_pad_set_link_function (audiofilter->sinkpad, gst_audio_filter_link);
188
  //gst_pad_set_getcaps_function (audiofilter->sinkpad, gst_pad_proxy_getcaps);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
189
190
191
192
193
194

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
  g_return_if_fail (pad_template != NULL);
  audiofilter->srcpad = gst_pad_new_from_template (pad_template, "src");
  gst_element_add_pad (GST_ELEMENT (audiofilter), audiofilter->srcpad);
195
  gst_pad_set_link_function (audiofilter->srcpad, gst_audio_filter_link);
196
  //gst_pad_set_getcaps_function (audiofilter->srcpad, gst_pad_proxy_getcaps);
David Schleef's avatar
David Schleef committed
197
198
199
200

  audiofilter->inited = FALSE;
}

201
static GstFlowReturn
202
gst_audio_filter_chain (GstPad * pad, GstBuffer * buffer)
David Schleef's avatar
David Schleef committed
203
{
204
  GstBuffer *inbuf = GST_BUFFER (buffer);
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
205
  GstAudioFilter *audiofilter;
David Schleef's avatar
David Schleef committed
206
  GstBuffer *outbuf;
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
207
  GstAudioFilterClass *audio_filter_class;
David Schleef's avatar
David Schleef committed
208

209
  GST_DEBUG ("gst_audio_filter_chain");
David Schleef's avatar
David Schleef committed
210

211
212
213
  g_return_val_if_fail (pad != NULL, GST_FLOW_ERROR);
  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
  g_return_val_if_fail (inbuf != NULL, GST_FLOW_ERROR);
David Schleef's avatar
David Schleef committed
214

215
  audiofilter = GST_AUDIO_FILTER (gst_pad_get_parent (pad));
216
  /* g_return_if_fail (audiofilter->inited); */
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
217
218
  audio_filter_class =
      GST_AUDIO_FILTER_CLASS (G_OBJECT_GET_CLASS (audiofilter));
David Schleef's avatar
David Schleef committed
219

220
  GST_DEBUG ("gst_audio_filter_chain: got buffer of %d bytes in '%s'",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
221
222
223
      GST_BUFFER_SIZE (inbuf), GST_OBJECT_NAME (audiofilter));

  if (audiofilter->passthru) {
224
    gst_pad_push (audiofilter->srcpad, buffer);
225
    gst_object_unref (audiofilter);
226
    return GST_FLOW_OK;
David Schleef's avatar
David Schleef committed
227
228
  }

229
230
231
  audiofilter->size = GST_BUFFER_SIZE (inbuf);
  audiofilter->n_samples = audiofilter->size / audiofilter->bytes_per_sample;

232
  if (gst_buffer_is_writable (buffer)) {
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
233
234
    if (audio_filter_class->filter_inplace) {
      (audio_filter_class->filter_inplace) (audiofilter, inbuf);
David Schleef's avatar
David Schleef committed
235
236
      outbuf = inbuf;
    } else {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
237
238
239
      outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (inbuf));
      GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
      GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
David Schleef's avatar
David Schleef committed
240

Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
241
      (audio_filter_class->filter) (audiofilter, outbuf, inbuf);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
242
      gst_buffer_unref (inbuf);
David Schleef's avatar
David Schleef committed
243
244
    }
  } else {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
245
246
247
    outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (inbuf));
    GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
    GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
248
249
    if (audio_filter_class->filter) {
      (audio_filter_class->filter) (audiofilter, outbuf, inbuf);
David Schleef's avatar
David Schleef committed
250
    } else {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
251
      memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf),
252
          GST_BUFFER_SIZE (inbuf));
David Schleef's avatar
David Schleef committed
253

Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
254
      (audio_filter_class->filter_inplace) (audiofilter, outbuf);
David Schleef's avatar
David Schleef committed
255
    }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
256
    gst_buffer_unref (inbuf);
David Schleef's avatar
David Schleef committed
257
258
  }

259
260
  gst_pad_push (audiofilter->srcpad, outbuf);

261
  gst_object_unref (audiofilter);
262
  return GST_FLOW_OK;
David Schleef's avatar
David Schleef committed
263
264
265
}

static void
266
gst_audio_filter_set_property (GObject * object, guint prop_id,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
267
    const GValue * value, GParamSpec * pspec)
David Schleef's avatar
David Schleef committed
268
{
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
269
  GstAudioFilter *src;
David Schleef's avatar
David Schleef committed
270

271
272
  g_return_if_fail (GST_IS_AUDIO_FILTER (object));
  src = GST_AUDIO_FILTER (object);
David Schleef's avatar
David Schleef committed
273

274
  GST_DEBUG ("gst_audio_filter_set_property");
David Schleef's avatar
David Schleef committed
275
276
277
278
279
280
281
  switch (prop_id) {
    default:
      break;
  }
}

static void
282
gst_audio_filter_get_property (GObject * object, guint prop_id, GValue * value,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
283
    GParamSpec * pspec)
David Schleef's avatar
David Schleef committed
284
{
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
285
  GstAudioFilter *src;
David Schleef's avatar
David Schleef committed
286

287
288
  g_return_if_fail (GST_IS_AUDIO_FILTER (object));
  src = GST_AUDIO_FILTER (object);
David Schleef's avatar
David Schleef committed
289
290
291
292
293
294
295
296

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
297
void
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
298
299
gst_audio_filter_class_add_pad_templates (GstAudioFilterClass *
    audio_filter_class, const GstCaps * caps)
David Schleef's avatar
David Schleef committed
300
{
Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
301
  GstElementClass *element_class = GST_ELEMENT_CLASS (audio_filter_class);
David Schleef's avatar
David Schleef committed
302

Thomas Vander Stichele's avatar
borgify    
Thomas Vander Stichele committed
303
  audio_filter_class->caps = gst_caps_copy (caps);
David Schleef's avatar
David Schleef committed
304
305

  gst_element_class_add_pad_template (element_class,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
306
      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
307
          gst_caps_copy (caps)));
David Schleef's avatar
David Schleef committed
308
309

  gst_element_class_add_pad_template (element_class,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
310
      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
311
          gst_caps_copy (caps)));
David Schleef's avatar
David Schleef committed
312
}