• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
3  *
4  * gstaudioparse.c:
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 /**
22  * SECTION:element-audioparse
23  * @title: audioparse
24  *
25  * Converts a byte stream into audio frames.
26  *
27  * This element is deprecated. Use #GstRawAudioParse instead.
28  */
29 
30 #ifdef HAVE_CONFIG_H
31 #  include "config.h"
32 #endif
33 
34 /* FIXME 0.11: suppress warnings for deprecated API such as g_value_array stuff
35  * for now with newer GLib versions (>= 2.31.0) */
36 #define GLIB_DISABLE_DEPRECATION_WARNINGS
37 
38 #include <gst/gst.h>
39 #include <gst/audio/audio.h>
40 #include "gstaudioparse.h"
41 
42 #include <string.h>
43 
44 typedef enum _GstRawAudioParseFormat GstRawAudioParseFormat;
45 enum _GstRawAudioParseFormat
46 {
47   GST_RAW_AUDIO_PARSE_FORMAT_PCM,
48   GST_RAW_AUDIO_PARSE_FORMAT_MULAW,
49   GST_RAW_AUDIO_PARSE_FORMAT_ALAW
50 };
51 
52 static GstStaticPadTemplate static_sink_template =
53 GST_STATIC_PAD_TEMPLATE ("sink",
54     GST_PAD_SINK,
55     GST_PAD_ALWAYS,
56     GST_STATIC_CAPS_ANY);
57 
58 #define GST_UNALIGNED_RAW_AUDIO_CAPS \
59   "audio/x-unaligned-raw" \
60   ", format = (string) " GST_AUDIO_FORMATS_ALL \
61   ", rate = (int) [ 1, MAX ]" \
62   ", channels = (int) [ 1, MAX ]" \
63   ", layout = (string) { interleaved, non-interleaved }"
64 
65 static GstStaticPadTemplate static_src_template =
66     GST_STATIC_PAD_TEMPLATE ("src",
67     GST_PAD_SRC,
68     GST_PAD_ALWAYS,
69     GST_STATIC_CAPS (GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL)
70         ", layout = (string) { interleaved, non-interleaved }; "
71         GST_UNALIGNED_RAW_AUDIO_CAPS "; "
72         "audio/x-alaw, rate=(int)[1,MAX], channels=(int)[1,MAX]; "
73         "audio/x-mulaw, rate=(int)[1,MAX], channels=(int)[1,MAX]")
74     );
75 
76 typedef enum
77 {
78   GST_AUDIO_PARSE_FORMAT_RAW,
79   GST_AUDIO_PARSE_FORMAT_MULAW,
80   GST_AUDIO_PARSE_FORMAT_ALAW
81 } GstAudioParseFormat;
82 
83 static void gst_audio_parse_set_property (GObject * object, guint prop_id,
84     const GValue * value, GParamSpec * pspec);
85 static void gst_audio_parse_get_property (GObject * object, guint prop_id,
86     GValue * value, GParamSpec * pspec);
87 
88 GST_DEBUG_CATEGORY_STATIC (gst_audio_parse_debug);
89 #define GST_CAT_DEFAULT gst_audio_parse_debug
90 
91 enum
92 {
93   PROP_0,
94   PROP_FORMAT,
95   PROP_RAW_FORMAT,
96   PROP_RATE,
97   PROP_CHANNELS,
98   PROP_INTERLEAVED,
99   PROP_CHANNEL_POSITIONS,
100   PROP_USE_SINK_CAPS
101 };
102 
103 #define GST_AUDIO_PARSE_FORMAT (gst_audio_parse_format_get_type ())
104 static GType
gst_audio_parse_format_get_type(void)105 gst_audio_parse_format_get_type (void)
106 {
107   static GType audio_parse_format_type = 0;
108   static const GEnumValue format_types[] = {
109     {GST_AUDIO_PARSE_FORMAT_RAW, "Raw", "raw"},
110     {GST_AUDIO_PARSE_FORMAT_ALAW, "A-Law", "alaw"},
111     {GST_AUDIO_PARSE_FORMAT_MULAW, "\302\265-Law", "mulaw"},
112     {0, NULL, NULL}
113   };
114 
115   if (!audio_parse_format_type) {
116     audio_parse_format_type =
117         g_enum_register_static ("GstAudioParseFormat", format_types);
118   }
119 
120   return audio_parse_format_type;
121 }
122 
123 #define gst_audio_parse_parent_class parent_class
124 G_DEFINE_TYPE (GstAudioParse, gst_audio_parse, GST_TYPE_BIN);
125 GST_ELEMENT_REGISTER_DEFINE (audioparse, "audioparse", GST_RANK_NONE,
126     gst_audio_parse_get_type ());
127 
128 static void
gst_audio_parse_class_init(GstAudioParseClass * klass)129 gst_audio_parse_class_init (GstAudioParseClass * klass)
130 {
131   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
132   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
133 
134   gobject_class->set_property = gst_audio_parse_set_property;
135   gobject_class->get_property = gst_audio_parse_get_property;
136 
137   g_object_class_install_property (gobject_class, PROP_FORMAT,
138       g_param_spec_enum ("format", "Format",
139           "Format of audio samples in raw stream", GST_AUDIO_PARSE_FORMAT,
140           GST_AUDIO_PARSE_FORMAT_RAW,
141           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
142 
143   g_object_class_install_property (gobject_class, PROP_RAW_FORMAT,
144       g_param_spec_enum ("raw-format", "Raw Format",
145           "Format of audio samples in raw stream", GST_TYPE_AUDIO_FORMAT,
146           GST_AUDIO_FORMAT_S16, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
147 
148   g_object_class_install_property (gobject_class, PROP_RATE,
149       g_param_spec_int ("rate", "Rate", "Rate of audio samples in raw stream",
150           1, INT_MAX, 44100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
151 
152   g_object_class_install_property (gobject_class, PROP_CHANNELS,
153       g_param_spec_int ("channels", "Channels",
154           "Number of channels in raw stream", 1, 64, 2,
155           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
156 
157   g_object_class_install_property (gobject_class, PROP_INTERLEAVED,
158       g_param_spec_boolean ("interleaved", "Interleaved Layout",
159           "True if audio has interleaved layout", TRUE,
160           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
161 
162   g_object_class_install_property (gobject_class, PROP_CHANNEL_POSITIONS,
163       g_param_spec_value_array ("channel-positions", "Channel positions",
164           "Channel positions used on the output",
165           g_param_spec_enum ("channel-position", "Channel position",
166               "Channel position of the n-th input",
167               GST_TYPE_AUDIO_CHANNEL_POSITION,
168               GST_AUDIO_CHANNEL_POSITION_NONE,
169               G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
170           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
171 
172   g_object_class_install_property (gobject_class, PROP_USE_SINK_CAPS,
173       g_param_spec_boolean ("use-sink-caps", "Use sink caps",
174           "Use the sink caps for the format, only performing timestamping",
175           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
176 
177   gst_element_class_set_static_metadata (gstelement_class, "Audio Parse",
178       "Filter/Audio",
179       "Converts stream into audio frames (deprecated: use rawaudioparse instead)",
180       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
181 
182   gst_element_class_add_pad_template (gstelement_class,
183       gst_static_pad_template_get (&static_sink_template));
184   gst_element_class_add_pad_template (gstelement_class,
185       gst_static_pad_template_get (&static_src_template));
186 
187   GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0,
188       "audioparse element");
189 
190   gst_type_mark_as_plugin_api (GST_AUDIO_PARSE_FORMAT, 0);
191 }
192 
193 static void
gst_audio_parse_init(GstAudioParse * ap)194 gst_audio_parse_init (GstAudioParse * ap)
195 {
196   GstPad *inner_pad;
197   GstPad *ghostpad;
198 
199   ap->rawaudioparse =
200       gst_element_factory_make ("rawaudioparse", "inner_rawaudioparse");
201   g_assert (ap->rawaudioparse != NULL);
202 
203   gst_bin_add (GST_BIN (ap), ap->rawaudioparse);
204 
205   inner_pad = gst_element_get_static_pad (ap->rawaudioparse, "sink");
206   ghostpad =
207       gst_ghost_pad_new_from_template ("sink", inner_pad,
208       gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (ap), "sink"));
209   gst_element_add_pad (GST_ELEMENT (ap), ghostpad);
210   gst_object_unref (GST_OBJECT (inner_pad));
211 
212   inner_pad = gst_element_get_static_pad (ap->rawaudioparse, "src");
213   ghostpad =
214       gst_ghost_pad_new_from_template ("src", inner_pad,
215       gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (ap), "src"));
216   gst_element_add_pad (GST_ELEMENT (ap), ghostpad);
217   gst_object_unref (GST_OBJECT (inner_pad));
218 }
219 
220 static void
gst_audio_parse_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)221 gst_audio_parse_set_property (GObject * object, guint prop_id,
222     const GValue * value, GParamSpec * pspec)
223 {
224   GstAudioParse *ap = GST_AUDIO_PARSE (object);
225 
226   switch (prop_id) {
227     case PROP_FORMAT:{
228       GstRawAudioParseFormat raw_parse_format;
229 
230       switch (g_value_get_enum (value)) {
231         case GST_AUDIO_PARSE_FORMAT_RAW:
232           raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_PCM;
233           break;
234 
235         case GST_AUDIO_PARSE_FORMAT_MULAW:
236           raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_MULAW;
237           break;
238 
239         case GST_AUDIO_PARSE_FORMAT_ALAW:
240           raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_ALAW;
241           break;
242 
243         default:
244           g_assert_not_reached ();
245           break;
246       }
247 
248       g_object_set (G_OBJECT (ap->rawaudioparse), "format", raw_parse_format,
249           NULL);
250 
251       break;
252     }
253 
254     case PROP_RAW_FORMAT:
255       g_object_set (G_OBJECT (ap->rawaudioparse), "pcm-format",
256           g_value_get_enum (value), NULL);
257       break;
258 
259     case PROP_RATE:
260       g_object_set (G_OBJECT (ap->rawaudioparse), "sample-rate",
261           g_value_get_int (value), NULL);
262       break;
263 
264     case PROP_CHANNELS:
265       g_object_set (G_OBJECT (ap->rawaudioparse), "num-channels",
266           g_value_get_int (value), NULL);
267       break;
268 
269     case PROP_INTERLEAVED:
270       g_object_set (G_OBJECT (ap->rawaudioparse), "interleaved",
271           g_value_get_boolean (value), NULL);
272       break;
273 
274     case PROP_CHANNEL_POSITIONS:
275       g_object_set (G_OBJECT (ap->rawaudioparse), "channel-positions",
276           g_value_get_boxed (value), NULL);
277       break;
278 
279     case PROP_USE_SINK_CAPS:
280       g_object_set (G_OBJECT (ap->rawaudioparse), "use-sink-caps",
281           g_value_get_boolean (value), NULL);
282       break;
283 
284     default:
285       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
286       break;
287   }
288 }
289 
290 static void
gst_audio_parse_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)291 gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value,
292     GParamSpec * pspec)
293 {
294   GstAudioParse *ap = GST_AUDIO_PARSE (object);
295 
296   switch (prop_id) {
297     case PROP_FORMAT:{
298       GstRawAudioParseFormat raw_parse_format;
299       GstAudioParseFormat format;
300 
301       g_object_get (G_OBJECT (ap->rawaudioparse), "format", &raw_parse_format,
302           NULL);
303 
304       switch (raw_parse_format) {
305         case GST_RAW_AUDIO_PARSE_FORMAT_PCM:
306           format = GST_AUDIO_PARSE_FORMAT_RAW;
307           break;
308 
309         case GST_RAW_AUDIO_PARSE_FORMAT_MULAW:
310           format = GST_AUDIO_PARSE_FORMAT_MULAW;
311           break;
312 
313         case GST_RAW_AUDIO_PARSE_FORMAT_ALAW:
314           format = GST_AUDIO_PARSE_FORMAT_ALAW;
315           break;
316 
317         default:
318           g_assert_not_reached ();
319           break;
320       }
321 
322       g_value_set_enum (value, format);
323 
324       break;
325     }
326 
327     case PROP_RAW_FORMAT:{
328       GstAudioFormat format;
329       g_object_get (G_OBJECT (ap->rawaudioparse), "pcm-format", &format, NULL);
330       g_value_set_enum (value, format);
331       break;
332     }
333 
334     case PROP_RATE:{
335       gint sample_rate;
336       g_object_get (G_OBJECT (ap->rawaudioparse), "sample-rate", &sample_rate,
337           NULL);
338       g_value_set_int (value, sample_rate);
339       break;
340     }
341 
342     case PROP_CHANNELS:{
343       gint num_channels;
344       g_object_get (G_OBJECT (ap->rawaudioparse), "num-channels", &num_channels,
345           NULL);
346       g_value_set_int (value, num_channels);
347       break;
348     }
349 
350     case PROP_INTERLEAVED:{
351       gboolean interleaved;
352       g_object_get (G_OBJECT (ap->rawaudioparse), "interleaved", &interleaved,
353           NULL);
354       g_value_set_boolean (value, interleaved);
355       break;
356     }
357 
358     case PROP_CHANNEL_POSITIONS:{
359       gpointer channel_positions;
360       g_object_get (G_OBJECT (ap->rawaudioparse), "channel-positions",
361           &channel_positions, NULL);
362       g_value_set_boxed (value, channel_positions);
363       break;
364     }
365 
366     case PROP_USE_SINK_CAPS:{
367       gboolean use_sink_caps;
368       g_object_get (G_OBJECT (ap->rawaudioparse), "use-sink-caps",
369           &use_sink_caps, NULL);
370       g_value_set_boolean (value, use_sink_caps);
371       break;
372     }
373 
374     default:
375       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
376       break;
377   }
378 }
379