2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 * @short_description: Support library for audio elements
23 * This library contains some helper functions for audio elements.
34 #include <gst/gststructure.h>
37 * gst_audio_info_copy:
38 * @info: a #GstAudioInfo
40 * Copy a GstAudioInfo structure.
42 * Returns: a new #GstAudioInfo. free with gst_audio_info_free.
45 gst_audio_info_copy (const GstAudioInfo * info)
47 return g_slice_dup (GstAudioInfo, info);
51 * gst_audio_info_free:
52 * @info: a #GstAudioInfo
54 * Free a GstAudioInfo structure previously allocated with gst_audio_info_new()
55 * or gst_audio_info_copy().
58 gst_audio_info_free (GstAudioInfo * info)
60 g_slice_free (GstAudioInfo, info);
63 G_DEFINE_BOXED_TYPE (GstAudioInfo, gst_audio_info,
64 (GBoxedCopyFunc) gst_audio_info_copy, (GBoxedFreeFunc) gst_audio_info_free);
69 * Allocate a new #GstAudioInfo that is also initialized with
70 * gst_audio_info_init().
72 * Returns: a new #GstAudioInfo. free with gst_audio_info_free().
75 gst_audio_info_new (void)
79 info = g_slice_new (GstAudioInfo);
80 gst_audio_info_init (info);
86 * gst_audio_info_init:
87 * @info: a #GstAudioInfo
89 * Initialize @info with default values.
92 gst_audio_info_init (GstAudioInfo * info)
94 g_return_if_fail (info != NULL);
96 memset (info, 0, sizeof (GstAudioInfo));
98 info->finfo = gst_audio_format_get_info (GST_AUDIO_FORMAT_UNKNOWN);
100 memset (&info->position, 0xff, sizeof (info->position));
104 * gst_audio_info_set_format:
105 * @info: a #GstAudioInfo
106 * @format: the format
107 * @rate: the samplerate
108 * @channels: the number of channels
109 * @position: the channel positions
111 * Set the default info for the audio info of @format and @rate and @channels.
114 gst_audio_info_set_format (GstAudioInfo * info, GstAudioFormat format,
115 gint rate, gint channels, const GstAudioChannelPosition * position)
117 const GstAudioFormatInfo *finfo;
120 g_return_if_fail (info != NULL);
121 g_return_if_fail (format != GST_AUDIO_FORMAT_UNKNOWN);
123 finfo = gst_audio_format_get_info (format);
126 info->layout = GST_AUDIO_LAYOUT_INTERLEAVED;
129 info->channels = channels;
130 info->bpf = (finfo->width * channels) / 8;
132 memset (&info->position, 0xff, sizeof (info->position));
134 if (!position && channels == 1) {
135 info->position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
137 } else if (!position && channels == 2) {
138 info->position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
139 info->position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
143 || !gst_audio_check_valid_channel_positions (position, channels,
146 g_warning ("Invalid channel positions");
148 memcpy (&info->position, position,
149 info->channels * sizeof (info->position[0]));
150 if (info->position[0] == GST_AUDIO_CHANNEL_POSITION_NONE)
151 info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
156 /* Otherwise a NONE layout */
157 info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
158 for (i = 0; i < MIN (64, channels); i++)
159 info->position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
163 * gst_audio_info_from_caps:
164 * @info: a #GstAudioInfo
167 * Parse @caps and update @info.
169 * Returns: TRUE if @caps could be parsed
172 gst_audio_info_from_caps (GstAudioInfo * info, const GstCaps * caps)
176 GstAudioFormat format;
178 guint64 channel_mask;
180 GstAudioChannelPosition position[64];
182 g_return_val_if_fail (info != NULL, FALSE);
183 g_return_val_if_fail (caps != NULL, FALSE);
184 g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
186 GST_DEBUG ("parsing caps %" GST_PTR_FORMAT, caps);
190 str = gst_caps_get_structure (caps, 0);
192 if (!gst_structure_has_name (str, "audio/x-raw"))
195 if (!(s = gst_structure_get_string (str, "format")))
198 format = gst_audio_format_from_string (s);
199 if (format == GST_AUDIO_FORMAT_UNKNOWN)
202 if (!(s = gst_structure_get_string (str, "layout")))
204 if (g_str_equal (s, "interleaved"))
205 info->layout = GST_AUDIO_LAYOUT_INTERLEAVED;
206 else if (g_str_equal (s, "non-interleaved"))
207 info->layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
211 if (!gst_structure_get_int (str, "rate", &rate))
213 if (!gst_structure_get_int (str, "channels", &channels))
216 if (!gst_structure_get (str, "channel-mask", GST_TYPE_BITMASK, &channel_mask,
219 position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
220 } else if (channels == 2) {
221 position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
222 position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
224 goto no_channel_mask;
226 } else if (channel_mask == 0) {
227 info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
228 for (i = 0; i < MIN (64, channels); i++)
229 position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
231 if (!gst_audio_channel_positions_from_mask (channels, channel_mask,
233 goto invalid_channel_mask;
236 gst_audio_info_set_format (info, format, rate, channels, position);
243 GST_ERROR ("wrong name, expected audio/x-raw");
248 GST_ERROR ("no format given");
253 GST_ERROR ("unknown format given");
258 GST_ERROR ("no layout given");
263 GST_ERROR ("unknown layout given");
268 GST_ERROR ("no rate property given");
273 GST_ERROR ("no channels property given");
278 GST_ERROR ("no channel-mask property given");
281 invalid_channel_mask:
283 GST_ERROR ("Invalid channel mask 0x%016" G_GINT64_MODIFIER
284 "x for %d channels", channel_mask, channels);
290 * gst_audio_info_to_caps:
291 * @info: a #GstAudioInfo
293 * Convert the values of @info into a #GstCaps.
295 * Returns: (transfer full): the new #GstCaps containing the
299 gst_audio_info_to_caps (const GstAudioInfo * info)
306 g_return_val_if_fail (info != NULL, NULL);
307 g_return_val_if_fail (info->finfo != NULL, NULL);
308 g_return_val_if_fail (info->finfo->format != GST_AUDIO_FORMAT_UNKNOWN, NULL);
310 format = gst_audio_format_to_string (info->finfo->format);
311 g_return_val_if_fail (format != NULL, NULL);
313 if (info->layout == GST_AUDIO_LAYOUT_INTERLEAVED)
314 layout = "interleaved";
315 else if (info->layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED)
316 layout = "non-interleaved";
318 g_return_val_if_reached (NULL);
321 if ((flags & GST_AUDIO_FLAG_UNPOSITIONED) && info->channels > 1
322 && info->position[0] != GST_AUDIO_CHANNEL_POSITION_NONE) {
323 flags &= ~GST_AUDIO_FLAG_UNPOSITIONED;
324 g_warning ("Unpositioned audio channel position flag set but "
325 "channel positions present");
326 } else if (!(flags & GST_AUDIO_FLAG_UNPOSITIONED) && info->channels > 1
327 && info->position[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
328 flags |= GST_AUDIO_FLAG_UNPOSITIONED;
329 g_warning ("Unpositioned audio channel position flag not set "
330 "but no channel positions present");
333 caps = gst_caps_new_simple ("audio/x-raw",
334 "format", G_TYPE_STRING, format,
335 "layout", G_TYPE_STRING, layout,
336 "rate", G_TYPE_INT, info->rate,
337 "channels", G_TYPE_INT, info->channels, NULL);
339 if (info->channels > 1
340 || info->position[0] != GST_AUDIO_CHANNEL_POSITION_MONO) {
341 guint64 channel_mask = 0;
343 if ((flags & GST_AUDIO_FLAG_UNPOSITIONED)) {
346 if (!gst_audio_channel_positions_to_mask (info->position, info->channels,
347 TRUE, &channel_mask))
348 goto invalid_channel_positions;
351 if (info->channels == 1
352 && info->position[0] == GST_AUDIO_CHANNEL_POSITION_MONO) {
353 /* Default mono special case */
355 gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
362 invalid_channel_positions:
364 GST_ERROR ("Invalid channel positions");
365 gst_caps_unref (caps);
371 * gst_audio_info_convert:
372 * @info: a #GstAudioInfo
373 * @src_fmt: #GstFormat of the @src_val
374 * @src_val: value to convert
375 * @dest_fmt: #GstFormat of the @dest_val
376 * @dest_val: pointer to destination value
378 * Converts among various #GstFormat types. This function handles
379 * GST_FORMAT_BYTES, GST_FORMAT_TIME, and GST_FORMAT_DEFAULT. For
380 * raw audio, GST_FORMAT_DEFAULT corresponds to audio frames. This
381 * function can be used to handle pad queries of the type GST_QUERY_CONVERT.
383 * Returns: TRUE if the conversion was successful.
386 gst_audio_info_convert (const GstAudioInfo * info,
387 GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
392 GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s (%d) to %s (%d)",
393 src_val, gst_format_get_name (src_fmt), src_fmt,
394 gst_format_get_name (dest_fmt), dest_fmt);
396 if (src_fmt == dest_fmt || src_val == -1) {
401 /* get important info */
402 bpf = GST_AUDIO_INFO_BPF (info);
403 rate = GST_AUDIO_INFO_RATE (info);
405 if (bpf == 0 || rate == 0) {
406 GST_DEBUG ("no rate or bpf configured");
412 case GST_FORMAT_BYTES:
414 case GST_FORMAT_TIME:
415 *dest_val = GST_FRAMES_TO_CLOCK_TIME (src_val / bpf, rate);
417 case GST_FORMAT_DEFAULT:
418 *dest_val = src_val / bpf;
425 case GST_FORMAT_DEFAULT:
427 case GST_FORMAT_TIME:
428 *dest_val = GST_FRAMES_TO_CLOCK_TIME (src_val, rate);
430 case GST_FORMAT_BYTES:
431 *dest_val = src_val * bpf;
438 case GST_FORMAT_TIME:
440 case GST_FORMAT_DEFAULT:
441 *dest_val = GST_CLOCK_TIME_TO_FRAMES (src_val, rate);
443 case GST_FORMAT_BYTES:
444 *dest_val = GST_CLOCK_TIME_TO_FRAMES (src_val, rate);
457 GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, res, *dest_val);