• 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 
126 static void
gst_audio_parse_class_init(GstAudioParseClass * klass)127 gst_audio_parse_class_init (GstAudioParseClass * klass)
128 {
129   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
130   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
131 
132   gobject_class->set_property = gst_audio_parse_set_property;
133   gobject_class->get_property = gst_audio_parse_get_property;
134 
135   g_object_class_install_property (gobject_class, PROP_FORMAT,
136       g_param_spec_enum ("format", "Format",
137           "Format of audio samples in raw stream", GST_AUDIO_PARSE_FORMAT,
138           GST_AUDIO_PARSE_FORMAT_RAW,
139           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
140 
141   g_object_class_install_property (gobject_class, PROP_RAW_FORMAT,
142       g_param_spec_enum ("raw-format", "Raw Format",
143           "Format of audio samples in raw stream", GST_TYPE_AUDIO_FORMAT,
144           GST_AUDIO_FORMAT_S16, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
145 
146   g_object_class_install_property (gobject_class, PROP_RATE,
147       g_param_spec_int ("rate", "Rate", "Rate of audio samples in raw stream",
148           1, INT_MAX, 44100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
149 
150   g_object_class_install_property (gobject_class, PROP_CHANNELS,
151       g_param_spec_int ("channels", "Channels",
152           "Number of channels in raw stream", 1, 64, 2,
153           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
154 
155   g_object_class_install_property (gobject_class, PROP_INTERLEAVED,
156       g_param_spec_boolean ("interleaved", "Interleaved Layout",
157           "True if audio has interleaved layout", TRUE,
158           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
159 
160   g_object_class_install_property (gobject_class, PROP_CHANNEL_POSITIONS,
161       g_param_spec_value_array ("channel-positions", "Channel positions",
162           "Channel positions used on the output",
163           g_param_spec_enum ("channel-position", "Channel position",
164               "Channel position of the n-th input",
165               GST_TYPE_AUDIO_CHANNEL_POSITION,
166               GST_AUDIO_CHANNEL_POSITION_NONE,
167               G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
168           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
169 
170   g_object_class_install_property (gobject_class, PROP_USE_SINK_CAPS,
171       g_param_spec_boolean ("use-sink-caps", "Use sink caps",
172           "Use the sink caps for the format, only performing timestamping",
173           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
174 
175   gst_element_class_set_static_metadata (gstelement_class, "Audio Parse",
176       "Filter/Audio",
177       "Converts stream into audio frames (deprecated: use rawaudioparse instead)",
178       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
179 
180   gst_element_class_add_pad_template (gstelement_class,
181       gst_static_pad_template_get (&static_sink_template));
182   gst_element_class_add_pad_template (gstelement_class,
183       gst_static_pad_template_get (&static_src_template));
184 
185   GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0,
186       "audioparse element");
187 }
188 
189 static void
gst_audio_parse_init(GstAudioParse * ap)190 gst_audio_parse_init (GstAudioParse * ap)
191 {
192   GstPad *inner_pad;
193   GstPad *ghostpad;
194 
195   ap->rawaudioparse =
196       gst_element_factory_make ("rawaudioparse", "inner_rawaudioparse");
197   g_assert (ap->rawaudioparse != NULL);
198 
199   gst_bin_add (GST_BIN (ap), ap->rawaudioparse);
200 
201   inner_pad = gst_element_get_static_pad (ap->rawaudioparse, "sink");
202   ghostpad =
203       gst_ghost_pad_new_from_template ("sink", inner_pad,
204       gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (ap), "sink"));
205   gst_element_add_pad (GST_ELEMENT (ap), ghostpad);
206   gst_object_unref (GST_OBJECT (inner_pad));
207 
208   inner_pad = gst_element_get_static_pad (ap->rawaudioparse, "src");
209   ghostpad =
210       gst_ghost_pad_new_from_template ("src", inner_pad,
211       gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (ap), "src"));
212   gst_element_add_pad (GST_ELEMENT (ap), ghostpad);
213   gst_object_unref (GST_OBJECT (inner_pad));
214 }
215 
216 static void
gst_audio_parse_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)217 gst_audio_parse_set_property (GObject * object, guint prop_id,
218     const GValue * value, GParamSpec * pspec)
219 {
220   GstAudioParse *ap = GST_AUDIO_PARSE (object);
221 
222   switch (prop_id) {
223     case PROP_FORMAT:{
224       GstRawAudioParseFormat raw_parse_format;
225 
226       switch (g_value_get_enum (value)) {
227         case GST_AUDIO_PARSE_FORMAT_RAW:
228           raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_PCM;
229           break;
230 
231         case GST_AUDIO_PARSE_FORMAT_MULAW:
232           raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_MULAW;
233           break;
234 
235         case GST_AUDIO_PARSE_FORMAT_ALAW:
236           raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_ALAW;
237           break;
238 
239         default:
240           g_assert_not_reached ();
241           break;
242       }
243 
244       g_object_set (G_OBJECT (ap->rawaudioparse), "format", raw_parse_format,
245           NULL);
246 
247       break;
248     }
249 
250     case PROP_RAW_FORMAT:
251       g_object_set (G_OBJECT (ap->rawaudioparse), "pcm-format",
252           g_value_get_enum (value), NULL);
253       break;
254 
255     case PROP_RATE:
256       g_object_set (G_OBJECT (ap->rawaudioparse), "sample-rate",
257           g_value_get_int (value), NULL);
258       break;
259 
260     case PROP_CHANNELS:
261       g_object_set (G_OBJECT (ap->rawaudioparse), "num-channels",
262           g_value_get_int (value), NULL);
263       break;
264 
265     case PROP_INTERLEAVED:
266       g_object_set (G_OBJECT (ap->rawaudioparse), "interleaved",
267           g_value_get_boolean (value), NULL);
268       break;
269 
270     case PROP_CHANNEL_POSITIONS:
271       g_object_set (G_OBJECT (ap->rawaudioparse), "channel-positions",
272           g_value_get_boxed (value), NULL);
273       break;
274 
275     case PROP_USE_SINK_CAPS:
276       g_object_set (G_OBJECT (ap->rawaudioparse), "use-sink-caps",
277           g_value_get_boolean (value), NULL);
278       break;
279 
280     default:
281       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
282       break;
283   }
284 }
285 
286 static void
gst_audio_parse_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)287 gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value,
288     GParamSpec * pspec)
289 {
290   GstAudioParse *ap = GST_AUDIO_PARSE (object);
291 
292   switch (prop_id) {
293     case PROP_FORMAT:{
294       GstRawAudioParseFormat raw_parse_format;
295       GstAudioParseFormat format;
296 
297       g_object_get (G_OBJECT (ap->rawaudioparse), "format", &raw_parse_format,
298           NULL);
299 
300       switch (raw_parse_format) {
301         case GST_RAW_AUDIO_PARSE_FORMAT_PCM:
302           format = GST_AUDIO_PARSE_FORMAT_RAW;
303           break;
304 
305         case GST_RAW_AUDIO_PARSE_FORMAT_MULAW:
306           format = GST_AUDIO_PARSE_FORMAT_MULAW;
307           break;
308 
309         case GST_RAW_AUDIO_PARSE_FORMAT_ALAW:
310           format = GST_AUDIO_PARSE_FORMAT_ALAW;
311           break;
312 
313         default:
314           g_assert_not_reached ();
315           break;
316       }
317 
318       g_value_set_enum (value, format);
319 
320       break;
321     }
322 
323     case PROP_RAW_FORMAT:{
324       GstAudioFormat format;
325       g_object_get (G_OBJECT (ap->rawaudioparse), "pcm-format", &format, NULL);
326       g_value_set_enum (value, format);
327       break;
328     }
329 
330     case PROP_RATE:{
331       gint sample_rate;
332       g_object_get (G_OBJECT (ap->rawaudioparse), "sample-rate", &sample_rate,
333           NULL);
334       g_value_set_int (value, sample_rate);
335       break;
336     }
337 
338     case PROP_CHANNELS:{
339       gint num_channels;
340       g_object_get (G_OBJECT (ap->rawaudioparse), "num-channels", &num_channels,
341           NULL);
342       g_value_set_int (value, num_channels);
343       break;
344     }
345 
346     case PROP_INTERLEAVED:{
347       gboolean interleaved;
348       g_object_get (G_OBJECT (ap->rawaudioparse), "interleaved", &interleaved,
349           NULL);
350       g_value_set_boolean (value, interleaved);
351       break;
352     }
353 
354     case PROP_CHANNEL_POSITIONS:{
355       gpointer channel_positions;
356       g_object_get (G_OBJECT (ap->rawaudioparse), "channel-positions",
357           &channel_positions, NULL);
358       g_value_set_boxed (value, channel_positions);
359       break;
360     }
361 
362     case PROP_USE_SINK_CAPS:{
363       gboolean use_sink_caps;
364       g_object_get (G_OBJECT (ap->rawaudioparse), "use-sink-caps",
365           &use_sink_caps, NULL);
366       g_value_set_boolean (value, use_sink_caps);
367       break;
368     }
369 
370     default:
371       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
372       break;
373   }
374 }
375