--- a/gst_plugins_base/gst-libs/gst/audio/multichannel.c Wed Mar 31 22:03:18 2010 +0300
+++ b/gst_plugins_base/gst-libs/gst/audio/multichannel.c Tue Aug 31 15:30:33 2010 +0300
@@ -16,32 +16,53 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+/**
+ * SECTION:gstmultichannel
+ * @short_description: Support for multichannel audio elements
+ *
+ * This module contains some helper functions and a enum to work with
+ * multichannel audio.
+ */
#ifdef HAVE_CONFIG_H
-#include <config.h>
+#include "config.h"
#endif
#include "multichannel.h"
#define GST_AUDIO_CHANNEL_POSITIONS_FIELD_NAME "channel-positions"
-/*
- * This function checks if basic assumptions apply:
- * - does each position occur at most once?
- * - do conflicting positions occur?
- * + front_mono vs. front_left/right
- * + front_center vs. front_left/right_of_center
- * + rear_center vs. rear_left/right
- * It also adds some hacks that 0.8.x needs for compatibility:
- * - if channels == 1, are we really mono?
- * - if channels == 2, are we really stereo?
+/**
+ * gst_audio_check_channel_positions:
+ * @pos: An array of #GstAudioChannelPosition.
+ * @channels: The number of elements in @pos.
+ *
+ * This functions checks if the given channel positions are valid. Channel
+ * positions are valid if:
+ * <itemizedlist>
+ * <listitem><para>No channel positions appears twice or all positions are %GST_AUDIO_CHANNEL_POSITION_NONE.
+ * </para></listitem>
+ * <listitem><para>Either all or none of the channel positions are %GST_AUDIO_CHANNEL_POSITION_NONE.
+ * </para></listitem>
+ * <listitem><para>%GST_AUDIO_CHANNEL_POSITION_FRONT_MONO and %GST_AUDIO_CHANNEL_POSITION_LEFT or %GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT don't appear together in the given positions.
+ * </para></listitem>
+ * </itemizedlist>
+ *
+ * Since: 0.10.20
+ *
+ * Returns: %TRUE if the given channel positions are valid
+ * and %FALSE otherwise.
*/
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
-static gboolean
+gboolean
gst_audio_check_channel_positions (const GstAudioChannelPosition * pos,
- gint channels)
+ guint channels)
{
gint i, n;
+
const struct
{
const GstAudioChannelPosition pos1[2];
@@ -51,27 +72,18 @@
{ {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
- GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}},
- /* front center: 2 <-> 1 */
- { {
- GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
- GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
- GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}},
- /* rear: 2 <-> 1 */
- { {
- GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
- GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
- GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}}, { {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}}, { {
GST_AUDIO_CHANNEL_POSITION_INVALID}}
};
- g_assert (pos != NULL && channels > 0);
+ g_return_val_if_fail (pos != NULL, FALSE);
+ g_return_val_if_fail (channels > 0, FALSE);
/* check for invalid channel positions */
for (n = 0; n < channels; n++) {
if (pos[n] <= GST_AUDIO_CHANNEL_POSITION_INVALID ||
pos[n] >= GST_AUDIO_CHANNEL_POSITION_NUM) {
- g_warning ("Channel position %d for channel %d is invalid", pos[n], n);
+ GST_WARNING ("Channel position %d for channel %d is invalid", pos[n], n);
return FALSE;
}
}
@@ -82,7 +94,7 @@
if (pos[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
for (n = 1; n < channels; ++n) {
if (pos[n] != GST_AUDIO_CHANNEL_POSITION_NONE) {
- g_warning ("Either all channel positions must be defined, or all "
+ GST_WARNING ("Either all channel positions must be defined, or all "
"be set to NONE, having only some defined is not allowed");
return FALSE;
}
@@ -103,13 +115,13 @@
/* NONE may not occur mixed with other channel positions */
if (i == GST_AUDIO_CHANNEL_POSITION_NONE && count > 0) {
- g_warning ("Either all channel positions must be defined, or all "
+ GST_WARNING ("Either all channel positions must be defined, or all "
"be set to NONE, having only some defined is not allowed");
return FALSE;
}
if (count > 1) {
- g_warning ("Channel position %d occurred %d times, not allowed",
+ GST_WARNING ("Channel position %d occurred %d times, not allowed",
i, count);
return FALSE;
}
@@ -127,21 +139,12 @@
}
if (found1 && found2) {
- g_warning ("Found conflicting channel positions %d/%d and %d",
+ GST_WARNING ("Found conflicting channel positions %d/%d and %d",
conf[i].pos1[0], conf[i].pos1[1], conf[i].pos2[0]);
return FALSE;
}
}
- /* Throw warning if we encounter an unusual 2-channel configuration,
- * at least until someone finds a reason why we should not */
- if (channels == 2 && (pos[0] != GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT ||
- pos[1] != GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT)) {
- g_warning ("channels=2 implies stereo, but channel positions are "
- "< %d, %d>", pos[0], pos[1]);
- return FALSE;
- }
-
return TRUE;
}
@@ -236,9 +239,13 @@
gst_audio_get_channel_positions (GstStructure * str)
{
GstAudioChannelPosition *pos;
+
gint channels, n;
+
const GValue *pos_val_arr, *pos_val_entry;
+
gboolean res;
+
GType t;
/* get number of channels, general type checkups */
@@ -316,6 +323,7 @@
GValue pos_val_arr = { 0 }, pos_val_entry = {
0};
gint channels, n;
+
gboolean res;
/* get number of channels, checkups */
@@ -383,11 +391,6 @@
g_return_if_fail (res);
g_return_if_fail (channels > 0);
- /* 0.8.x: channels=1 or channels=2 is mono/stereo, no positions needed
- * there (we discard them anyway) */
- if (channels == 1 || channels == 2)
- return;
-
/* create the array of lists */
g_value_init (&pos_val_arr, GST_TYPE_ARRAY);
g_value_init (&pos_val_entry, GST_TYPE_AUDIO_CHANNEL_POSITION);
@@ -417,6 +420,7 @@
const GstAudioChannelPosition * pos, gint num_positions)
{
GstCaps *caps = gst_caps_new_empty ();
+
const GValue *chan_val;
chan_val = gst_structure_get_value (str, "channels");
@@ -424,6 +428,7 @@
gst_audio_set_structure_channel_positions_list (str, pos, num_positions);
} else if (G_VALUE_TYPE (chan_val) == GST_TYPE_LIST) {
gint size;
+
const GValue *sub_val;
size = gst_value_list_get_size (chan_val);
@@ -526,9 +531,13 @@
gst_audio_fixate_channel_positions (GstStructure * str)
{
GstAudioChannelPosition *pos;
+
gint channels, n, num_unfixed = 0, i, c;
+
const GValue *pos_val_arr, *pos_val_entry, *pos_val;
+
gboolean res, is_stereo = TRUE;
+
GType t;
/*
@@ -543,19 +552,20 @@
const GstAudioChannelPosition pos2[1];
} conf[] = {
/* front: mono <-> stereo */
- { {
- GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+ {
+ {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
- GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}},
- /* front center: 2 <-> 1 */
- { {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}}, { {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
- GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}},
- /* rear: 2 <-> 1 */
- { {
+ GST_AUDIO_CHANNEL_POSITION_INVALID}}, { {
+ GST_AUDIO_CHANNEL_POSITION_INVALID, GST_AUDIO_CHANNEL_POSITION_INVALID}, {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}}, { {
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
+ GST_AUDIO_CHANNEL_POSITION_INVALID}}, { {
+ GST_AUDIO_CHANNEL_POSITION_INVALID, GST_AUDIO_CHANNEL_POSITION_INVALID}, {
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}}, { {
GST_AUDIO_CHANNEL_POSITION_INVALID, GST_AUDIO_CHANNEL_POSITION_INVALID}, {
GST_AUDIO_CHANNEL_POSITION_LFE}}, { {