gst_plugins_base/gst-libs/gst/audio/multichannel.c
changeset 16 8e837d1bf446
parent 2 5505e8908944
child 30 7e817e7e631c
--- a/gst_plugins_base/gst-libs/gst/audio/multichannel.c	Wed Mar 24 17:58:42 2010 -0500
+++ b/gst_plugins_base/gst-libs/gst/audio/multichannel.c	Wed Mar 24 18:04:17 2010 -0500
@@ -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}}, { {