# variables used for enum/marshal generation
glib_enum_headers= \
audio.h \
+ audio-format.h \
+ audio-channels.h \
+ audio-info.h \
gstaudioringbuffer.h
glib_enum_define = GST_AUDIO
libgstaudio_@GST_API_VERSION@_la_SOURCES = \
audio.c \
+ audio-format.c \
+ audio-channels.c \
+ audio-info.c \
gstaudioringbuffer.c \
gstaudioclock.c \
gstaudiocdsrc.c \
libgstaudio_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/audio
libgstaudio_@GST_API_VERSION@include_HEADERS = \
audio.h \
+ audio-format.h \
+ audio-channels.h \
+ audio-info.h \
gstaudioringbuffer.h \
gstaudioclock.h \
gstaudiofilter.h \
--- /dev/null
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * 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.
+ */
+/**
+ * SECTION:gstaudio
+ * @short_description: Support library for audio elements
+ *
+ * This library contains some helper functions for audio elements.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include "audio-channels.h"
+
+static const GstAudioChannelPosition default_channel_order[64] = {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_LFE1,
+ GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_LFE2,
+ GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_TOP_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID,
+ GST_AUDIO_CHANNEL_POSITION_INVALID
+};
+
+static gboolean
+check_valid_channel_positions (const GstAudioChannelPosition * position,
+ gint channels, gboolean enforce_order, guint64 * channel_mask_out)
+{
+ gint i, j;
+ guint64 channel_mask = 0;
+
+ if (channels == 1 && position[0] == GST_AUDIO_CHANNEL_POSITION_MONO) {
+ if (channel_mask_out)
+ *channel_mask_out = 0;
+ return TRUE;
+ }
+
+ if (channels > 0 && position[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
+ if (channel_mask_out)
+ *channel_mask_out = 0;
+ return TRUE;
+ }
+
+ j = 0;
+ for (i = 0; i < channels; i++) {
+ while (j < G_N_ELEMENTS (default_channel_order)
+ && default_channel_order[j] != position[i])
+ j++;
+
+ if (position[i] == GST_AUDIO_CHANNEL_POSITION_INVALID ||
+ position[i] == GST_AUDIO_CHANNEL_POSITION_MONO ||
+ position[i] == GST_AUDIO_CHANNEL_POSITION_NONE)
+ return FALSE;
+
+ /* Is this in valid channel order? */
+ if (enforce_order && j == G_N_ELEMENTS (default_channel_order))
+ return FALSE;
+ j++;
+
+ if ((channel_mask & (G_GUINT64_CONSTANT (1) << position[i])))
+ return FALSE;
+
+ channel_mask |= (G_GUINT64_CONSTANT (1) << position[i]);
+ }
+
+ if (channel_mask_out)
+ *channel_mask_out = channel_mask;
+
+ return TRUE;
+}
+
+/**
+ * gst_audio_reorder_channels:
+ * @data: The pointer to the memory.
+ * @size: The size of the memory.
+ * @format: The %GstAudioFormat of the buffer.
+ * @channels: The number of channels.
+ * @from: The channel positions in the buffer.
+ * @to: The channel positions to convert to.
+ *
+ * Reorders @data from the channel positions @from to the channel
+ * positions @to. @from and @to must contain the same number of
+ * positions and the same positions, only in a different order.
+ *
+ * Returns: %TRUE if the reordering was possible.
+ */
+gboolean
+gst_audio_reorder_channels (gpointer data, gsize size, GstAudioFormat format,
+ gint channels, const GstAudioChannelPosition * from,
+ const GstAudioChannelPosition * to)
+{
+ const GstAudioFormatInfo *info;
+ gint i, j, n;
+ gint reorder_map[64] = { 0, };
+ guint8 *ptr;
+ gint bpf, bps;
+ guint8 tmp[64 * 8];
+
+ info = gst_audio_format_get_info (format);
+
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (from != NULL, FALSE);
+ g_return_val_if_fail (to != NULL, FALSE);
+ g_return_val_if_fail (info != NULL && info->width > 0, FALSE);
+ g_return_val_if_fail (info->width > 0, FALSE);
+ g_return_val_if_fail (info->width <= 8 * 64, FALSE);
+ g_return_val_if_fail (size % ((info->width * channels) / 8) == 0, FALSE);
+ g_return_val_if_fail (channels > 0, FALSE);
+ g_return_val_if_fail (channels <= 64, FALSE);
+
+ if (size == 0)
+ return TRUE;
+
+ if (memcmp (from, to, channels * sizeof (from[0])) == 0)
+ return TRUE;
+
+ if (!gst_audio_get_channel_reorder_map (channels, from, to, reorder_map))
+ return FALSE;
+
+ bps = info->width / 8;
+ bpf = bps * channels;
+ ptr = data;
+
+ n = size / bpf;
+ for (i = 0; i < n; i++) {
+
+ memcpy (tmp, ptr, bpf);
+ for (j = 0; j < channels; j++)
+ memcpy (ptr + reorder_map[j] * bps, tmp + j * bps, bps);
+
+ ptr += bpf;
+ }
+
+ return TRUE;
+}
+
+/**
+ * gst_audio_buffer_reorder_channels:
+ * @buffer: The buffer to reorder.
+ * @format: The %GstAudioFormat of the buffer.
+ * @channels: The number of channels.
+ * @from: The channel positions in the buffer.
+ * @to: The channel positions to convert to.
+ *
+ * Reorders @buffer from the channel positions @from to the channel
+ * positions @to. @from and @to must contain the same number of
+ * positions and the same positions, only in a different order.
+ * @buffer must be writable.
+ *
+ * Returns: %TRUE if the reordering was possible.
+ */
+gboolean
+gst_audio_buffer_reorder_channels (GstBuffer * buffer,
+ GstAudioFormat format, gint channels,
+ const GstAudioChannelPosition * from, const GstAudioChannelPosition * to)
+{
+ GstMapInfo info;
+ gboolean ret;
+
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+ g_return_val_if_fail (gst_buffer_is_writable (buffer), FALSE);
+
+ gst_buffer_map (buffer, &info, GST_MAP_READWRITE);
+
+ ret =
+ gst_audio_reorder_channels (info.data, info.size, format, channels, from,
+ to);
+
+ gst_buffer_unmap (buffer, &info);
+
+ return ret;
+}
+
+/**
+ * gst_audio_check_valid_channel_positions:
+ * @position: The %GstAudioChannelPositions to check.
+ * @channels: The number of channels.
+ * @force_order: Only consider the GStreamer channel order.
+ *
+ * Checks if @position contains valid channel positions for
+ * @channels channels. If @force_order is %TRUE it additionally
+ * checks if the channels are in the order required by GStreamer.
+ *
+ * Returns: %TRUE if the channel positions are valid.
+ */
+gboolean
+gst_audio_check_valid_channel_positions (const GstAudioChannelPosition *
+ position, gint channels, gboolean force_order)
+{
+ return check_valid_channel_positions (position, channels, force_order, NULL);
+}
+
+/**
+ * gst_audio_channel_positions_to_mask:
+ * @position: The %GstAudioChannelPositions
+ * @channels: The number of channels.
+ * @force_order: Only consider the GStreamer channel order.
+ * @channel_mask: the output channel mask
+ *
+ * Convert the @position array of @channels channels to a bitmask.
+ *
+ * If @force_order is %TRUE it additionally checks if the channels are
+ * in the order required by GStreamer.
+ *
+ * Returns: %TRUE if the channel positions are valid and could be converted.
+ */
+gboolean
+gst_audio_channel_positions_to_mask (const GstAudioChannelPosition * position,
+ gint channels, gboolean force_order, guint64 * channel_mask)
+{
+ return check_valid_channel_positions (position, channels, force_order,
+ channel_mask);
+}
+
+/**
+ * gst_audio_channel_positions_from_mask:
+ * @channels: The number of channels
+ * @channel_mask: The input channel_mask
+ * @position: The %GstAudioChannelPositions
+ * @caps: a #GstCaps
+ *
+ * Convert the @channels present in @channel_mask to a @position array
+ * (which should have at least @channels entries ensured by caller).
+ * If @channel_mask is set to 0, it is considered as 'not present' for purpose
+ * of conversion.
+ *
+ * Returns: %TRUE if channel and channel mask are valid and could be converted
+ */
+gboolean
+gst_audio_channel_positions_from_mask (gint channels, guint64 channel_mask,
+ GstAudioChannelPosition * position)
+{
+ g_return_val_if_fail (position != NULL, FALSE);
+ g_return_val_if_fail (channels != 0, FALSE);
+
+ GST_DEBUG ("converting %d channels for "
+ " channel mask 0x%016" G_GINT64_MODIFIER "x", channels, channel_mask);
+
+ if (!channel_mask) {
+ if (channels == 1) {
+ position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
+ } else if (channels == 2) {
+ position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
+ position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
+ } else {
+ goto no_channel_mask;
+ }
+ } else {
+ gint i, j;
+
+ j = 0;
+ for (i = 0; i < 64; i++) {
+ if ((channel_mask & (G_GUINT64_CONSTANT (1) << i))) {
+ if (j < channels)
+ position[j] = default_channel_order[i];
+ if (default_channel_order[i] == GST_AUDIO_CHANNEL_POSITION_INVALID)
+ goto invalid_channel_mask;
+ j++;
+ }
+ }
+
+ if (j != channels)
+ goto invalid_channel_mask;
+ }
+
+ return TRUE;
+
+ /* ERROR */
+no_channel_mask:
+ {
+ GST_ERROR ("no channel-mask property given");
+ return FALSE;
+ }
+invalid_channel_mask:
+ {
+ GST_ERROR ("Invalid channel mask 0x%016" G_GINT64_MODIFIER
+ "x for %d channels", channel_mask, channels);
+ return FALSE;
+ }
+}
+
+
+/**
+ * gst_audio_get_channel_reorder_map:
+ * @channels: The number of channels.
+ * @from: The channel positions to reorder from.
+ * @to: The channel positions to reorder to.
+ * @reorder_map: Pointer to the reorder map.
+ *
+ * Returns a reorder map for @from to @to that can be used in
+ * custom channel reordering code, e.g. to convert from or to the
+ * GStreamer channel order. @from and @to must contain the same
+ * number of positions and the same positions, only in a
+ * different order.
+ *
+ * The resulting @reorder_map can be used for reordering by assigning
+ * channel i of the input to channel reorder_map[i] of the output.
+ *
+ * Returns: %TRUE if the channel positions are valid and reordering
+ * is possible.
+ */
+gboolean
+gst_audio_get_channel_reorder_map (gint channels,
+ const GstAudioChannelPosition * from, const GstAudioChannelPosition * to,
+ gint * reorder_map)
+{
+ gint i, j;
+
+ g_return_val_if_fail (reorder_map != NULL, FALSE);
+ g_return_val_if_fail (channels > 0, FALSE);
+ g_return_val_if_fail (from != NULL, FALSE);
+ g_return_val_if_fail (to != NULL, FALSE);
+ g_return_val_if_fail (check_valid_channel_positions (from, channels, FALSE,
+ NULL), FALSE);
+ g_return_val_if_fail (check_valid_channel_positions (to, channels, FALSE,
+ NULL), FALSE);
+
+ /* Build reorder map and check compatibility */
+ for (i = 0; i < channels; i++) {
+ if (from[i] == GST_AUDIO_CHANNEL_POSITION_NONE
+ || to[i] == GST_AUDIO_CHANNEL_POSITION_NONE)
+ return FALSE;
+ if (from[i] == GST_AUDIO_CHANNEL_POSITION_INVALID
+ || to[i] == GST_AUDIO_CHANNEL_POSITION_INVALID)
+ return FALSE;
+ if (from[i] == GST_AUDIO_CHANNEL_POSITION_MONO
+ || to[i] == GST_AUDIO_CHANNEL_POSITION_MONO)
+ return FALSE;
+
+ for (j = 0; j < channels; j++) {
+ if (from[i] == to[j]) {
+ reorder_map[i] = j;
+ break;
+ }
+ }
+
+ /* Not all channels present in both */
+ if (j == channels)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * gst_audio_channel_positions_to_valid_order:
+ * @position: The channel positions to reorder to.
+ * @channels: The number of channels.
+ *
+ * Reorders the channel positions in @position from any order to
+ * the GStreamer channel order.
+ *
+ * Returns: %TRUE if the channel positions are valid and reordering
+ * was successful.
+ */
+gboolean
+gst_audio_channel_positions_to_valid_order (GstAudioChannelPosition * position,
+ gint channels)
+{
+ GstAudioChannelPosition tmp[64];
+ guint64 channel_mask = 0;
+ gint i, j;
+
+ g_return_val_if_fail (channels > 0, FALSE);
+ g_return_val_if_fail (position != NULL, FALSE);
+ g_return_val_if_fail (check_valid_channel_positions (position, channels,
+ FALSE, NULL), FALSE);
+
+ if (channels == 1 && position[0] == GST_AUDIO_CHANNEL_POSITION_MONO)
+ return TRUE;
+ if (position[0] == GST_AUDIO_CHANNEL_POSITION_NONE)
+ return TRUE;
+
+ check_valid_channel_positions (position, channels, FALSE, &channel_mask);
+
+ memset (tmp, 0xff, sizeof (tmp));
+ j = 0;
+ for (i = 0; i < 64; i++) {
+ if ((channel_mask & (G_GUINT64_CONSTANT (1) << i))) {
+ tmp[j] = i;
+ j++;
+ }
+ }
+
+ memcpy (position, tmp, sizeof (tmp[0]) * channels);
+
+ return TRUE;
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Library <2001> Thomas Vander Stichele <thomas@apestaart.org>
+ * <2011> Wim Taymans <wim.taymans@gmail.com>
+ *
+ * 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.
+ */
+
+#ifndef __GST_AUDIO_CHANNELS_H__
+#define __GST_AUDIO_CHANNELS_H__
+
+#include <gst/gst.h>
+
+#include <gst/audio/audio-format.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GstAudioChannelPosition:
+ * @GST_AUDIO_CHANNEL_POSITION_MONO: Mono without direction;
+ * can only be used with 1 channel
+ * @GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT: Front left
+ * @GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT: Front right
+ * @GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER: Front center
+ * @GST_AUDIO_CHANNEL_POSITION_LFE1: Low-frequency effects 1 (subwoofer)
+ * @GST_AUDIO_CHANNEL_POSITION_REAR_LEFT: Rear left
+ * @GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT: Rear right
+ * @GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: Front left of center
+ * @GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: Front right of center
+ * @GST_AUDIO_CHANNEL_POSITION_REAR_CENTER: Rear center
+ * @GST_AUDIO_CHANNEL_POSITION_LFE2: Low-frequency effects 2 (subwoofer)
+ * @GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT: Side left
+ * @GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT: Side right
+ * @GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT: Top front left
+ * @GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT: Top front right
+ * @GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER: Top front center
+ * @GST_AUDIO_CHANNEL_POSITION_TOP_CENTER: Top center
+ * @GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT: Top rear left
+ * @GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT: Top rear right
+ * @GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT: Top side right
+ * @GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT: Top rear right
+ * @GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER: Top rear center
+ * @GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER: Bottom front center
+ * @GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT: Bottom front left
+ * @GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT: Bottom front right
+ * @GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT: Wide left (between front left and side left)
+ * @GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT: Wide right (between front right and side right)
+ * @GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT: Surround left (between rear left and side left)
+ * @GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT: Surround right (between rear right and side right)
+ * @GST_AUDIO_CHANNEL_POSITION_NONE: used for position-less channels, e.g.
+ * from a sound card that records 1024 channels; mutually exclusive with
+ * any other channel position
+ * @GST_AUDIO_CHANNEL_POSITION_INVALID: invalid position
+ *
+ * Audio channel positions.
+ *
+ * These are the channels defined in SMPTE 2036-2-2008
+ * Table 1 for 22.2 audio systems with the Surround and Wide channels from
+ * DTS Coherent Acoustics (v.1.3.1) and 10.2 and 7.1 layouts. In the caps the
+ * actual channel layout is expressed with a channel count and a channel mask,
+ * which describes the existing channels. The positions in the bit mask correspond
+ * to the enum values.
+ * For negotiation it is allowed to have more bits set in the channel mask than
+ * the number of channels to specify the allowed channel positions but this is
+ * not allowed in negotiated caps. It is not allowed in any situation other
+ * than the one mentioned below to have less bits set in the channel mask than
+ * the number of channels.
+ *
+ * @GST_AUDIO_CHANNEL_POSITION_MONO can only be used with a single mono channel that
+ * has no direction information and would be mixed into all directional channels.
+ * This is expressed in caps by having a single channel and no channel mask.
+ *
+ * @GST_AUDIO_CHANNEL_POSITION_NONE can only be used if all channels have this position.
+ * This is expressed in caps by having a channel mask with no bits set.
+ *
+ * As another special case it is allowed to have two channels without a channel mask.
+ * This implicitely means that this is a stereo stream with a front left and front right
+ * channel.
+ */
+typedef enum {
+ /* These get negative indices to allow to use
+ * the enum values of the normal cases for the
+ * bit-mask position */
+ GST_AUDIO_CHANNEL_POSITION_NONE = -3,
+ GST_AUDIO_CHANNEL_POSITION_MONO = -2,
+ GST_AUDIO_CHANNEL_POSITION_INVALID = -1,
+
+ /* Normal cases */
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT = 0,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_LFE1,
+ GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_LFE2,
+ GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_TOP_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT
+} GstAudioChannelPosition;
+
+#define GST_AUDIO_CHANNEL_POSITION_MASK(pos) (G_GUINT64_CONSTANT(1)<< GST_AUDIO_CHANNEL_POSITION_ ## pos)
+
+gboolean gst_audio_buffer_reorder_channels (GstBuffer * buffer,
+ GstAudioFormat format,
+ gint channels,
+ const GstAudioChannelPosition * from,
+ const GstAudioChannelPosition * to);
+
+gboolean gst_audio_reorder_channels (gpointer data, gsize size,
+ GstAudioFormat format,
+ gint channels,
+ const GstAudioChannelPosition * from,
+ const GstAudioChannelPosition * to);
+
+gboolean gst_audio_channel_positions_to_valid_order (GstAudioChannelPosition *position,
+ gint channels);
+
+gboolean gst_audio_check_valid_channel_positions (const GstAudioChannelPosition *position,
+ gint channels, gboolean force_order);
+
+gboolean gst_audio_channel_positions_to_mask (const GstAudioChannelPosition *position,
+ gint channels, gboolean force_order,
+ guint64 *channel_mask);
+
+gboolean gst_audio_channel_positions_from_mask (gint channels, guint64 channel_mask,
+ GstAudioChannelPosition * position);
+
+gboolean gst_audio_get_channel_reorder_map (gint channels,
+ const GstAudioChannelPosition * from,
+ const GstAudioChannelPosition * to,
+ gint *reorder_map);
+
+G_END_DECLS
+
+#endif /* __GST_AUDIO_CHANNELS_H__ */
--- /dev/null
+/* GStreamer
+ * Copyright (C) <2012> Wim Taymans <wim.taymans@gmail.com>
+ *
+ * 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
+
+#include <string.h>
+
+#include "audio-format.h"
+
+#define SINT (GST_AUDIO_FORMAT_FLAG_INTEGER | GST_AUDIO_FORMAT_FLAG_SIGNED)
+#define UINT (GST_AUDIO_FORMAT_FLAG_INTEGER)
+
+#define MAKE_FORMAT(str,desc,flags,end,width,depth,silent) \
+ { GST_AUDIO_FORMAT_ ##str, G_STRINGIFY(str), desc, flags, end, width, depth, silent }
+
+#define SILENT_0 { 0, 0, 0, 0, 0, 0, 0, 0 }
+#define SILENT_U8 { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }
+#define SILENT_U16LE { 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80 }
+#define SILENT_U16BE { 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 }
+#define SILENT_U24_32LE { 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00 }
+#define SILENT_U24_32BE { 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00 }
+#define SILENT_U32LE { 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80 }
+#define SILENT_U32BE { 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }
+#define SILENT_U24LE { 0x00, 0x00, 0x80, 0x00, 0x00, 0x80 }
+#define SILENT_U24BE { 0x80, 0x00, 0x00, 0x80, 0x00, 0x00 }
+#define SILENT_U20LE { 0x00, 0x00, 0x08, 0x00, 0x00, 0x08 }
+#define SILENT_U20BE { 0x08, 0x00, 0x00, 0x08, 0x00, 0x00 }
+#define SILENT_U18LE { 0x00, 0x00, 0x02, 0x00, 0x00, 0x02 }
+#define SILENT_U18BE { 0x02, 0x00, 0x00, 0x02, 0x00, 0x00 }
+
+static GstAudioFormatInfo formats[] = {
+ {GST_AUDIO_FORMAT_UNKNOWN, "UNKNOWN", "Unknown audio", 0, 0, 0, 0},
+ {GST_AUDIO_FORMAT_ENCODED, "ENCODED", "Encoded audio",
+ GST_AUDIO_FORMAT_FLAG_COMPLEX, 0, 0, 0},
+ /* 8 bit */
+ MAKE_FORMAT (S8, "8-bit signed PCM audio", SINT, 0, 8, 8, SILENT_0),
+ MAKE_FORMAT (U8, "8-bit unsigned PCM audio", UINT, 0, 8, 8, SILENT_U8),
+ /* 16 bit */
+ MAKE_FORMAT (S16LE, "16-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 16, 16,
+ SILENT_0),
+ MAKE_FORMAT (S16BE, "16-bit signed PCM audio", SINT, G_BIG_ENDIAN, 16, 16,
+ SILENT_0),
+ MAKE_FORMAT (U16LE, "16-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 16,
+ 16, SILENT_U16LE),
+ MAKE_FORMAT (U16BE, "16-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 16, 16,
+ SILENT_U16BE),
+ /* 24 bit in low 3 bytes of 32 bits */
+ MAKE_FORMAT (S24_32LE, "24-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 32,
+ 24, SILENT_0),
+ MAKE_FORMAT (S24_32BE, "24-bit signed PCM audio", SINT, G_BIG_ENDIAN, 32, 24,
+ SILENT_0),
+ MAKE_FORMAT (U24_32LE, "24-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 32,
+ 24, SILENT_U24_32LE),
+ MAKE_FORMAT (U24_32BE, "24-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 32,
+ 24, SILENT_U24_32BE),
+ /* 32 bit */
+ MAKE_FORMAT (S32LE, "32-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 32, 32,
+ SILENT_0),
+ MAKE_FORMAT (S32BE, "32-bit signed PCM audio", SINT, G_BIG_ENDIAN, 32, 32,
+ SILENT_0),
+ MAKE_FORMAT (U32LE, "32-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 32,
+ 32, SILENT_U32LE),
+ MAKE_FORMAT (U32BE, "32-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 32, 32,
+ SILENT_U32BE),
+ /* 24 bit in 3 bytes */
+ MAKE_FORMAT (S24LE, "24-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 24, 24,
+ SILENT_0),
+ MAKE_FORMAT (S24BE, "24-bit signed PCM audio", SINT, G_BIG_ENDIAN, 24, 24,
+ SILENT_0),
+ MAKE_FORMAT (U24LE, "24-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 24,
+ 24, SILENT_U24LE),
+ MAKE_FORMAT (U24BE, "24-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 24, 24,
+ SILENT_U24BE),
+ /* 20 bit in 3 bytes */
+ MAKE_FORMAT (S20LE, "20-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 24, 20,
+ SILENT_0),
+ MAKE_FORMAT (S20BE, "20-bit signed PCM audio", SINT, G_BIG_ENDIAN, 24, 20,
+ SILENT_0),
+ MAKE_FORMAT (U20LE, "20-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 24,
+ 20, SILENT_U20LE),
+ MAKE_FORMAT (U20BE, "20-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 24, 20,
+ SILENT_U20BE),
+ /* 18 bit in 3 bytes */
+ MAKE_FORMAT (S18LE, "18-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 24, 18,
+ SILENT_0),
+ MAKE_FORMAT (S18BE, "18-bit signed PCM audio", SINT, G_BIG_ENDIAN, 24, 18,
+ SILENT_0),
+ MAKE_FORMAT (U18LE, "18-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 24,
+ 18, SILENT_U18LE),
+ MAKE_FORMAT (U18BE, "18-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 24, 18,
+ SILENT_U18BE),
+ /* float */
+ MAKE_FORMAT (F32LE, "32-bit floating-point audio",
+ GST_AUDIO_FORMAT_FLAG_FLOAT, G_LITTLE_ENDIAN, 32, 32,
+ SILENT_0),
+ MAKE_FORMAT (F32BE, "32-bit floating-point audio",
+ GST_AUDIO_FORMAT_FLAG_FLOAT, G_BIG_ENDIAN, 32, 32,
+ SILENT_0),
+ MAKE_FORMAT (F64LE, "64-bit floating-point audio",
+ GST_AUDIO_FORMAT_FLAG_FLOAT, G_LITTLE_ENDIAN, 64, 64,
+ SILENT_0),
+ MAKE_FORMAT (F64BE, "64-bit floating-point audio",
+ GST_AUDIO_FORMAT_FLAG_FLOAT, G_BIG_ENDIAN, 64, 64,
+ SILENT_0)
+};
+
+G_DEFINE_POINTER_TYPE (GstAudioFormatInfo, gst_audio_format_info);
+
+/**
+ * gst_audio_format_build_integer:
+ * @sign: signed or unsigned format
+ * @endianness: G_LITTLE_ENDIAN or G_BIG_ENDIAN
+ * @width: amount of bits used per sample
+ * @depth: amount of used bits in @width
+ *
+ * Construct a #GstAudioFormat with given parameters.
+ *
+ * Returns: a #GstAudioFormat or GST_AUDIO_FORMAT_UNKNOWN when no audio format
+ * exists with the given parameters.
+ */
+GstAudioFormat
+gst_audio_format_build_integer (gboolean sign, gint endianness,
+ gint width, gint depth)
+{
+ gint i, e;
+
+ for (i = 0; i < G_N_ELEMENTS (formats); i++) {
+ GstAudioFormatInfo *finfo = &formats[i];
+
+ /* must be int */
+ if (!GST_AUDIO_FORMAT_INFO_IS_INTEGER (finfo))
+ continue;
+
+ /* width and depth must match */
+ if (width != GST_AUDIO_FORMAT_INFO_WIDTH (finfo))
+ continue;
+ if (depth != GST_AUDIO_FORMAT_INFO_DEPTH (finfo))
+ continue;
+
+ /* if there is endianness, it must match */
+ e = GST_AUDIO_FORMAT_INFO_ENDIANNESS (finfo);
+ if (e && e != endianness)
+ continue;
+
+ /* check sign */
+ if ((sign && !GST_AUDIO_FORMAT_INFO_IS_SIGNED (finfo)) ||
+ (!sign && GST_AUDIO_FORMAT_INFO_IS_SIGNED (finfo)))
+ continue;
+
+ return GST_AUDIO_FORMAT_INFO_FORMAT (finfo);
+ }
+ return GST_AUDIO_FORMAT_UNKNOWN;
+}
+
+/**
+ * gst_audio_format_from_string:
+ * @format: a format string
+ *
+ * Convert the @format string to its #GstAudioFormat.
+ *
+ * Returns: the #GstAudioFormat for @format or GST_AUDIO_FORMAT_UNKNOWN when the
+ * string is not a known format.
+ */
+GstAudioFormat
+gst_audio_format_from_string (const gchar * format)
+{
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (formats); i++) {
+ if (strcmp (GST_AUDIO_FORMAT_INFO_NAME (&formats[i]), format) == 0)
+ return GST_AUDIO_FORMAT_INFO_FORMAT (&formats[i]);
+ }
+ return GST_AUDIO_FORMAT_UNKNOWN;
+}
+
+const gchar *
+gst_audio_format_to_string (GstAudioFormat format)
+{
+ g_return_val_if_fail (format != GST_AUDIO_FORMAT_UNKNOWN, NULL);
+
+ if (format >= G_N_ELEMENTS (formats))
+ return NULL;
+
+ return GST_AUDIO_FORMAT_INFO_NAME (&formats[format]);
+}
+
+/**
+ * gst_audio_format_get_info:
+ * @format: a #GstAudioFormat
+ *
+ * Get the #GstAudioFormatInfo for @format
+ *
+ * Returns: The #GstAudioFormatInfo for @format.
+ */
+const GstAudioFormatInfo *
+gst_audio_format_get_info (GstAudioFormat format)
+{
+ g_return_val_if_fail (format < G_N_ELEMENTS (formats), NULL);
+
+ return &formats[format];
+}
+
+/**
+ * gst_audio_format_fill_silence:
+ * @info: a #GstAudioFormatInfo
+ * @dest: a destination to fill
+ * @length: the length to fill
+ *
+ * Fill @length bytes in @dest with silence samples for @info.
+ */
+void
+gst_audio_format_fill_silence (const GstAudioFormatInfo * info,
+ gpointer dest, gsize length)
+{
+ guint8 *dptr = dest;
+
+ g_return_if_fail (info != NULL);
+ g_return_if_fail (dest != NULL);
+
+ if (info->flags & GST_AUDIO_FORMAT_FLAG_FLOAT ||
+ info->flags & GST_AUDIO_FORMAT_FLAG_SIGNED) {
+ /* float or signed always 0 */
+ memset (dest, 0, length);
+ } else {
+ gint i, j, bps = info->width >> 3;
+
+ switch (bps) {
+ case 1:
+ memset (dest, info->silence[0], length);
+ break;
+ default:
+ for (i = 0; i < length; i += bps) {
+ for (j = 0; j < bps; j++)
+ *dptr++ = info->silence[j];
+ }
+ break;
+ }
+ }
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Library <2001> Thomas Vander Stichele <thomas@apestaart.org>
+ * <2011> Wim Taymans <wim.taymans@gmail.com>
+ *
+ * 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.
+ */
+
+#include <gst/gst.h>
+
+#ifndef __GST_AUDIO_FORMAT_H__
+#define __GST_AUDIO_FORMAT_H__
+
+G_BEGIN_DECLS
+
+#include <gst/audio/audio-enumtypes.h>
+
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+#define _GST_AUDIO_FORMAT_NE(fmt) GST_AUDIO_FORMAT_ ## fmt ## BE
+#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define _GST_AUDIO_FORMAT_NE(fmt) GST_AUDIO_FORMAT_ ## fmt ## LE
+#endif
+
+/**
+ * GstAudioFormat:
+ * @GST_AUDIO_FORMAT_UNKNOWN: unknown or unset audio format
+ * @GST_AUDIO_FORMAT_ENCODED: encoded audio format
+ * @GST_AUDIO_FORMAT_S8: 8 bits in 8 bits, signed
+ * @GST_AUDIO_FORMAT_U8: 8 bits in 8 bits, unsigned
+ * @GST_AUDIO_FORMAT_S16LE: 16 bits in 16 bits, signed, little endian
+ * @GST_AUDIO_FORMAT_S16BE: 16 bits in 16 bits, signed, big endian
+ * @GST_AUDIO_FORMAT_U16LE: 16 bits in 16 bits, unsigned, little endian
+ * @GST_AUDIO_FORMAT_U16BE: 16 bits in 16 bits, unsigned, big endian
+ * @GST_AUDIO_FORMAT_S24_32LE: 24 bits in 32 bits, signed, little endian
+ * @GST_AUDIO_FORMAT_S24_32BE: 24 bits in 32 bits, signed, big endian
+ * @GST_AUDIO_FORMAT_U24_32LE: 24 bits in 32 bits, unsigned, little endian
+ * @GST_AUDIO_FORMAT_U24_32BE: 24 bits in 32 bits, unsigned, big endian
+ * @GST_AUDIO_FORMAT_S32LE: 32 bits in 32 bits, signed, little endian
+ * @GST_AUDIO_FORMAT_S32BE: 32 bits in 32 bits, signed, big endian
+ * @GST_AUDIO_FORMAT_U32LE: 32 bits in 32 bits, unsigned, little endian
+ * @GST_AUDIO_FORMAT_U32BE: 32 bits in 32 bits, unsigned, big endian
+ * @GST_AUDIO_FORMAT_S24LE: 24 bits in 24 bits, signed, little endian
+ * @GST_AUDIO_FORMAT_S24BE: 24 bits in 24 bits, signed, big endian
+ * @GST_AUDIO_FORMAT_U24LE: 24 bits in 24 bits, unsigned, little endian
+ * @GST_AUDIO_FORMAT_U24BE: 24 bits in 24 bits, unsigned, big endian
+ * @GST_AUDIO_FORMAT_S20LE: 20 bits in 24 bits, signed, little endian
+ * @GST_AUDIO_FORMAT_S20BE: 20 bits in 24 bits, signed, big endian
+ * @GST_AUDIO_FORMAT_U20LE: 20 bits in 24 bits, unsigned, little endian
+ * @GST_AUDIO_FORMAT_U20BE: 20 bits in 24 bits, unsigned, big endian
+ * @GST_AUDIO_FORMAT_S18LE: 18 bits in 24 bits, signed, little endian
+ * @GST_AUDIO_FORMAT_S18BE: 18 bits in 24 bits, signed, big endian
+ * @GST_AUDIO_FORMAT_U18LE: 18 bits in 24 bits, unsigned, little endian
+ * @GST_AUDIO_FORMAT_U18BE: 18 bits in 24 bits, unsigned, big endian
+ * @GST_AUDIO_FORMAT_F32LE: 32-bit floating point samples, little endian
+ * @GST_AUDIO_FORMAT_F32BE: 32-bit floating point samples, big endian
+ * @GST_AUDIO_FORMAT_F64LE: 64-bit floating point samples, little endian
+ * @GST_AUDIO_FORMAT_F64BE: 64-bit floating point samples, big endian
+ * @GST_AUDIO_FORMAT_S16: 16 bits in 16 bits, signed, native endianness
+ * @GST_AUDIO_FORMAT_U16: 16 bits in 16 bits, unsigned, native endianness
+ * @GST_AUDIO_FORMAT_S24_32: 24 bits in 32 bits, signed, native endianness
+ * @GST_AUDIO_FORMAT_U24_32: 24 bits in 32 bits, unsigned, native endianness
+ * @GST_AUDIO_FORMAT_S32: 32 bits in 32 bits, signed, native endianness
+ * @GST_AUDIO_FORMAT_U32: 32 bits in 32 bits, unsigned, native endianness
+ * @GST_AUDIO_FORMAT_S24: 24 bits in 24 bits, signed, native endianness
+ * @GST_AUDIO_FORMAT_U24: 24 bits in 24 bits, unsigned, native endianness
+ * @GST_AUDIO_FORMAT_S20: 20 bits in 24 bits, signed, native endianness
+ * @GST_AUDIO_FORMAT_U20: 20 bits in 24 bits, unsigned, native endianness
+ * @GST_AUDIO_FORMAT_S18: 18 bits in 24 bits, signed, native endianness
+ * @GST_AUDIO_FORMAT_U18: 18 bits in 24 bits, unsigned, native endianness
+ * @GST_AUDIO_FORMAT_F32: 32-bit floating point samples, native endianness
+ * @GST_AUDIO_FORMAT_F64: 64-bit floating point samples, native endianness
+ *
+ * Enum value describing the most common audio formats.
+ */
+typedef enum {
+ GST_AUDIO_FORMAT_UNKNOWN,
+ GST_AUDIO_FORMAT_ENCODED,
+ /* 8 bit */
+ GST_AUDIO_FORMAT_S8,
+ GST_AUDIO_FORMAT_U8,
+ /* 16 bit */
+ GST_AUDIO_FORMAT_S16LE,
+ GST_AUDIO_FORMAT_S16BE,
+ GST_AUDIO_FORMAT_U16LE,
+ GST_AUDIO_FORMAT_U16BE,
+ /* 24 bit in low 3 bytes of 32 bits*/
+ GST_AUDIO_FORMAT_S24_32LE,
+ GST_AUDIO_FORMAT_S24_32BE,
+ GST_AUDIO_FORMAT_U24_32LE,
+ GST_AUDIO_FORMAT_U24_32BE,
+ /* 32 bit */
+ GST_AUDIO_FORMAT_S32LE,
+ GST_AUDIO_FORMAT_S32BE,
+ GST_AUDIO_FORMAT_U32LE,
+ GST_AUDIO_FORMAT_U32BE,
+ /* 24 bit in 3 bytes*/
+ GST_AUDIO_FORMAT_S24LE,
+ GST_AUDIO_FORMAT_S24BE,
+ GST_AUDIO_FORMAT_U24LE,
+ GST_AUDIO_FORMAT_U24BE,
+ /* 20 bit in 3 bytes*/
+ GST_AUDIO_FORMAT_S20LE,
+ GST_AUDIO_FORMAT_S20BE,
+ GST_AUDIO_FORMAT_U20LE,
+ GST_AUDIO_FORMAT_U20BE,
+ /* 18 bit in 3 bytes*/
+ GST_AUDIO_FORMAT_S18LE,
+ GST_AUDIO_FORMAT_S18BE,
+ GST_AUDIO_FORMAT_U18LE,
+ GST_AUDIO_FORMAT_U18BE,
+ /* float */
+ GST_AUDIO_FORMAT_F32LE,
+ GST_AUDIO_FORMAT_F32BE,
+ GST_AUDIO_FORMAT_F64LE,
+ GST_AUDIO_FORMAT_F64BE,
+ /* native endianness equivalents */
+ GST_AUDIO_FORMAT_S16 = _GST_AUDIO_FORMAT_NE(S16),
+ GST_AUDIO_FORMAT_U16 = _GST_AUDIO_FORMAT_NE(U16),
+ GST_AUDIO_FORMAT_S24_32 = _GST_AUDIO_FORMAT_NE(S24_32),
+ GST_AUDIO_FORMAT_U24_32 = _GST_AUDIO_FORMAT_NE(U24_32),
+ GST_AUDIO_FORMAT_S32 = _GST_AUDIO_FORMAT_NE(S32),
+ GST_AUDIO_FORMAT_U32 = _GST_AUDIO_FORMAT_NE(U32),
+ GST_AUDIO_FORMAT_S24 = _GST_AUDIO_FORMAT_NE(S24),
+ GST_AUDIO_FORMAT_U24 = _GST_AUDIO_FORMAT_NE(U24),
+ GST_AUDIO_FORMAT_S20 = _GST_AUDIO_FORMAT_NE(S20),
+ GST_AUDIO_FORMAT_U20 = _GST_AUDIO_FORMAT_NE(U20),
+ GST_AUDIO_FORMAT_S18 = _GST_AUDIO_FORMAT_NE(S18),
+ GST_AUDIO_FORMAT_U18 = _GST_AUDIO_FORMAT_NE(U18),
+ GST_AUDIO_FORMAT_F32 = _GST_AUDIO_FORMAT_NE(F32),
+ GST_AUDIO_FORMAT_F64 = _GST_AUDIO_FORMAT_NE(F64)
+} GstAudioFormat;
+
+
+typedef struct _GstAudioFormatInfo GstAudioFormatInfo;
+
+/**
+ * GstAudioFormatFlags:
+ * @GST_AUDIO_FORMAT_FLAG_INTEGER: integer samples
+ * @GST_AUDIO_FORMAT_FLAG_FLOAT: float samples
+ * @GST_AUDIO_FORMAT_FLAG_SIGNED: signed samples
+ * @GST_AUDIO_FORMAT_FLAG_COMPLEX: complex layout
+ *
+ * The different audio flags that a format info can have.
+ */
+typedef enum
+{
+ GST_AUDIO_FORMAT_FLAG_INTEGER = (1 << 0),
+ GST_AUDIO_FORMAT_FLAG_FLOAT = (1 << 1),
+ GST_AUDIO_FORMAT_FLAG_SIGNED = (1 << 2),
+ GST_AUDIO_FORMAT_FLAG_COMPLEX = (1 << 4)
+} GstAudioFormatFlags;
+
+/**
+ * GstAudioPackFlags:
+ * @GST_AUDIO_PACK_FLAG_NONE: No flag
+ *
+ * The different flags that can be used when packing and unpacking.
+ */
+typedef enum
+{
+ GST_AUDIO_PACK_FLAG_NONE = 0
+} GstAudioPackFlags;
+
+/**
+ * GstAudioFormatUnpack:
+ * @info: a #GstAudioFormatInfo
+ * @dest: a destination array
+ * @data: pointer to the audio data
+ * @length: the amount of samples to unpack.
+ *
+ * Unpacks @length samples from the given data of format @info.
+ * The samples will be unpacked into @dest which each channel
+ * interleaved. @dest should at least be big enough to hold @length *
+ * channels * size(unpack_format) bytes.
+ */
+typedef void (*GstAudioFormatUnpack) (const GstAudioFormatInfo *info,
+ GstAudioPackFlags flags, gpointer dest,
+ const gpointer data, gint length);
+/**
+ * GstAudioFormatPack:
+ * @info: a #GstAudioFormatInfo
+ * @src: a source array
+ * @data: pointer to the destination data
+ * @length: the amount of samples to pack.
+ *
+ * Packs @length samples from @src to the data array in format @info.
+ * The samples from source have each channel interleaved
+ * and will be packed into @data.
+ */
+typedef void (*GstAudioFormatPack) (const GstAudioFormatInfo *info,
+ GstAudioPackFlags flags, const gpointer src,
+ gpointer data, gint length);
+
+/**
+ * GstAudioFormatInfo:
+ * @format: #GstAudioFormat
+ * @name: string representation of the format
+ * @description: user readable description of the format
+ * @flags: #GstAudioFormatFlags
+ * @endianness: the endianness
+ * @width: amount of bits used for one sample
+ * @depth: amount of valid bits in @width
+ * @silence: @width/8 bytes with 1 silent sample
+ * @unpack_format: the format of the unpacked samples
+ * @unpack_func: function to unpack samples
+ * @pack_func: function to pack samples
+ *
+ * Information for an audio format.
+ */
+struct _GstAudioFormatInfo {
+ GstAudioFormat format;
+ const gchar *name;
+ const gchar *description;
+ GstAudioFormatFlags flags;
+ gint endianness;
+ gint width;
+ gint depth;
+ guint8 silence[8];
+
+ GstAudioFormat unpack_format;
+ GstAudioFormatUnpack unpack_func;
+ GstAudioFormatPack pack_func;
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GType gst_audio_format_info_get_type (void);
+
+#define GST_AUDIO_FORMAT_INFO_FORMAT(info) ((info)->format)
+#define GST_AUDIO_FORMAT_INFO_NAME(info) ((info)->name)
+#define GST_AUDIO_FORMAT_INFO_FLAGS(info) ((info)->flags)
+
+#define GST_AUDIO_FORMAT_INFO_IS_INTEGER(info) !!((info)->flags & GST_AUDIO_FORMAT_FLAG_INTEGER)
+#define GST_AUDIO_FORMAT_INFO_IS_FLOAT(info) !!((info)->flags & GST_AUDIO_FORMAT_FLAG_FLOAT)
+#define GST_AUDIO_FORMAT_INFO_IS_SIGNED(info) !!((info)->flags & GST_AUDIO_FORMAT_FLAG_SIGNED)
+
+#define GST_AUDIO_FORMAT_INFO_ENDIANNESS(info) ((info)->endianness)
+#define GST_AUDIO_FORMAT_INFO_IS_LITTLE_ENDIAN(info) ((info)->endianness == G_LITTLE_ENDIAN)
+#define GST_AUDIO_FORMAT_INFO_IS_BIG_ENDIAN(info) ((info)->endianness == G_BIG_ENDIAN)
+#define GST_AUDIO_FORMAT_INFO_WIDTH(info) ((info)->width)
+#define GST_AUDIO_FORMAT_INFO_DEPTH(info) ((info)->depth)
+
+
+GstAudioFormat gst_audio_format_build_integer (gboolean sign, gint endianness,
+ gint width, gint depth) G_GNUC_CONST;
+
+GstAudioFormat gst_audio_format_from_string (const gchar *format) G_GNUC_CONST;
+const gchar * gst_audio_format_to_string (GstAudioFormat format) G_GNUC_CONST;
+
+const GstAudioFormatInfo *
+ gst_audio_format_get_info (GstAudioFormat format) G_GNUC_CONST;
+
+void gst_audio_format_fill_silence (const GstAudioFormatInfo *info,
+ gpointer dest, gsize length);
+
+#define GST_AUDIO_RATE_RANGE "(int) [ 1, max ]"
+#define GST_AUDIO_CHANNELS_RANGE "(int) [ 1, max ]"
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+# define GST_AUDIO_NE(s) G_STRINGIFY(s)"LE"
+# define GST_AUDIO_OE(s) G_STRINGIFY(s)"BE"
+#else
+# define GST_AUDIO_NE(s) G_STRINGIFY(s)"BE"
+# define GST_AUDIO_OE(s) G_STRINGIFY(s)"LE"
+#endif
+
+#define GST_AUDIO_FORMATS_ALL " { S8, U8, " \
+ "S16LE, S16BE, U16LE, U16BE, " \
+ "S24_32LE, S24_32BE, U24_32LE, U24_32BE, " \
+ "S32LE, S32BE, U32LE, U32BE, " \
+ "S24LE, S24BE, U24LE, U24BE, " \
+ "S20LE, S20BE, U20LE, U20BE, " \
+ "S18LE, S18BE, U18LE, U18BE, " \
+ "F32LE, F32BE, F64LE, F64BE }"
+
+/**
+ * GST_AUDIO_CAPS_MAKE:
+ * @format: string format that describes the sample layout, as string
+ * (e.g. "S16LE", "S8", etc.)
+ *
+ * Generic caps string for audio, for use in pad templates.
+ */
+#define GST_AUDIO_CAPS_MAKE(format) \
+ "audio/x-raw, " \
+ "format = (string) " format ", " \
+ "rate = " GST_AUDIO_RATE_RANGE ", " \
+ "channels = " GST_AUDIO_CHANNELS_RANGE
+
+/**
+ * GST_AUDIO_DEF_RATE:
+ *
+ * Standard sampling rate used in consumer audio.
+ */
+#define GST_AUDIO_DEF_RATE 44100
+/**
+ * GST_AUDIO_DEF_CHANNELS:
+ *
+ * Standard number of channels used in consumer audio.
+ */
+#define GST_AUDIO_DEF_CHANNELS 2
+/**
+ * GST_AUDIO_DEF_FORMAT:
+ *
+ * Standard format used in consumer audio.
+ */
+#define GST_AUDIO_DEF_FORMAT "S16LE"
+
+G_END_DECLS
+
+#endif /* __GST_AUDIO_FORMAT_H__ */
--- /dev/null
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * 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.
+ */
+/**
+ * SECTION:gstaudio
+ * @short_description: Support library for audio elements
+ *
+ * This library contains some helper functions for audio elements.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include "audio.h"
+
+#include <gst/gststructure.h>
+
+/**
+ * gst_audio_info_copy:
+ * @info: a #GstAudioInfo
+ *
+ * Copy a GstAudioInfo structure.
+ *
+ * Returns: a new #GstAudioInfo. free with gst_audio_info_free.
+ */
+GstAudioInfo *
+gst_audio_info_copy (const GstAudioInfo * info)
+{
+ return g_slice_dup (GstAudioInfo, info);
+}
+
+/**
+ * gst_audio_info_free:
+ * @info: a #GstAudioInfo
+ *
+ * Free a GstAudioInfo structure previously allocated with gst_audio_info_new()
+ * or gst_audio_info_copy().
+ */
+void
+gst_audio_info_free (GstAudioInfo * info)
+{
+ g_slice_free (GstAudioInfo, info);
+}
+
+G_DEFINE_BOXED_TYPE (GstAudioInfo, gst_audio_info,
+ (GBoxedCopyFunc) gst_audio_info_copy, (GBoxedFreeFunc) gst_audio_info_free);
+
+/**
+ * gst_audio_info_new:
+ *
+ * Allocate a new #GstAudioInfo that is also initialized with
+ * gst_audio_info_init().
+ *
+ * Returns: a new #GstAudioInfo. free with gst_audio_info_free().
+ */
+GstAudioInfo *
+gst_audio_info_new (void)
+{
+ GstAudioInfo *info;
+
+ info = g_slice_new (GstAudioInfo);
+ gst_audio_info_init (info);
+
+ return info;
+}
+
+/**
+ * gst_audio_info_init:
+ * @info: a #GstAudioInfo
+ *
+ * Initialize @info with default values.
+ */
+void
+gst_audio_info_init (GstAudioInfo * info)
+{
+ g_return_if_fail (info != NULL);
+
+ memset (info, 0, sizeof (GstAudioInfo));
+
+ info->finfo = gst_audio_format_get_info (GST_AUDIO_FORMAT_UNKNOWN);
+
+ memset (&info->position, 0xff, sizeof (info->position));
+}
+
+/**
+ * gst_audio_info_set_format:
+ * @info: a #GstAudioInfo
+ * @format: the format
+ * @rate: the samplerate
+ * @channels: the number of channels
+ * @position: the channel positions
+ *
+ * Set the default info for the audio info of @format and @rate and @channels.
+ */
+void
+gst_audio_info_set_format (GstAudioInfo * info, GstAudioFormat format,
+ gint rate, gint channels, const GstAudioChannelPosition * position)
+{
+ const GstAudioFormatInfo *finfo;
+ gint i;
+
+ g_return_if_fail (info != NULL);
+ g_return_if_fail (format != GST_AUDIO_FORMAT_UNKNOWN);
+
+ finfo = gst_audio_format_get_info (format);
+
+ info->flags = 0;
+ info->layout = GST_AUDIO_LAYOUT_INTERLEAVED;
+ info->finfo = finfo;
+ info->rate = rate;
+ info->channels = channels;
+ info->bpf = (finfo->width * channels) / 8;
+
+ memset (&info->position, 0xff, sizeof (info->position));
+
+ if (!position && channels == 1) {
+ info->position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
+ return;
+ } else if (!position && channels == 2) {
+ info->position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
+ info->position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
+ return;
+ } else {
+ if (!position
+ || !gst_audio_check_valid_channel_positions (position, channels,
+ TRUE)) {
+ if (position)
+ g_warning ("Invalid channel positions");
+ } else {
+ memcpy (&info->position, position,
+ info->channels * sizeof (info->position[0]));
+ if (info->position[0] == GST_AUDIO_CHANNEL_POSITION_NONE)
+ info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
+ return;
+ }
+ }
+
+ /* Otherwise a NONE layout */
+ info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
+ for (i = 0; i < MIN (64, channels); i++)
+ info->position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
+}
+
+/**
+ * gst_audio_info_from_caps:
+ * @info: a #GstAudioInfo
+ * @caps: a #GstCaps
+ *
+ * Parse @caps and update @info.
+ *
+ * Returns: TRUE if @caps could be parsed
+ */
+gboolean
+gst_audio_info_from_caps (GstAudioInfo * info, const GstCaps * caps)
+{
+ GstStructure *str;
+ const gchar *s;
+ GstAudioFormat format;
+ gint rate, channels;
+ guint64 channel_mask;
+ gint i;
+ GstAudioChannelPosition position[64];
+
+ g_return_val_if_fail (info != NULL, FALSE);
+ g_return_val_if_fail (caps != NULL, FALSE);
+ g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
+
+ GST_DEBUG ("parsing caps %" GST_PTR_FORMAT, caps);
+
+ info->flags = 0;
+
+ str = gst_caps_get_structure (caps, 0);
+
+ if (!gst_structure_has_name (str, "audio/x-raw"))
+ goto wrong_name;
+
+ if (!(s = gst_structure_get_string (str, "format")))
+ goto no_format;
+
+ format = gst_audio_format_from_string (s);
+ if (format == GST_AUDIO_FORMAT_UNKNOWN)
+ goto unknown_format;
+
+ if (!(s = gst_structure_get_string (str, "layout")))
+ goto no_layout;
+ if (g_str_equal (s, "interleaved"))
+ info->layout = GST_AUDIO_LAYOUT_INTERLEAVED;
+ else if (g_str_equal (s, "non-interleaved"))
+ info->layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
+ else
+ goto unknown_layout;
+
+ if (!gst_structure_get_int (str, "rate", &rate))
+ goto no_rate;
+ if (!gst_structure_get_int (str, "channels", &channels))
+ goto no_channels;
+
+ if (!gst_structure_get (str, "channel-mask", GST_TYPE_BITMASK, &channel_mask,
+ NULL)) {
+ if (channels == 1) {
+ position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
+ } else if (channels == 2) {
+ position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
+ position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
+ } else {
+ goto no_channel_mask;
+ }
+ } else if (channel_mask == 0) {
+ info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
+ for (i = 0; i < MIN (64, channels); i++)
+ position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
+ } else {
+ if (!gst_audio_channel_positions_from_mask (channels, channel_mask,
+ position))
+ goto invalid_channel_mask;
+ }
+
+ gst_audio_info_set_format (info, format, rate, channels, position);
+
+ return TRUE;
+
+ /* ERROR */
+wrong_name:
+ {
+ GST_ERROR ("wrong name, expected audio/x-raw");
+ return FALSE;
+ }
+no_format:
+ {
+ GST_ERROR ("no format given");
+ return FALSE;
+ }
+unknown_format:
+ {
+ GST_ERROR ("unknown format given");
+ return FALSE;
+ }
+no_layout:
+ {
+ GST_ERROR ("no layout given");
+ return FALSE;
+ }
+unknown_layout:
+ {
+ GST_ERROR ("unknown layout given");
+ return FALSE;
+ }
+no_rate:
+ {
+ GST_ERROR ("no rate property given");
+ return FALSE;
+ }
+no_channels:
+ {
+ GST_ERROR ("no channels property given");
+ return FALSE;
+ }
+no_channel_mask:
+ {
+ GST_ERROR ("no channel-mask property given");
+ return FALSE;
+ }
+invalid_channel_mask:
+ {
+ GST_ERROR ("Invalid channel mask 0x%016" G_GINT64_MODIFIER
+ "x for %d channels", channel_mask, channels);
+ return FALSE;
+ }
+}
+
+/**
+ * gst_audio_info_to_caps:
+ * @info: a #GstAudioInfo
+ *
+ * Convert the values of @info into a #GstCaps.
+ *
+ * Returns: (transfer full): the new #GstCaps containing the
+ * info of @info.
+ */
+GstCaps *
+gst_audio_info_to_caps (const GstAudioInfo * info)
+{
+ GstCaps *caps;
+ const gchar *format;
+ const gchar *layout;
+ GstAudioFlags flags;
+
+ g_return_val_if_fail (info != NULL, NULL);
+ g_return_val_if_fail (info->finfo != NULL, NULL);
+ g_return_val_if_fail (info->finfo->format != GST_AUDIO_FORMAT_UNKNOWN, NULL);
+
+ format = gst_audio_format_to_string (info->finfo->format);
+ g_return_val_if_fail (format != NULL, NULL);
+
+ if (info->layout == GST_AUDIO_LAYOUT_INTERLEAVED)
+ layout = "interleaved";
+ else if (info->layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED)
+ layout = "non-interleaved";
+ else
+ g_return_val_if_reached (NULL);
+
+ flags = info->flags;
+ if ((flags & GST_AUDIO_FLAG_UNPOSITIONED) && info->channels > 1
+ && info->position[0] != GST_AUDIO_CHANNEL_POSITION_NONE) {
+ flags &= ~GST_AUDIO_FLAG_UNPOSITIONED;
+ g_warning ("Unpositioned audio channel position flag set but "
+ "channel positions present");
+ } else if (!(flags & GST_AUDIO_FLAG_UNPOSITIONED) && info->channels > 1
+ && info->position[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
+ flags |= GST_AUDIO_FLAG_UNPOSITIONED;
+ g_warning ("Unpositioned audio channel position flag not set "
+ "but no channel positions present");
+ }
+
+ caps = gst_caps_new_simple ("audio/x-raw",
+ "format", G_TYPE_STRING, format,
+ "layout", G_TYPE_STRING, layout,
+ "rate", G_TYPE_INT, info->rate,
+ "channels", G_TYPE_INT, info->channels, NULL);
+
+ if (info->channels > 1
+ || info->position[0] != GST_AUDIO_CHANNEL_POSITION_MONO) {
+ guint64 channel_mask = 0;
+
+ if ((flags & GST_AUDIO_FLAG_UNPOSITIONED)) {
+ channel_mask = 0;
+ } else {
+ if (!gst_audio_channel_positions_to_mask (info->position, info->channels,
+ TRUE, &channel_mask))
+ goto invalid_channel_positions;
+ }
+
+ if (info->channels == 1
+ && info->position[0] == GST_AUDIO_CHANNEL_POSITION_MONO) {
+ /* Default mono special case */
+ } else {
+ gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
+ NULL);
+ }
+ }
+
+ return caps;
+
+invalid_channel_positions:
+ {
+ GST_ERROR ("Invalid channel positions");
+ gst_caps_unref (caps);
+ return NULL;
+ }
+}
+
+/**
+ * gst_audio_info_convert:
+ * @info: a #GstAudioInfo
+ * @src_format: #GstFormat of the @src_value
+ * @src_value: value to convert
+ * @dest_format: #GstFormat of the @dest_value
+ * @dest_value: pointer to destination value
+ *
+ * Converts among various #GstFormat types. This function handles
+ * GST_FORMAT_BYTES, GST_FORMAT_TIME, and GST_FORMAT_DEFAULT. For
+ * raw audio, GST_FORMAT_DEFAULT corresponds to audio frames. This
+ * function can be used to handle pad queries of the type GST_QUERY_CONVERT.
+ *
+ * Returns: TRUE if the conversion was successful.
+ */
+gboolean
+gst_audio_info_convert (const GstAudioInfo * info,
+ GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
+{
+ gboolean res = TRUE;
+ gint bpf, rate;
+
+ GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s (%d) to %s (%d)",
+ src_val, gst_format_get_name (src_fmt), src_fmt,
+ gst_format_get_name (dest_fmt), dest_fmt);
+
+ if (src_fmt == dest_fmt || src_val == -1) {
+ *dest_val = src_val;
+ goto done;
+ }
+
+ /* get important info */
+ bpf = GST_AUDIO_INFO_BPF (info);
+ rate = GST_AUDIO_INFO_RATE (info);
+
+ if (bpf == 0 || rate == 0) {
+ GST_DEBUG ("no rate or bpf configured");
+ res = FALSE;
+ goto done;
+ }
+
+ switch (src_fmt) {
+ case GST_FORMAT_BYTES:
+ switch (dest_fmt) {
+ case GST_FORMAT_TIME:
+ *dest_val = GST_FRAMES_TO_CLOCK_TIME (src_val / bpf, rate);
+ break;
+ case GST_FORMAT_DEFAULT:
+ *dest_val = src_val / bpf;
+ break;
+ default:
+ res = FALSE;
+ break;
+ }
+ break;
+ case GST_FORMAT_DEFAULT:
+ switch (dest_fmt) {
+ case GST_FORMAT_TIME:
+ *dest_val = GST_FRAMES_TO_CLOCK_TIME (src_val, rate);
+ break;
+ case GST_FORMAT_BYTES:
+ *dest_val = src_val * bpf;
+ break;
+ default:
+ res = FALSE;
+ break;
+ }
+ break;
+ case GST_FORMAT_TIME:
+ switch (dest_fmt) {
+ case GST_FORMAT_DEFAULT:
+ *dest_val = GST_CLOCK_TIME_TO_FRAMES (src_val, rate);
+ break;
+ case GST_FORMAT_BYTES:
+ *dest_val = GST_CLOCK_TIME_TO_FRAMES (src_val, rate);
+ *dest_val *= bpf;
+ break;
+ default:
+ res = FALSE;
+ break;
+ }
+ break;
+ default:
+ res = FALSE;
+ break;
+ }
+done:
+ GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, res, *dest_val);
+
+ return res;
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Library <2001> Thomas Vander Stichele <thomas@apestaart.org>
+ * <2011> Wim Taymans <wim.taymans@gmail.com>
+ *
+ * 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.
+ */
+
+#ifndef __GST_AUDIO_INFO_H__
+#define __GST_AUDIO_INFO_H__
+
+#include <gst/gst.h>
+#include <gst/audio/audio-enumtypes.h>
+#include <gst/audio/audio-format.h>
+#include <gst/audio/audio-channels.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstAudioInfo GstAudioInfo;
+
+/**
+ * GstAudioFlags:
+ * @GST_AUDIO_FLAG_NONE: no valid flag
+ * @GST_AUDIO_FLAG_UNPOSITIONED: the position array explicitly
+ * contains unpositioned channels.
+ *
+ * Extra audio flags
+ */
+typedef enum {
+ GST_AUDIO_FLAG_NONE = 0,
+ GST_AUDIO_FLAG_UNPOSITIONED = (1 << 0)
+} GstAudioFlags;
+
+/**
+ * GstAudioLayout:
+ * @GST_AUDIO_LAYOUT_INTERLEAVED: interleaved audio
+ * @GST_AUDIO_LAYOUT_NON_INTERLEAVED: non-interleaved audio
+ *
+ * Layout of the audio samples for the different channels.
+ */
+typedef enum {
+ GST_AUDIO_LAYOUT_INTERLEAVED = 0,
+ GST_AUDIO_LAYOUT_NON_INTERLEAVED
+} GstAudioLayout;
+
+/**
+ * GstAudioInfo:
+ * @finfo: the format info of the audio
+ * @flags: additional audio flags
+ * @layout: audio layout
+ * @rate: the audio sample rate
+ * @channels: the number of channels
+ * @bpf: the number of bytes for one frame, this is the size of one
+ * sample * @channels
+ * @position: the positions for each channel
+ *
+ * Information describing audio properties. This information can be filled
+ * in from GstCaps with gst_audio_info_from_caps().
+ *
+ * Use the provided macros to access the info in this structure.
+ */
+struct _GstAudioInfo {
+ const GstAudioFormatInfo *finfo;
+ GstAudioFlags flags;
+ GstAudioLayout layout;
+ gint rate;
+ gint channels;
+ gint bpf;
+ GstAudioChannelPosition position[64];
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GType gst_audio_info_get_type (void);
+
+#define GST_AUDIO_INFO_IS_VALID(i) ((i)->finfo != NULL && (i)->rate > 0 && (i)->channels > 0 && (i)->bpf > 0)
+
+#define GST_AUDIO_INFO_FORMAT(i) (GST_AUDIO_FORMAT_INFO_FORMAT((i)->finfo))
+#define GST_AUDIO_INFO_NAME(i) (GST_AUDIO_FORMAT_INFO_NAME((i)->finfo))
+#define GST_AUDIO_INFO_WIDTH(i) (GST_AUDIO_FORMAT_INFO_WIDTH((i)->finfo))
+#define GST_AUDIO_INFO_DEPTH(i) (GST_AUDIO_FORMAT_INFO_DEPTH((i)->finfo))
+#define GST_AUDIO_INFO_BPS(info) (GST_AUDIO_INFO_DEPTH(info) >> 3)
+
+#define GST_AUDIO_INFO_IS_INTEGER(i) (GST_AUDIO_FORMAT_INFO_IS_INTEGER((i)->finfo))
+#define GST_AUDIO_INFO_IS_FLOAT(i) (GST_AUDIO_FORMAT_INFO_IS_FLOAT((i)->finfo))
+#define GST_AUDIO_INFO_IS_SIGNED(i) (GST_AUDIO_FORMAT_INFO_IS_SIGNED((i)->finfo))
+
+#define GST_AUDIO_INFO_ENDIANNESS(i) (GST_AUDIO_FORMAT_INFO_ENDIANNES((i)->finfo))
+#define GST_AUDIO_INFO_IS_LITTLE_ENDIAN(i) (GST_AUDIO_FORMAT_INFO_IS_LITTLE_ENDIAN((i)->finfo))
+#define GST_AUDIO_INFO_IS_BIG_ENDIAN(i) (GST_AUDIO_FORMAT_INFO_IS_BIG_ENDIAN((i)->finfo))
+
+#define GST_AUDIO_INFO_FLAGS(info) ((info)->flags)
+#define GST_AUDIO_INFO_IS_UNPOSITIONED(info) ((info)->flags & GST_AUDIO_FLAG_UNPOSITIONED)
+#define GST_AUDIO_INFO_LAYOUT(info) ((info)->layout)
+
+#define GST_AUDIO_INFO_RATE(info) ((info)->rate)
+#define GST_AUDIO_INFO_CHANNELS(info) ((info)->channels)
+#define GST_AUDIO_INFO_BPF(info) ((info)->bpf)
+#define GST_AUDIO_INFO_POSITION(info,c) ((info)->position[c])
+
+GstAudioInfo * gst_audio_info_new (void);
+void gst_audio_info_init (GstAudioInfo *info);
+GstAudioInfo * gst_audio_info_copy (const GstAudioInfo *info);
+void gst_audio_info_free (GstAudioInfo *info);
+
+void gst_audio_info_set_format (GstAudioInfo *info, GstAudioFormat format,
+ gint rate, gint channels,
+ const GstAudioChannelPosition *position);
+
+gboolean gst_audio_info_from_caps (GstAudioInfo *info, const GstCaps *caps);
+GstCaps * gst_audio_info_to_caps (const GstAudioInfo *info);
+
+gboolean gst_audio_info_convert (const GstAudioInfo * info,
+ GstFormat src_fmt, gint64 src_val,
+ GstFormat dest_fmt, gint64 * dest_val);
+
+G_END_DECLS
+
+#endif /* __GST_AUDIO_INFO_H__ */
#include "audio.h"
#include "audio-enumtypes.h"
-#include <gst/gststructure.h>
-
-#define SINT (GST_AUDIO_FORMAT_FLAG_INTEGER | GST_AUDIO_FORMAT_FLAG_SIGNED)
-#define UINT (GST_AUDIO_FORMAT_FLAG_INTEGER)
-
-#define MAKE_FORMAT(str,desc,flags,end,width,depth,silent) \
- { GST_AUDIO_FORMAT_ ##str, G_STRINGIFY(str), desc, flags, end, width, depth, silent }
-
-#define SILENT_0 { 0, 0, 0, 0, 0, 0, 0, 0 }
-#define SILENT_U8 { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }
-#define SILENT_U16LE { 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80 }
-#define SILENT_U16BE { 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 }
-#define SILENT_U24_32LE { 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00 }
-#define SILENT_U24_32BE { 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00 }
-#define SILENT_U32LE { 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80 }
-#define SILENT_U32BE { 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }
-#define SILENT_U24LE { 0x00, 0x00, 0x80, 0x00, 0x00, 0x80 }
-#define SILENT_U24BE { 0x80, 0x00, 0x00, 0x80, 0x00, 0x00 }
-#define SILENT_U20LE { 0x00, 0x00, 0x08, 0x00, 0x00, 0x08 }
-#define SILENT_U20BE { 0x08, 0x00, 0x00, 0x08, 0x00, 0x00 }
-#define SILENT_U18LE { 0x00, 0x00, 0x02, 0x00, 0x00, 0x02 }
-#define SILENT_U18BE { 0x02, 0x00, 0x00, 0x02, 0x00, 0x00 }
-
-static GstAudioFormatInfo formats[] = {
- {GST_AUDIO_FORMAT_UNKNOWN, "UNKNOWN", 0, 0, 0, 0},
- /* 8 bit */
- MAKE_FORMAT (S8, "8-bit signed PCM audio", SINT, 0, 8, 8, SILENT_0),
- MAKE_FORMAT (U8, "8-bit unsigned PCM audio", UINT, 0, 8, 8, SILENT_U8),
- /* 16 bit */
- MAKE_FORMAT (S16LE, "16-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 16, 16,
- SILENT_0),
- MAKE_FORMAT (S16BE, "16-bit signed PCM audio", SINT, G_BIG_ENDIAN, 16, 16,
- SILENT_0),
- MAKE_FORMAT (U16LE, "16-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 16,
- 16, SILENT_U16LE),
- MAKE_FORMAT (U16BE, "16-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 16, 16,
- SILENT_U16BE),
- /* 24 bit in low 3 bytes of 32 bits */
- MAKE_FORMAT (S24_32LE, "24-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 32,
- 24, SILENT_0),
- MAKE_FORMAT (S24_32BE, "24-bit signed PCM audio", SINT, G_BIG_ENDIAN, 32, 24,
- SILENT_0),
- MAKE_FORMAT (U24_32LE, "24-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 32,
- 24, SILENT_U24_32LE),
- MAKE_FORMAT (U24_32BE, "24-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 32,
- 24, SILENT_U24_32BE),
- /* 32 bit */
- MAKE_FORMAT (S32LE, "32-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 32, 32,
- SILENT_0),
- MAKE_FORMAT (S32BE, "32-bit signed PCM audio", SINT, G_BIG_ENDIAN, 32, 32,
- SILENT_0),
- MAKE_FORMAT (U32LE, "32-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 32,
- 32, SILENT_U32LE),
- MAKE_FORMAT (U32BE, "32-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 32, 32,
- SILENT_U32BE),
- /* 24 bit in 3 bytes */
- MAKE_FORMAT (S24LE, "24-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 24, 24,
- SILENT_0),
- MAKE_FORMAT (S24BE, "24-bit signed PCM audio", SINT, G_BIG_ENDIAN, 24, 24,
- SILENT_0),
- MAKE_FORMAT (U24LE, "24-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 24,
- 24, SILENT_U24LE),
- MAKE_FORMAT (U24BE, "24-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 24, 24,
- SILENT_U24BE),
- /* 20 bit in 3 bytes */
- MAKE_FORMAT (S20LE, "20-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 24, 20,
- SILENT_0),
- MAKE_FORMAT (S20BE, "20-bit signed PCM audio", SINT, G_BIG_ENDIAN, 24, 20,
- SILENT_0),
- MAKE_FORMAT (U20LE, "20-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 24,
- 20, SILENT_U20LE),
- MAKE_FORMAT (U20BE, "20-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 24, 20,
- SILENT_U20BE),
- /* 18 bit in 3 bytes */
- MAKE_FORMAT (S18LE, "18-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 24, 18,
- SILENT_0),
- MAKE_FORMAT (S18BE, "18-bit signed PCM audio", SINT, G_BIG_ENDIAN, 24, 18,
- SILENT_0),
- MAKE_FORMAT (U18LE, "18-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN, 24,
- 18, SILENT_U18LE),
- MAKE_FORMAT (U18BE, "18-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 24, 18,
- SILENT_U18BE),
- /* float */
- MAKE_FORMAT (F32LE, "32-bit floating-point audio",
- GST_AUDIO_FORMAT_FLAG_FLOAT, G_LITTLE_ENDIAN, 32, 32,
- SILENT_0),
- MAKE_FORMAT (F32BE, "32-bit floating-point audio",
- GST_AUDIO_FORMAT_FLAG_FLOAT, G_BIG_ENDIAN, 32, 32,
- SILENT_0),
- MAKE_FORMAT (F64LE, "64-bit floating-point audio",
- GST_AUDIO_FORMAT_FLAG_FLOAT, G_LITTLE_ENDIAN, 64, 64,
- SILENT_0),
- MAKE_FORMAT (F64BE, "64-bit floating-point audio",
- GST_AUDIO_FORMAT_FLAG_FLOAT, G_BIG_ENDIAN, 64, 64,
- SILENT_0)
-};
-
-G_DEFINE_POINTER_TYPE (GstAudioFormatInfo, gst_audio_format_info);
-
-/**
- * gst_audio_format_build_integer:
- * @sign: signed or unsigned format
- * @endianness: G_LITTLE_ENDIAN or G_BIG_ENDIAN
- * @width: amount of bits used per sample
- * @depth: amount of used bits in @width
- *
- * Construct a #GstAudioFormat with given parameters.
- *
- * Returns: a #GstAudioFormat or GST_AUDIO_FORMAT_UNKNOWN when no audio format
- * exists with the given parameters.
- */
-GstAudioFormat
-gst_audio_format_build_integer (gboolean sign, gint endianness,
- gint width, gint depth)
-{
- gint i, e;
-
- for (i = 0; i < G_N_ELEMENTS (formats); i++) {
- GstAudioFormatInfo *finfo = &formats[i];
-
- /* must be int */
- if (!GST_AUDIO_FORMAT_INFO_IS_INTEGER (finfo))
- continue;
-
- /* width and depth must match */
- if (width != GST_AUDIO_FORMAT_INFO_WIDTH (finfo))
- continue;
- if (depth != GST_AUDIO_FORMAT_INFO_DEPTH (finfo))
- continue;
-
- /* if there is endianness, it must match */
- e = GST_AUDIO_FORMAT_INFO_ENDIANNESS (finfo);
- if (e && e != endianness)
- continue;
-
- /* check sign */
- if ((sign && !GST_AUDIO_FORMAT_INFO_IS_SIGNED (finfo)) ||
- (!sign && GST_AUDIO_FORMAT_INFO_IS_SIGNED (finfo)))
- continue;
-
- return GST_AUDIO_FORMAT_INFO_FORMAT (finfo);
- }
- return GST_AUDIO_FORMAT_UNKNOWN;
-}
-
-/**
- * gst_audio_format_from_string:
- * @format: a format string
- *
- * Convert the @format string to its #GstAudioFormat.
- *
- * Returns: the #GstAudioFormat for @format or GST_AUDIO_FORMAT_UNKNOWN when the
- * string is not a known format.
- */
-GstAudioFormat
-gst_audio_format_from_string (const gchar * format)
-{
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (formats); i++) {
- if (strcmp (GST_AUDIO_FORMAT_INFO_NAME (&formats[i]), format) == 0)
- return GST_AUDIO_FORMAT_INFO_FORMAT (&formats[i]);
- }
- return GST_AUDIO_FORMAT_UNKNOWN;
-}
-
-const gchar *
-gst_audio_format_to_string (GstAudioFormat format)
-{
- g_return_val_if_fail (format != GST_AUDIO_FORMAT_UNKNOWN, NULL);
-
- if (format >= G_N_ELEMENTS (formats))
- return NULL;
-
- return GST_AUDIO_FORMAT_INFO_NAME (&formats[format]);
-}
-
-/**
- * gst_audio_format_get_info:
- * @format: a #GstAudioFormat
- *
- * Get the #GstAudioFormatInfo for @format
- *
- * Returns: The #GstAudioFormatInfo for @format.
- */
-const GstAudioFormatInfo *
-gst_audio_format_get_info (GstAudioFormat format)
-{
- g_return_val_if_fail (format != GST_AUDIO_FORMAT_UNKNOWN, NULL);
- g_return_val_if_fail (format < G_N_ELEMENTS (formats), NULL);
-
- return &formats[format];
-}
-
-/**
- * gst_audio_format_fill_silence:
- * @info: a #GstAudioFormatInfo
- * @dest: a destination to fill
- * @length: the length to fill
- *
- * Fill @length bytes in @dest with silence samples for @info.
- */
-void
-gst_audio_format_fill_silence (const GstAudioFormatInfo * info,
- gpointer dest, gsize length)
-{
- guint8 *dptr = dest;
-
- g_return_if_fail (info != NULL);
- g_return_if_fail (dest != NULL);
-
- if (info->flags & GST_AUDIO_FORMAT_FLAG_FLOAT ||
- info->flags & GST_AUDIO_FORMAT_FLAG_SIGNED) {
- /* float or signed always 0 */
- memset (dest, 0, length);
- } else {
- gint i, j, bps = info->width >> 3;
-
- switch (bps) {
- case 1:
- memset (dest, info->silence[0], length);
- break;
- default:
- for (i = 0; i < length; i += bps) {
- for (j = 0; j < bps; j++)
- *dptr++ = info->silence[j];
- }
- break;
- }
- }
-}
-
-/**
- * gst_audio_info_copy:
- * @info: a #GstAudioInfo
- *
- * Copy a GstAudioInfo structure.
- *
- * Returns: a new #GstAudioInfo. free with gst_audio_info_free.
- */
-GstAudioInfo *
-gst_audio_info_copy (const GstAudioInfo * info)
-{
- return g_slice_dup (GstAudioInfo, info);
-}
-
-/**
- * gst_audio_info_free:
- * @info: a #GstAudioInfo
- *
- * Free a GstAudioInfo structure previously allocated with gst_audio_info_new()
- * or gst_audio_info_copy().
- */
-void
-gst_audio_info_free (GstAudioInfo * info)
-{
- g_slice_free (GstAudioInfo, info);
-}
-
-G_DEFINE_BOXED_TYPE (GstAudioInfo, gst_audio_info,
- (GBoxedCopyFunc) gst_audio_info_copy, (GBoxedFreeFunc) gst_audio_info_free);
-
-/**
- * gst_audio_info_new:
- *
- * Allocate a new #GstAudioInfo that is also initialized with
- * gst_audio_info_init().
- *
- * Returns: a new #GstAudioInfo. free with gst_audio_info_free().
- */
-GstAudioInfo *
-gst_audio_info_new (void)
-{
- GstAudioInfo *info;
-
- info = g_slice_new (GstAudioInfo);
- gst_audio_info_init (info);
-
- return info;
-}
-
-/**
- * gst_audio_info_init:
- * @info: a #GstAudioInfo
- *
- * Initialize @info with default values.
- */
-void
-gst_audio_info_init (GstAudioInfo * info)
-{
- g_return_if_fail (info != NULL);
-
- memset (info, 0, sizeof (GstAudioInfo));
-
- info->finfo = &formats[GST_AUDIO_FORMAT_UNKNOWN];
-
- memset (&info->position, 0xff, sizeof (info->position));
-}
-
-static const GstAudioChannelPosition default_channel_order[64] = {
- GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
- GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
- GST_AUDIO_CHANNEL_POSITION_LFE1,
- GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
- GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
- GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
- GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
- GST_AUDIO_CHANNEL_POSITION_LFE2,
- GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
- GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT,
- GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER,
- GST_AUDIO_CHANNEL_POSITION_TOP_CENTER,
- GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT,
- GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT,
- GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER,
- GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER,
- GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT,
- GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT,
- GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT,
- GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID,
- GST_AUDIO_CHANNEL_POSITION_INVALID
-};
-
-static gboolean
-check_valid_channel_positions (const GstAudioChannelPosition * position,
- gint channels, gboolean enforce_order, guint64 * channel_mask_out)
-{
- gint i, j;
- guint64 channel_mask = 0;
-
- if (channels == 1 && position[0] == GST_AUDIO_CHANNEL_POSITION_MONO) {
- if (channel_mask_out)
- *channel_mask_out = 0;
- return TRUE;
- }
-
- if (channels > 0 && position[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
- if (channel_mask_out)
- *channel_mask_out = 0;
- return TRUE;
- }
-
- j = 0;
- for (i = 0; i < channels; i++) {
- while (j < G_N_ELEMENTS (default_channel_order)
- && default_channel_order[j] != position[i])
- j++;
-
- if (position[i] == GST_AUDIO_CHANNEL_POSITION_INVALID ||
- position[i] == GST_AUDIO_CHANNEL_POSITION_MONO ||
- position[i] == GST_AUDIO_CHANNEL_POSITION_NONE)
- return FALSE;
-
- /* Is this in valid channel order? */
- if (enforce_order && j == G_N_ELEMENTS (default_channel_order))
- return FALSE;
- j++;
-
- if ((channel_mask & (G_GUINT64_CONSTANT (1) << position[i])))
- return FALSE;
-
- channel_mask |= (G_GUINT64_CONSTANT (1) << position[i]);
- }
-
- if (channel_mask_out)
- *channel_mask_out = channel_mask;
-
- return TRUE;
-}
-
-/**
- * gst_audio_info_set_format:
- * @info: a #GstAudioInfo
- * @format: the format
- * @rate: the samplerate
- * @channels: the number of channels
- * @position: the channel positions
- *
- * Set the default info for the audio info of @format and @rate and @channels.
- */
-void
-gst_audio_info_set_format (GstAudioInfo * info, GstAudioFormat format,
- gint rate, gint channels, const GstAudioChannelPosition * position)
-{
- const GstAudioFormatInfo *finfo;
- gint i;
-
- g_return_if_fail (info != NULL);
- g_return_if_fail (format != GST_AUDIO_FORMAT_UNKNOWN);
-
- finfo = &formats[format];
-
- info->flags = 0;
- info->layout = GST_AUDIO_LAYOUT_INTERLEAVED;
- info->finfo = finfo;
- info->rate = rate;
- info->channels = channels;
- info->bpf = (finfo->width * channels) / 8;
-
- memset (&info->position, 0xff, sizeof (info->position));
-
- if (!position && channels == 1) {
- info->position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
- return;
- } else if (!position && channels == 2) {
- info->position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
- info->position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
- return;
- } else {
- if (!position
- || !check_valid_channel_positions (position, channels, TRUE, NULL)) {
- if (position)
- g_warning ("Invalid channel positions");
- } else {
- memcpy (&info->position, position,
- info->channels * sizeof (info->position[0]));
- if (info->position[0] == GST_AUDIO_CHANNEL_POSITION_NONE)
- info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
- return;
- }
- }
-
- /* Otherwise a NONE layout */
- info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
- for (i = 0; i < MIN (64, channels); i++)
- info->position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
-}
-
-/**
- * gst_audio_info_from_caps:
- * @info: a #GstAudioInfo
- * @caps: a #GstCaps
- *
- * Parse @caps and update @info.
- *
- * Returns: TRUE if @caps could be parsed
- */
-gboolean
-gst_audio_info_from_caps (GstAudioInfo * info, const GstCaps * caps)
-{
- GstStructure *str;
- const gchar *s;
- GstAudioFormat format;
- gint rate, channels;
- guint64 channel_mask;
- gint i;
- GstAudioChannelPosition position[64];
-
- g_return_val_if_fail (info != NULL, FALSE);
- g_return_val_if_fail (caps != NULL, FALSE);
- g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
-
- GST_DEBUG ("parsing caps %" GST_PTR_FORMAT, caps);
-
- info->flags = 0;
-
- str = gst_caps_get_structure (caps, 0);
-
- if (!gst_structure_has_name (str, "audio/x-raw"))
- goto wrong_name;
-
- if (!(s = gst_structure_get_string (str, "format")))
- goto no_format;
-
- format = gst_audio_format_from_string (s);
- if (format == GST_AUDIO_FORMAT_UNKNOWN)
- goto unknown_format;
-
- if (!(s = gst_structure_get_string (str, "layout")))
- goto no_layout;
- if (g_str_equal (s, "interleaved"))
- info->layout = GST_AUDIO_LAYOUT_INTERLEAVED;
- else if (g_str_equal (s, "non-interleaved"))
- info->layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
- else
- goto unknown_layout;
-
- if (!gst_structure_get_int (str, "rate", &rate))
- goto no_rate;
- if (!gst_structure_get_int (str, "channels", &channels))
- goto no_channels;
-
- if (!gst_structure_get (str, "channel-mask", GST_TYPE_BITMASK, &channel_mask,
- NULL)) {
- if (channels == 1) {
- position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
- } else if (channels == 2) {
- position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
- position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
- } else {
- goto no_channel_mask;
- }
- } else if (channel_mask == 0) {
- info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
- for (i = 0; i < MIN (64, channels); i++)
- position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
- } else {
- if (!gst_audio_channel_positions_from_mask (channels, channel_mask,
- position))
- goto invalid_channel_mask;
- }
-
- gst_audio_info_set_format (info, format, rate, channels, position);
-
- return TRUE;
-
- /* ERROR */
-wrong_name:
- {
- GST_ERROR ("wrong name, expected audio/x-raw");
- return FALSE;
- }
-no_format:
- {
- GST_ERROR ("no format given");
- return FALSE;
- }
-unknown_format:
- {
- GST_ERROR ("unknown format given");
- return FALSE;
- }
-no_layout:
- {
- GST_ERROR ("no layout given");
- return FALSE;
- }
-unknown_layout:
- {
- GST_ERROR ("unknown layout given");
- return FALSE;
- }
-no_rate:
- {
- GST_ERROR ("no rate property given");
- return FALSE;
- }
-no_channels:
- {
- GST_ERROR ("no channels property given");
- return FALSE;
- }
-no_channel_mask:
- {
- GST_ERROR ("no channel-mask property given");
- return FALSE;
- }
-invalid_channel_mask:
- {
- GST_ERROR ("Invalid channel mask 0x%016" G_GINT64_MODIFIER
- "x for %d channels", channel_mask, channels);
- return FALSE;
- }
-}
-
-/**
- * gst_audio_info_to_caps:
- * @info: a #GstAudioInfo
- *
- * Convert the values of @info into a #GstCaps.
- *
- * Returns: (transfer full): the new #GstCaps containing the
- * info of @info.
- */
-GstCaps *
-gst_audio_info_to_caps (const GstAudioInfo * info)
-{
- GstCaps *caps;
- const gchar *format;
- const gchar *layout;
- GstAudioFlags flags;
-
- g_return_val_if_fail (info != NULL, NULL);
- g_return_val_if_fail (info->finfo != NULL, NULL);
- g_return_val_if_fail (info->finfo->format != GST_AUDIO_FORMAT_UNKNOWN, NULL);
-
- format = gst_audio_format_to_string (info->finfo->format);
- g_return_val_if_fail (format != NULL, NULL);
-
- if (info->layout == GST_AUDIO_LAYOUT_INTERLEAVED)
- layout = "interleaved";
- else if (info->layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED)
- layout = "non-interleaved";
- else
- g_return_val_if_reached (NULL);
-
- flags = info->flags;
- if ((flags & GST_AUDIO_FLAG_UNPOSITIONED) && info->channels > 1
- && info->position[0] != GST_AUDIO_CHANNEL_POSITION_NONE) {
- flags &= ~GST_AUDIO_FLAG_UNPOSITIONED;
- g_warning ("Unpositioned audio channel position flag set but "
- "channel positions present");
- } else if (!(flags & GST_AUDIO_FLAG_UNPOSITIONED) && info->channels > 1
- && info->position[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
- flags |= GST_AUDIO_FLAG_UNPOSITIONED;
- g_warning ("Unpositioned audio channel position flag not set "
- "but no channel positions present");
- }
-
- caps = gst_caps_new_simple ("audio/x-raw",
- "format", G_TYPE_STRING, format,
- "layout", G_TYPE_STRING, layout,
- "rate", G_TYPE_INT, info->rate,
- "channels", G_TYPE_INT, info->channels, NULL);
-
- if (info->channels > 1
- || info->position[0] != GST_AUDIO_CHANNEL_POSITION_MONO) {
- guint64 channel_mask = 0;
-
- if ((flags & GST_AUDIO_FLAG_UNPOSITIONED)) {
- channel_mask = 0;
- } else {
- if (!check_valid_channel_positions (info->position, info->channels,
- TRUE, &channel_mask))
- goto invalid_channel_positions;
- }
-
- if (info->channels == 1
- && info->position[0] == GST_AUDIO_CHANNEL_POSITION_MONO) {
- /* Default mono special case */
- } else {
- gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
- NULL);
- }
- }
-
- return caps;
-
-invalid_channel_positions:
- {
- GST_ERROR ("Invalid channel positions");
- gst_caps_unref (caps);
- return NULL;
- }
-}
-
-/**
- * gst_audio_format_convert:
- * @info: a #GstAudioInfo
- * @src_format: #GstFormat of the @src_value
- * @src_value: value to convert
- * @dest_format: #GstFormat of the @dest_value
- * @dest_value: pointer to destination value
- *
- * Converts among various #GstFormat types. This function handles
- * GST_FORMAT_BYTES, GST_FORMAT_TIME, and GST_FORMAT_DEFAULT. For
- * raw audio, GST_FORMAT_DEFAULT corresponds to audio frames. This
- * function can be used to handle pad queries of the type GST_QUERY_CONVERT.
- *
- * Returns: TRUE if the conversion was successful.
- */
-gboolean
-gst_audio_info_convert (const GstAudioInfo * info,
- GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
-{
- gboolean res = TRUE;
- gint bpf, rate;
-
- GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s (%d) to %s (%d)",
- src_val, gst_format_get_name (src_fmt), src_fmt,
- gst_format_get_name (dest_fmt), dest_fmt);
-
- if (src_fmt == dest_fmt || src_val == -1) {
- *dest_val = src_val;
- goto done;
- }
-
- /* get important info */
- bpf = GST_AUDIO_INFO_BPF (info);
- rate = GST_AUDIO_INFO_RATE (info);
-
- if (bpf == 0 || rate == 0) {
- GST_DEBUG ("no rate or bpf configured");
- res = FALSE;
- goto done;
- }
-
- switch (src_fmt) {
- case GST_FORMAT_BYTES:
- switch (dest_fmt) {
- case GST_FORMAT_TIME:
- *dest_val = GST_FRAMES_TO_CLOCK_TIME (src_val / bpf, rate);
- break;
- case GST_FORMAT_DEFAULT:
- *dest_val = src_val / bpf;
- break;
- default:
- res = FALSE;
- break;
- }
- break;
- case GST_FORMAT_DEFAULT:
- switch (dest_fmt) {
- case GST_FORMAT_TIME:
- *dest_val = GST_FRAMES_TO_CLOCK_TIME (src_val, rate);
- break;
- case GST_FORMAT_BYTES:
- *dest_val = src_val * bpf;
- break;
- default:
- res = FALSE;
- break;
- }
- break;
- case GST_FORMAT_TIME:
- switch (dest_fmt) {
- case GST_FORMAT_DEFAULT:
- *dest_val = GST_CLOCK_TIME_TO_FRAMES (src_val, rate);
- break;
- case GST_FORMAT_BYTES:
- *dest_val = GST_CLOCK_TIME_TO_FRAMES (src_val, rate);
- *dest_val *= bpf;
- break;
- default:
- res = FALSE;
- break;
- }
- break;
- default:
- res = FALSE;
- break;
- }
-done:
- GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, res, *dest_val);
-
- return res;
-}
-
/**
* gst_audio_buffer_clip:
* @buffer: The buffer to clip.
}
return ret;
}
-
-/**
- * gst_audio_reorder_channels:
- * @data: The pointer to the memory.
- * @size: The size of the memory.
- * @format: The %GstAudioFormat of the buffer.
- * @channels: The number of channels.
- * @from: The channel positions in the buffer.
- * @to: The channel positions to convert to.
- *
- * Reorders @data from the channel positions @from to the channel
- * positions @to. @from and @to must contain the same number of
- * positions and the same positions, only in a different order.
- *
- * Returns: %TRUE if the reordering was possible.
- */
-gboolean
-gst_audio_reorder_channels (gpointer data, gsize size, GstAudioFormat format,
- gint channels, const GstAudioChannelPosition * from,
- const GstAudioChannelPosition * to)
-{
- const GstAudioFormatInfo *info;
- gint i, j, n;
- gint reorder_map[64] = { 0, };
- guint8 *ptr;
- gint bpf, bps;
- guint8 tmp[64 * 8];
-
- info = gst_audio_format_get_info (format);
-
- g_return_val_if_fail (data != NULL, FALSE);
- g_return_val_if_fail (from != NULL, FALSE);
- g_return_val_if_fail (to != NULL, FALSE);
- g_return_val_if_fail (info != NULL && info->width > 0, FALSE);
- g_return_val_if_fail (info->width > 0, FALSE);
- g_return_val_if_fail (info->width <= 8 * 64, FALSE);
- g_return_val_if_fail (size % ((info->width * channels) / 8) == 0, FALSE);
- g_return_val_if_fail (channels > 0, FALSE);
- g_return_val_if_fail (channels <= 64, FALSE);
-
- if (size == 0)
- return TRUE;
-
- if (memcmp (from, to, channels * sizeof (from[0])) == 0)
- return TRUE;
-
- if (!gst_audio_get_channel_reorder_map (channels, from, to, reorder_map))
- return FALSE;
-
- bps = info->width / 8;
- bpf = bps * channels;
- ptr = data;
-
- n = size / bpf;
- for (i = 0; i < n; i++) {
-
- memcpy (tmp, ptr, bpf);
- for (j = 0; j < channels; j++)
- memcpy (ptr + reorder_map[j] * bps, tmp + j * bps, bps);
-
- ptr += bpf;
- }
-
- return TRUE;
-}
-
-/**
- * gst_audio_buffer_reorder_channels:
- * @buffer: The buffer to reorder.
- * @format: The %GstAudioFormat of the buffer.
- * @channels: The number of channels.
- * @from: The channel positions in the buffer.
- * @to: The channel positions to convert to.
- *
- * Reorders @buffer from the channel positions @from to the channel
- * positions @to. @from and @to must contain the same number of
- * positions and the same positions, only in a different order.
- * @buffer must be writable.
- *
- * Returns: %TRUE if the reordering was possible.
- */
-gboolean
-gst_audio_buffer_reorder_channels (GstBuffer * buffer,
- GstAudioFormat format, gint channels,
- const GstAudioChannelPosition * from, const GstAudioChannelPosition * to)
-{
- GstMapInfo info;
- gboolean ret;
-
- g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
- g_return_val_if_fail (gst_buffer_is_writable (buffer), FALSE);
-
- gst_buffer_map (buffer, &info, GST_MAP_READWRITE);
-
- ret =
- gst_audio_reorder_channels (info.data, info.size, format, channels, from,
- to);
-
- gst_buffer_unmap (buffer, &info);
-
- return ret;
-}
-
-/**
- * gst_audio_check_valid_channel_positions:
- * @position: The %GstAudioChannelPositions to check.
- * @channels: The number of channels.
- * @force_order: Only consider the GStreamer channel order.
- *
- * Checks if @position contains valid channel positions for
- * @channels channels. If @force_order is %TRUE it additionally
- * checks if the channels are in the order required by GStreamer.
- *
- * Returns: %TRUE if the channel positions are valid.
- */
-gboolean
-gst_audio_check_valid_channel_positions (const GstAudioChannelPosition *
- position, gint channels, gboolean force_order)
-{
- return check_valid_channel_positions (position, channels, force_order, NULL);
-}
-
-/**
- * gst_audio_channel_positions_to_mask:
- * @position: The %GstAudioChannelPositions
- * @channels: The number of channels.
- * @channel_mask: the output channel mask
- *
- * Convert the @position array of @channels channels to a bitmask.
- *
- * Returns: %TRUE if the channel positions are valid and could be converted.
- */
-gboolean
-gst_audio_channel_positions_to_mask (const GstAudioChannelPosition * position,
- gint channels, guint64 * channel_mask)
-{
- return check_valid_channel_positions (position, channels, FALSE,
- channel_mask);
-}
-
-/**
- * gst_audio_channel_positions_from_mask:
- * @channels: The number of channels
- * @channel_mask: The input channel_mask
- * @position: The %GstAudioChannelPositions
- * @caps: a #GstCaps
- *
- * Convert the @channels present in @channel_mask to a @position array
- * (which should have at least @channels entries ensured by caller).
- * If @channel_mask is set to 0, it is considered as 'not present' for purpose
- * of conversion.
- *
- * Returns: %TRUE if channel and channel mask are valid and could be converted
- */
-gboolean
-gst_audio_channel_positions_from_mask (gint channels, guint64 channel_mask,
- GstAudioChannelPosition * position)
-{
- g_return_val_if_fail (position != NULL, FALSE);
- g_return_val_if_fail (channels != 0, FALSE);
-
- GST_DEBUG ("converting %d channels for "
- " channel mask 0x%016" G_GINT64_MODIFIER "x", channels, channel_mask);
-
- if (!channel_mask) {
- if (channels == 1) {
- position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
- } else if (channels == 2) {
- position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
- position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
- } else {
- goto no_channel_mask;
- }
- } else {
- gint i, j;
-
- j = 0;
- for (i = 0; i < 64; i++) {
- if ((channel_mask & (G_GUINT64_CONSTANT (1) << i))) {
- if (j < channels)
- position[j] = default_channel_order[i];
- if (default_channel_order[i] == GST_AUDIO_CHANNEL_POSITION_INVALID)
- goto invalid_channel_mask;
- j++;
- }
- }
-
- if (j != channels)
- goto invalid_channel_mask;
- }
-
- return TRUE;
-
- /* ERROR */
-no_channel_mask:
- {
- GST_ERROR ("no channel-mask property given");
- return FALSE;
- }
-invalid_channel_mask:
- {
- GST_ERROR ("Invalid channel mask 0x%016" G_GINT64_MODIFIER
- "x for %d channels", channel_mask, channels);
- return FALSE;
- }
-}
-
-
-/**
- * gst_audio_get_channel_reorder_map:
- * @channels: The number of channels.
- * @from: The channel positions to reorder from.
- * @to: The channel positions to reorder to.
- * @reorder_map: Pointer to the reorder map.
- *
- * Returns a reorder map for @from to @to that can be used in
- * custom channel reordering code, e.g. to convert from or to the
- * GStreamer channel order. @from and @to must contain the same
- * number of positions and the same positions, only in a
- * different order.
- *
- * The resulting @reorder_map can be used for reordering by assigning
- * channel i of the input to channel reorder_map[i] of the output.
- *
- * Returns: %TRUE if the channel positions are valid and reordering
- * is possible.
- */
-gboolean
-gst_audio_get_channel_reorder_map (gint channels,
- const GstAudioChannelPosition * from, const GstAudioChannelPosition * to,
- gint * reorder_map)
-{
- gint i, j;
-
- g_return_val_if_fail (reorder_map != NULL, FALSE);
- g_return_val_if_fail (channels > 0, FALSE);
- g_return_val_if_fail (from != NULL, FALSE);
- g_return_val_if_fail (to != NULL, FALSE);
- g_return_val_if_fail (check_valid_channel_positions (from, channels, FALSE,
- NULL), FALSE);
- g_return_val_if_fail (check_valid_channel_positions (to, channels, FALSE,
- NULL), FALSE);
-
- /* Build reorder map and check compatibility */
- for (i = 0; i < channels; i++) {
- if (from[i] == GST_AUDIO_CHANNEL_POSITION_NONE
- || to[i] == GST_AUDIO_CHANNEL_POSITION_NONE)
- return FALSE;
- if (from[i] == GST_AUDIO_CHANNEL_POSITION_INVALID
- || to[i] == GST_AUDIO_CHANNEL_POSITION_INVALID)
- return FALSE;
- if (from[i] == GST_AUDIO_CHANNEL_POSITION_MONO
- || to[i] == GST_AUDIO_CHANNEL_POSITION_MONO)
- return FALSE;
-
- for (j = 0; j < channels; j++) {
- if (from[i] == to[j]) {
- reorder_map[i] = j;
- break;
- }
- }
-
- /* Not all channels present in both */
- if (j == channels)
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * gst_audio_channel_positions_to_valid_order:
- * @position: The channel positions to reorder to.
- * @channels: The number of channels.
- *
- * Reorders the channel positions in @position from any order to
- * the GStreamer channel order.
- *
- * Returns: %TRUE if the channel positions are valid and reordering
- * was successful.
- */
-gboolean
-gst_audio_channel_positions_to_valid_order (GstAudioChannelPosition * position,
- gint channels)
-{
- GstAudioChannelPosition tmp[64];
- guint64 channel_mask = 0;
- gint i, j;
-
- g_return_val_if_fail (channels > 0, FALSE);
- g_return_val_if_fail (position != NULL, FALSE);
- g_return_val_if_fail (check_valid_channel_positions (position, channels,
- FALSE, NULL), FALSE);
-
- if (channels == 1 && position[0] == GST_AUDIO_CHANNEL_POSITION_MONO)
- return TRUE;
- if (position[0] == GST_AUDIO_CHANNEL_POSITION_NONE)
- return TRUE;
-
- check_valid_channel_positions (position, channels, FALSE, &channel_mask);
-
- memset (tmp, 0xff, sizeof (tmp));
- j = 0;
- for (i = 0; i < 64; i++) {
- if ((channel_mask & (G_GUINT64_CONSTANT (1) << i))) {
- tmp[j] = i;
- j++;
- }
- }
-
- memcpy (position, tmp, sizeof (tmp[0]) * channels);
-
- return TRUE;
-}
* Boston, MA 02111-1307, USA.
*/
-#include <gst/gst.h>
-
#ifndef __GST_AUDIO_AUDIO_H__
#define __GST_AUDIO_AUDIO_H__
-G_BEGIN_DECLS
-
+#include <gst/gst.h>
#include <gst/audio/audio-enumtypes.h>
+#include <gst/audio/audio-format.h>
+#include <gst/audio/audio-channels.h>
+#include <gst/audio/audio-info.h>
-#if G_BYTE_ORDER == G_BIG_ENDIAN
-#define _GST_AUDIO_FORMAT_NE(fmt) GST_AUDIO_FORMAT_ ## fmt ## BE
-#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
-#define _GST_AUDIO_FORMAT_NE(fmt) GST_AUDIO_FORMAT_ ## fmt ## LE
-#endif
-
-/**
- * GstAudioFormat:
- * @GST_AUDIO_FORMAT_UNKNOWN: unknown audio format
- * @GST_AUDIO_FORMAT_S8: 8 bits in 8 bits, signed
- * @GST_AUDIO_FORMAT_U8: 8 bits in 8 bits, unsigned
- * @GST_AUDIO_FORMAT_S16LE: 16 bits in 16 bits, signed, little endian
- * @GST_AUDIO_FORMAT_S16BE: 16 bits in 16 bits, signed, big endian
- * @GST_AUDIO_FORMAT_U16LE: 16 bits in 16 bits, unsigned, little endian
- * @GST_AUDIO_FORMAT_U16BE: 16 bits in 16 bits, unsigned, big endian
- * @GST_AUDIO_FORMAT_S24_32LE: 24 bits in 32 bits, signed, little endian
- * @GST_AUDIO_FORMAT_S24_32BE: 24 bits in 32 bits, signed, big endian
- * @GST_AUDIO_FORMAT_U24_32LE: 24 bits in 32 bits, unsigned, little endian
- * @GST_AUDIO_FORMAT_U24_32BE: 24 bits in 32 bits, unsigned, big endian
- * @GST_AUDIO_FORMAT_S32LE: 32 bits in 32 bits, signed, little endian
- * @GST_AUDIO_FORMAT_S32BE: 32 bits in 32 bits, signed, big endian
- * @GST_AUDIO_FORMAT_U32LE: 32 bits in 32 bits, unsigned, little endian
- * @GST_AUDIO_FORMAT_U32BE: 32 bits in 32 bits, unsigned, big endian
- * @GST_AUDIO_FORMAT_S24LE: 24 bits in 24 bits, signed, little endian
- * @GST_AUDIO_FORMAT_S24BE: 24 bits in 24 bits, signed, big endian
- * @GST_AUDIO_FORMAT_U24LE: 24 bits in 24 bits, unsigned, little endian
- * @GST_AUDIO_FORMAT_U24BE: 24 bits in 24 bits, unsigned, big endian
- * @GST_AUDIO_FORMAT_S20LE: 20 bits in 24 bits, signed, little endian
- * @GST_AUDIO_FORMAT_S20BE: 20 bits in 24 bits, signed, big endian
- * @GST_AUDIO_FORMAT_U20LE: 20 bits in 24 bits, unsigned, little endian
- * @GST_AUDIO_FORMAT_U20BE: 20 bits in 24 bits, unsigned, big endian
- * @GST_AUDIO_FORMAT_S18LE: 18 bits in 24 bits, signed, little endian
- * @GST_AUDIO_FORMAT_S18BE: 18 bits in 24 bits, signed, big endian
- * @GST_AUDIO_FORMAT_U18LE: 18 bits in 24 bits, unsigned, little endian
- * @GST_AUDIO_FORMAT_U18BE: 18 bits in 24 bits, unsigned, big endian
- * @GST_AUDIO_FORMAT_F32LE: 32-bit floating point samples, little endian
- * @GST_AUDIO_FORMAT_F32BE: 32-bit floating point samples, big endian
- * @GST_AUDIO_FORMAT_F64LE: 64-bit floating point samples, little endian
- * @GST_AUDIO_FORMAT_F64BE: 64-bit floating point samples, big endian
- * @GST_AUDIO_FORMAT_S16: 16 bits in 16 bits, signed, native endianness
- * @GST_AUDIO_FORMAT_U16: 16 bits in 16 bits, unsigned, native endianness
- * @GST_AUDIO_FORMAT_S24_32: 24 bits in 32 bits, signed, native endianness
- * @GST_AUDIO_FORMAT_U24_32: 24 bits in 32 bits, unsigned, native endianness
- * @GST_AUDIO_FORMAT_S32: 32 bits in 32 bits, signed, native endianness
- * @GST_AUDIO_FORMAT_U32: 32 bits in 32 bits, unsigned, native endianness
- * @GST_AUDIO_FORMAT_S24: 24 bits in 24 bits, signed, native endianness
- * @GST_AUDIO_FORMAT_U24: 24 bits in 24 bits, unsigned, native endianness
- * @GST_AUDIO_FORMAT_S20: 20 bits in 24 bits, signed, native endianness
- * @GST_AUDIO_FORMAT_U20: 20 bits in 24 bits, unsigned, native endianness
- * @GST_AUDIO_FORMAT_S18: 18 bits in 24 bits, signed, native endianness
- * @GST_AUDIO_FORMAT_U18: 18 bits in 24 bits, unsigned, native endianness
- * @GST_AUDIO_FORMAT_F32: 32-bit floating point samples, native endianness
- * @GST_AUDIO_FORMAT_F64: 64-bit floating point samples, native endianness
- *
- * Enum value describing the most common audio formats.
- */
-typedef enum {
- GST_AUDIO_FORMAT_UNKNOWN,
- /* 8 bit */
- GST_AUDIO_FORMAT_S8,
- GST_AUDIO_FORMAT_U8,
- /* 16 bit */
- GST_AUDIO_FORMAT_S16LE,
- GST_AUDIO_FORMAT_S16BE,
- GST_AUDIO_FORMAT_U16LE,
- GST_AUDIO_FORMAT_U16BE,
- /* 24 bit in low 3 bytes of 32 bits*/
- GST_AUDIO_FORMAT_S24_32LE,
- GST_AUDIO_FORMAT_S24_32BE,
- GST_AUDIO_FORMAT_U24_32LE,
- GST_AUDIO_FORMAT_U24_32BE,
- /* 32 bit */
- GST_AUDIO_FORMAT_S32LE,
- GST_AUDIO_FORMAT_S32BE,
- GST_AUDIO_FORMAT_U32LE,
- GST_AUDIO_FORMAT_U32BE,
- /* 24 bit in 3 bytes*/
- GST_AUDIO_FORMAT_S24LE,
- GST_AUDIO_FORMAT_S24BE,
- GST_AUDIO_FORMAT_U24LE,
- GST_AUDIO_FORMAT_U24BE,
- /* 20 bit in 3 bytes*/
- GST_AUDIO_FORMAT_S20LE,
- GST_AUDIO_FORMAT_S20BE,
- GST_AUDIO_FORMAT_U20LE,
- GST_AUDIO_FORMAT_U20BE,
- /* 18 bit in 3 bytes*/
- GST_AUDIO_FORMAT_S18LE,
- GST_AUDIO_FORMAT_S18BE,
- GST_AUDIO_FORMAT_U18LE,
- GST_AUDIO_FORMAT_U18BE,
- /* float */
- GST_AUDIO_FORMAT_F32LE,
- GST_AUDIO_FORMAT_F32BE,
- GST_AUDIO_FORMAT_F64LE,
- GST_AUDIO_FORMAT_F64BE,
- /* native endianness equivalents */
- GST_AUDIO_FORMAT_S16 = _GST_AUDIO_FORMAT_NE(S16),
- GST_AUDIO_FORMAT_U16 = _GST_AUDIO_FORMAT_NE(U16),
- GST_AUDIO_FORMAT_S24_32 = _GST_AUDIO_FORMAT_NE(S24_32),
- GST_AUDIO_FORMAT_U24_32 = _GST_AUDIO_FORMAT_NE(U24_32),
- GST_AUDIO_FORMAT_S32 = _GST_AUDIO_FORMAT_NE(S32),
- GST_AUDIO_FORMAT_U32 = _GST_AUDIO_FORMAT_NE(U32),
- GST_AUDIO_FORMAT_S24 = _GST_AUDIO_FORMAT_NE(S24),
- GST_AUDIO_FORMAT_U24 = _GST_AUDIO_FORMAT_NE(U24),
- GST_AUDIO_FORMAT_S20 = _GST_AUDIO_FORMAT_NE(S20),
- GST_AUDIO_FORMAT_U20 = _GST_AUDIO_FORMAT_NE(U20),
- GST_AUDIO_FORMAT_S18 = _GST_AUDIO_FORMAT_NE(S18),
- GST_AUDIO_FORMAT_U18 = _GST_AUDIO_FORMAT_NE(U18),
- GST_AUDIO_FORMAT_F32 = _GST_AUDIO_FORMAT_NE(F32),
- GST_AUDIO_FORMAT_F64 = _GST_AUDIO_FORMAT_NE(F64)
-} GstAudioFormat;
-
-
-typedef struct _GstAudioFormatInfo GstAudioFormatInfo;
-typedef struct _GstAudioInfo GstAudioInfo;
-
-/**
- * GstAudioFormatFlags:
- * @GST_AUDIO_FORMAT_FLAG_INTEGER: integer samples
- * @GST_AUDIO_FORMAT_FLAG_FLOAT: float samples
- * @GST_AUDIO_FORMAT_FLAG_SIGNED: signed samples
- * @GST_AUDIO_FORMAT_FLAG_COMPLEX: complex layout
- *
- * The different audio flags that a format info can have.
- */
-typedef enum
-{
- GST_AUDIO_FORMAT_FLAG_INTEGER = (1 << 0),
- GST_AUDIO_FORMAT_FLAG_FLOAT = (1 << 1),
- GST_AUDIO_FORMAT_FLAG_SIGNED = (1 << 2),
- GST_AUDIO_FORMAT_FLAG_COMPLEX = (1 << 4)
-} GstAudioFormatFlags;
-
-/**
- * GstAudioPackFlags:
- * @GST_AUDIO_PACK_FLAG_NONE: No flag
- *
- * The different flags that can be used when packing and unpacking.
- */
-typedef enum
-{
- GST_AUDIO_PACK_FLAG_NONE = 0
-} GstAudioPackFlags;
-
-/**
- * GstAudioFormatUnpack:
- * @info: a #GstAudioFormatInfo
- * @dest: a destination array
- * @data: pointer to the audio data
- * @length: the amount of samples to unpack.
- *
- * Unpacks @length samples from the given data of format @info.
- * The samples will be unpacked into @dest which each channel
- * interleaved. @dest should at least be big enough to hold @length *
- * channels * size(unpack_format) bytes.
- */
-typedef void (*GstAudioFormatUnpack) (const GstAudioFormatInfo *info,
- GstAudioPackFlags flags, gpointer dest,
- const gpointer data, gint length);
-/**
- * GstAudioFormatPack:
- * @info: a #GstAudioFormatInfo
- * @src: a source array
- * @data: pointer to the destination data
- * @length: the amount of samples to pack.
- *
- * Packs @length samples from @src to the data array in format @info.
- * The samples from source have each channel interleaved
- * and will be packed into @data.
- */
-typedef void (*GstAudioFormatPack) (const GstAudioFormatInfo *info,
- GstAudioPackFlags flags, const gpointer src,
- gpointer data, gint length);
-
-/**
- * GstAudioFormatInfo:
- * @format: #GstAudioFormat
- * @name: string representation of the format
- * @description: user readable description of the format
- * @flags: #GstAudioFormatFlags
- * @endianness: the endianness
- * @width: amount of bits used for one sample
- * @depth: amount of valid bits in @width
- * @silence: @width/8 bytes with 1 silent sample
- * @unpack_format: the format of the unpacked samples
- * @unpack_func: function to unpack samples
- * @pack_func: function to pack samples
- *
- * Information for an audio format.
- */
-struct _GstAudioFormatInfo {
- GstAudioFormat format;
- const gchar *name;
- const gchar *description;
- GstAudioFormatFlags flags;
- gint endianness;
- gint width;
- gint depth;
- guint8 silence[8];
-
- GstAudioFormat unpack_format;
- GstAudioFormatUnpack unpack_func;
- GstAudioFormatPack pack_func;
-
- /*< private >*/
- gpointer _gst_reserved[GST_PADDING];
-};
-
-GType gst_audio_format_info_get_type (void);
-
-#define GST_AUDIO_FORMAT_INFO_FORMAT(info) ((info)->format)
-#define GST_AUDIO_FORMAT_INFO_NAME(info) ((info)->name)
-#define GST_AUDIO_FORMAT_INFO_FLAGS(info) ((info)->flags)
-
-#define GST_AUDIO_FORMAT_INFO_IS_INTEGER(info) !!((info)->flags & GST_AUDIO_FORMAT_FLAG_INTEGER)
-#define GST_AUDIO_FORMAT_INFO_IS_FLOAT(info) !!((info)->flags & GST_AUDIO_FORMAT_FLAG_FLOAT)
-#define GST_AUDIO_FORMAT_INFO_IS_SIGNED(info) !!((info)->flags & GST_AUDIO_FORMAT_FLAG_SIGNED)
-
-#define GST_AUDIO_FORMAT_INFO_ENDIANNESS(info) ((info)->endianness)
-#define GST_AUDIO_FORMAT_INFO_IS_LITTLE_ENDIAN(info) ((info)->endianness == G_LITTLE_ENDIAN)
-#define GST_AUDIO_FORMAT_INFO_IS_BIG_ENDIAN(info) ((info)->endianness == G_BIG_ENDIAN)
-#define GST_AUDIO_FORMAT_INFO_WIDTH(info) ((info)->width)
-#define GST_AUDIO_FORMAT_INFO_DEPTH(info) ((info)->depth)
-
-
-GstAudioFormat gst_audio_format_build_integer (gboolean sign, gint endianness,
- gint width, gint depth) G_GNUC_CONST;
-
-GstAudioFormat gst_audio_format_from_string (const gchar *format) G_GNUC_CONST;
-const gchar * gst_audio_format_to_string (GstAudioFormat format) G_GNUC_CONST;
-
-const GstAudioFormatInfo *
- gst_audio_format_get_info (GstAudioFormat format) G_GNUC_CONST;
-
-void gst_audio_format_fill_silence (const GstAudioFormatInfo *info,
- gpointer dest, gsize length);
-
-/**
- * GstAudioChannelPosition:
- * @GST_AUDIO_CHANNEL_POSITION_MONO: Mono without direction;
- * can only be used with 1 channel
- * @GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT: Front left
- * @GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT: Front right
- * @GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER: Front center
- * @GST_AUDIO_CHANNEL_POSITION_LFE1: Low-frequency effects 1 (subwoofer)
- * @GST_AUDIO_CHANNEL_POSITION_REAR_LEFT: Rear left
- * @GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT: Rear right
- * @GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: Front left of center
- * @GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: Front right of center
- * @GST_AUDIO_CHANNEL_POSITION_REAR_CENTER: Rear center
- * @GST_AUDIO_CHANNEL_POSITION_LFE2: Low-frequency effects 2 (subwoofer)
- * @GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT: Side left
- * @GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT: Side right
- * @GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT: Top front left
- * @GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT: Top front right
- * @GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER: Top front center
- * @GST_AUDIO_CHANNEL_POSITION_TOP_CENTER: Top center
- * @GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT: Top rear left
- * @GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT: Top rear right
- * @GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT: Top side right
- * @GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT: Top rear right
- * @GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER: Top rear center
- * @GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER: Bottom front center
- * @GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT: Bottom front left
- * @GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT: Bottom front right
- * @GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT: Wide left (between front left and side left)
- * @GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT: Wide right (between front right and side right)
- * @GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT: Surround left (between rear left and side left)
- * @GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT: Surround right (between rear right and side right)
- * @GST_AUDIO_CHANNEL_POSITION_NONE: used for position-less channels, e.g.
- * from a sound card that records 1024 channels; mutually exclusive with
- * any other channel position
- * @GST_AUDIO_CHANNEL_POSITION_INVALID: invalid position
- *
- * Audio channel positions.
- *
- * These are the channels defined in SMPTE 2036-2-2008
- * Table 1 for 22.2 audio systems with the Surround and Wide channels from
- * DTS Coherent Acoustics (v.1.3.1) and 10.2 and 7.1 layouts. In the caps the
- * actual channel layout is expressed with a channel count and a channel mask,
- * which describes the existing channels. The positions in the bit mask correspond
- * to the enum values.
- * For negotiation it is allowed to have more bits set in the channel mask than
- * the number of channels to specify the allowed channel positions but this is
- * not allowed in negotiated caps. It is not allowed in any situation other
- * than the one mentioned below to have less bits set in the channel mask than
- * the number of channels.
- *
- * @GST_AUDIO_CHANNEL_POSITION_MONO can only be used with a single mono channel that
- * has no direction information and would be mixed into all directional channels.
- * This is expressed in caps by having a single channel and no channel mask.
- *
- * @GST_AUDIO_CHANNEL_POSITION_NONE can only be used if all channels have this position.
- * This is expressed in caps by having a channel mask with no bits set.
- *
- * As another special case it is allowed to have two channels without a channel mask.
- * This implicitely means that this is a stereo stream with a front left and front right
- * channel.
- */
-typedef enum {
- /* These get negative indices to allow to use
- * the enum values of the normal cases for the
- * bit-mask position */
- GST_AUDIO_CHANNEL_POSITION_NONE = -3,
- GST_AUDIO_CHANNEL_POSITION_MONO = -2,
- GST_AUDIO_CHANNEL_POSITION_INVALID = -1,
-
- /* Normal cases */
- GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT = 0,
- GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
- GST_AUDIO_CHANNEL_POSITION_LFE1,
- GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
- GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
- GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
- GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
- GST_AUDIO_CHANNEL_POSITION_LFE2,
- GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
- GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT,
- GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER,
- GST_AUDIO_CHANNEL_POSITION_TOP_CENTER,
- GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT,
- GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT,
- GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER,
- GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER,
- GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT,
- GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT,
- GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT,
- GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT
-} GstAudioChannelPosition;
-
-#define GST_AUDIO_CHANNEL_POSITION_MASK(pos) (G_GUINT64_CONSTANT(1)<< GST_AUDIO_CHANNEL_POSITION_ ## pos)
-
-/**
- * GstAudioFlags:
- * @GST_AUDIO_FLAG_NONE: no valid flag
- * @GST_AUDIO_FLAG_UNPOSITIONED: the position array explicitly
- * contains unpositioned channels.
- *
- * Extra audio flags
- */
-typedef enum {
- GST_AUDIO_FLAG_NONE = 0,
- GST_AUDIO_FLAG_UNPOSITIONED = (1 << 0)
-} GstAudioFlags;
-
-/**
- * GstAudioLayout:
- * @GST_AUDIO_LAYOUT_INTERLEAVED: interleaved audio
- * @GST_AUDIO_LAYOUT_NON_INTERLEAVED: non-interleaved audio
- *
- * Layout of the audio samples for the different channels.
- */
-typedef enum {
- GST_AUDIO_LAYOUT_INTERLEAVED = 0,
- GST_AUDIO_LAYOUT_NON_INTERLEAVED
-} GstAudioLayout;
-
-/**
- * GstAudioInfo:
- * @finfo: the format info of the audio
- * @flags: additional audio flags
- * @layout: audio layout
- * @rate: the audio sample rate
- * @channels: the number of channels
- * @bpf: the number of bytes for one frame, this is the size of one
- * sample * @channels
- * @position: the positions for each channel
- *
- * Information describing audio properties. This information can be filled
- * in from GstCaps with gst_audio_info_from_caps().
- *
- * Use the provided macros to access the info in this structure.
- */
-struct _GstAudioInfo {
- const GstAudioFormatInfo *finfo;
- GstAudioFlags flags;
- GstAudioLayout layout;
- gint rate;
- gint channels;
- gint bpf;
- GstAudioChannelPosition position[64];
-
- /*< private >*/
- gpointer _gst_reserved[GST_PADDING];
-};
-
-GType gst_audio_info_get_type (void);
-
-#define GST_AUDIO_INFO_IS_VALID(i) ((i)->finfo != NULL && (i)->rate > 0 && (i)->channels > 0 && (i)->bpf > 0)
-
-#define GST_AUDIO_INFO_FORMAT(i) (GST_AUDIO_FORMAT_INFO_FORMAT((i)->finfo))
-#define GST_AUDIO_INFO_NAME(i) (GST_AUDIO_FORMAT_INFO_NAME((i)->finfo))
-#define GST_AUDIO_INFO_WIDTH(i) (GST_AUDIO_FORMAT_INFO_WIDTH((i)->finfo))
-#define GST_AUDIO_INFO_DEPTH(i) (GST_AUDIO_FORMAT_INFO_DEPTH((i)->finfo))
-#define GST_AUDIO_INFO_BPS(info) (GST_AUDIO_INFO_DEPTH(info) >> 3)
-
-#define GST_AUDIO_INFO_IS_INTEGER(i) (GST_AUDIO_FORMAT_INFO_IS_INTEGER((i)->finfo))
-#define GST_AUDIO_INFO_IS_FLOAT(i) (GST_AUDIO_FORMAT_INFO_IS_FLOAT((i)->finfo))
-#define GST_AUDIO_INFO_IS_SIGNED(i) (GST_AUDIO_FORMAT_INFO_IS_SIGNED((i)->finfo))
-
-#define GST_AUDIO_INFO_ENDIANNESS(i) (GST_AUDIO_FORMAT_INFO_ENDIANNES((i)->finfo))
-#define GST_AUDIO_INFO_IS_LITTLE_ENDIAN(i) (GST_AUDIO_FORMAT_INFO_IS_LITTLE_ENDIAN((i)->finfo))
-#define GST_AUDIO_INFO_IS_BIG_ENDIAN(i) (GST_AUDIO_FORMAT_INFO_IS_BIG_ENDIAN((i)->finfo))
-
-#define GST_AUDIO_INFO_FLAGS(info) ((info)->flags)
-#define GST_AUDIO_INFO_IS_UNPOSITIONED(info) ((info)->flags & GST_AUDIO_FLAG_UNPOSITIONED)
-#define GST_AUDIO_INFO_LAYOUT(info) ((info)->layout)
-
-#define GST_AUDIO_INFO_RATE(info) ((info)->rate)
-#define GST_AUDIO_INFO_CHANNELS(info) ((info)->channels)
-#define GST_AUDIO_INFO_BPF(info) ((info)->bpf)
-#define GST_AUDIO_INFO_POSITION(info,c) ((info)->position[c])
-
-GstAudioInfo * gst_audio_info_new (void);
-void gst_audio_info_init (GstAudioInfo *info);
-GstAudioInfo * gst_audio_info_copy (const GstAudioInfo *info);
-void gst_audio_info_free (GstAudioInfo *info);
-
-void gst_audio_info_set_format (GstAudioInfo *info, GstAudioFormat format,
- gint rate, gint channels,
- const GstAudioChannelPosition *position);
-
-gboolean gst_audio_info_from_caps (GstAudioInfo *info, const GstCaps *caps);
-GstCaps * gst_audio_info_to_caps (const GstAudioInfo *info);
-
-gboolean gst_audio_info_convert (const GstAudioInfo * info,
- GstFormat src_fmt, gint64 src_val,
- GstFormat dest_fmt, gint64 * dest_val);
-
-
-
-#define GST_AUDIO_RATE_RANGE "(int) [ 1, max ]"
-#define GST_AUDIO_CHANNELS_RANGE "(int) [ 1, max ]"
-
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-# define GST_AUDIO_NE(s) G_STRINGIFY(s)"LE"
-# define GST_AUDIO_OE(s) G_STRINGIFY(s)"BE"
-#else
-# define GST_AUDIO_NE(s) G_STRINGIFY(s)"BE"
-# define GST_AUDIO_OE(s) G_STRINGIFY(s)"LE"
-#endif
-
-#define GST_AUDIO_FORMATS_ALL " { S8, U8, " \
- "S16LE, S16BE, U16LE, U16BE, " \
- "S24_32LE, S24_32BE, U24_32LE, U24_32BE, " \
- "S32LE, S32BE, U32LE, U32BE, " \
- "S24LE, S24BE, U24LE, U24BE, " \
- "S20LE, S20BE, U20LE, U20BE, " \
- "S18LE, S18BE, U18LE, U18BE, " \
- "F32LE, F32BE, F64LE, F64BE }"
-
-/**
- * GST_AUDIO_CAPS_MAKE:
- * @format: string format that describes the pixel layout, as string
- * (e.g. "S16LE", "S8", etc.)
- *
- * Generic caps string for audio, for use in pad templates.
- */
-#define GST_AUDIO_CAPS_MAKE(format) \
- "audio/x-raw, " \
- "format = (string) " format ", " \
- "rate = " GST_AUDIO_RATE_RANGE ", " \
- "channels = " GST_AUDIO_CHANNELS_RANGE
-
-/**
- * GST_AUDIO_DEF_RATE:
- *
- * Standard sampling rate used in consumer audio.
- */
-#define GST_AUDIO_DEF_RATE 44100
-/**
- * GST_AUDIO_DEF_CHANNELS:
- *
- * Standard number of channels used in consumer audio.
- */
-#define GST_AUDIO_DEF_CHANNELS 2
-/**
- * GST_AUDIO_DEF_FORMAT:
- *
- * Standard format used in consumer audio.
- */
-#define GST_AUDIO_DEF_FORMAT "S16LE"
+G_BEGIN_DECLS
/* conversion macros */
/**
gint rate, gint bpf);
-gboolean gst_audio_buffer_reorder_channels (GstBuffer * buffer,
- GstAudioFormat format,
- gint channels,
- const GstAudioChannelPosition * from,
- const GstAudioChannelPosition * to);
-
-gboolean gst_audio_reorder_channels (gpointer data, gsize size,
- GstAudioFormat format,
- gint channels,
- const GstAudioChannelPosition * from,
- const GstAudioChannelPosition * to);
-
-gboolean gst_audio_channel_positions_to_valid_order (GstAudioChannelPosition *position,
- gint channels);
-
-gboolean gst_audio_check_valid_channel_positions (const GstAudioChannelPosition *position,
- gint channels, gboolean force_order);
-
-gboolean gst_audio_channel_positions_to_mask (const GstAudioChannelPosition *position,
- gint channels, guint64 *channel_mask);
-
-gboolean gst_audio_channel_positions_from_mask (gint channels, guint64 channel_mask,
- GstAudioChannelPosition * position);
-
-gboolean gst_audio_get_channel_reorder_map (gint channels,
- const GstAudioChannelPosition * from,
- const GstAudioChannelPosition * to,
- gint *reorder_map);
-
G_END_DECLS
#endif /* __GST_AUDIO_AUDIO_H__ */