Index: tests/check/elements/audioconvert.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/tests/check/elements/audioconvert.c,v
retrieving revision 1.20
diff -u -p -r1.20 audioconvert.c
--- tests/check/elements/audioconvert.c	21 Aug 2006 11:42:12 -0000	1.20
+++ tests/check/elements/audioconvert.c	23 Jan 2007 11:18:16 -0000
@@ -3,6 +3,7 @@
  * unit test for audioconvert
  *
  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
+ * Copyright (C) <2007> Tim-Philipp Müller <tim centricular net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -35,33 +36,33 @@ GstPad *mysrcpad, *mysinkpad;
 #define CONVERT_CAPS_TEMPLATE_STRING    \
   "audio/x-raw-float, " \
     "rate = (int) [ 1, MAX ], " \
-    "channels = (int) [ 1, 8 ], " \
+    "channels = (int) [ 1, MAX ], " \
     "endianness = (int) BYTE_ORDER, " \
     "width = (int) 32;" \
   "audio/x-raw-int, " \
     "rate = (int) [ 1, MAX ], " \
-    "channels = (int) [ 1, 8 ], " \
+    "channels = (int) [ 1, MAX ], " \
     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
     "width = (int) 32, " \
     "depth = (int) [ 1, 32 ], " \
     "signed = (boolean) { true, false }; " \
   "audio/x-raw-int, " \
     "rate = (int) [ 1, MAX ], " \
-    "channels = (int) [ 1, 8 ], " \
+    "channels = (int) [ 1, MAX ], " \
     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
     "width = (int) 24, " \
     "depth = (int) [ 1, 24 ], " \
     "signed = (boolean) { true, false }; " \
   "audio/x-raw-int, " \
     "rate = (int) [ 1, MAX ], " \
-    "channels = (int) [ 1, 8 ], " \
+    "channels = (int) [ 1, MAX ], " \
     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
     "width = (int) 16, " \
     "depth = (int) [ 1, 16 ], " \
     "signed = (boolean) { true, false }; " \
   "audio/x-raw-int, " \
     "rate = (int) [ 1, MAX ], " \
-    "channels = (int) [ 1, 8 ], " \
+    "channels = (int) [ 1, MAX ], " \
     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
     "width = (int) 8, " \
     "depth = (int) [ 1, 8 ], " \
@@ -228,6 +229,74 @@ static GstAudioChannelPosition mixed_up_
       }
 };
 
+/* we get this when recording from a soundcard with lots of input channels */
+static GstAudioChannelPosition undefined_positions[][9] = {
+  {
+        GST_AUDIO_CHANNEL_POSITION_NONE
+      },
+  {
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE
+      },
+  {
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE
+      },
+  {
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE
+      },
+  {
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE
+      },
+  {
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE
+      },
+  {
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE
+      },
+  {
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE
+      },
+  {
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE,
+        GST_AUDIO_CHANNEL_POSITION_NONE
+      }
+
+};
+
 static void
 set_channel_positions (GstCaps * caps, int channels,
     GstAudioChannelPosition * channelpositions)
@@ -314,7 +383,7 @@ verify_convert (const gchar * which, voi
 
   /* pushing gives away my reference ... */
   GST_DEBUG ("push it");
-  fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
+  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
   GST_DEBUG ("pushed it");
   /* ... and puts a new buffer on the global list */
   fail_unless (g_list_length (buffers) == 1);
@@ -583,8 +652,194 @@ GST_START_TEST (test_caps_negotiation)
 
 GST_END_TEST;
 
+GST_START_TEST (test_convert_undefined_multichannel)
+{
+  /* (A) CONVERSION FROM 'WORSE' TO 'BETTER' FORMAT */
+
+  /* 1 channel, NONE positions, int8 => int16 */
+  {
+    guint16 out[] = { 0x2000 };
+    guint8 in[] = { 0x20 };
+    GstCaps *out_caps = get_int_mc_caps (1, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *in_caps = get_int_mc_caps (1, "BYTE_ORDER", 8, 8, FALSE, FALSE);
+    set_channel_positions (out_caps, 1, undefined_positions[1 - 1]);
+    set_channel_positions (in_caps, 1, undefined_positions[1 - 1]);
+
+    RUN_CONVERSION ("1 channel, undefined layout, identity conversion, "
+        "int8 => int16", in, in_caps, out, out_caps);
+  }
+
+  /* 2 channels, NONE positions, int8 => int16 */
+  {
+    guint16 out[] = { 0x8000, 0x2000 };
+    guint8 in[] = { 0x80, 0x20 };
+    GstCaps *out_caps = get_int_mc_caps (2, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *in_caps = get_int_mc_caps (2, "BYTE_ORDER", 8, 8, FALSE, FALSE);
+    set_channel_positions (out_caps, 2, undefined_positions[2 - 1]);
+    set_channel_positions (in_caps, 2, undefined_positions[2 - 1]);
+
+    RUN_CONVERSION ("2 channels, undefined layout, identity conversion, "
+        "int8 => int16", in, in_caps, out, out_caps);
+  }
+
+  /* 6 channels, NONE positions, int8 => int16 */
+  {
+    guint16 out[] = { 0x0000, 0x2000, 0x8000, 0x2000, 0x0000, 0xff00 };
+    guint8 in[] = { 0x00, 0x20, 0x80, 0x20, 0x00, 0xff };
+    GstCaps *out_caps = get_int_mc_caps (6, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *in_caps = get_int_mc_caps (6, "BYTE_ORDER", 8, 8, FALSE, FALSE);
+    set_channel_positions (out_caps, 6, undefined_positions[6 - 1]);
+    set_channel_positions (in_caps, 6, undefined_positions[6 - 1]);
+
+    RUN_CONVERSION ("6 channels, undefined layout, identity conversion, "
+        "int8 => int16", in, in_caps, out, out_caps);
+  }
+
+  /* 9 channels, NONE positions, int8 => int16 */
+  {
+    guint16 out[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
+        0x0000, 0xff00, 0x0000 };
+    guint8 in[] = { 0x00, 0xff, 0x00, 0x20, 0x80, 0x20, 0x00, 0xff, 0x00 };
+    GstCaps *out_caps = get_int_mc_caps (9, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *in_caps = get_int_mc_caps (9, "BYTE_ORDER", 8, 8, FALSE, FALSE);
+    set_channel_positions (out_caps, 9, undefined_positions[9 - 1]);
+    set_channel_positions (in_caps, 9, undefined_positions[9 - 1]);
+
+    RUN_CONVERSION ("9 channels, undefined layout, identity conversion, "
+        "int8 => int16", in, in_caps, out, out_caps);
+  }
+
+  /* (B) CONVERSION FROM 'BETTER' TO 'WORSE' FORMAT */
+
+  /* 1 channel, NONE positions, int16 => int8 */
+  {
+    guint16 in[] = { 0x2000 };
+    guint8 out[] = { 0x20 };
+    GstCaps *in_caps = get_int_mc_caps (1, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *out_caps = get_int_mc_caps (1, "BYTE_ORDER", 8, 8, FALSE, FALSE);
+    set_channel_positions (out_caps, 1, undefined_positions[1 - 1]);
+    set_channel_positions (in_caps, 1, undefined_positions[1 - 1]);
+
+    RUN_CONVERSION ("1 channel, undefined layout, identity conversion, "
+        "int16 => int8", in, in_caps, out, out_caps);
+  }
+
+  /* 2 channels, NONE positions, int16 => int8 */
+  {
+    guint16 in[] = { 0x8000, 0x2000 };
+    guint8 out[] = { 0x80, 0x20 };
+    GstCaps *in_caps = get_int_mc_caps (2, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *out_caps = get_int_mc_caps (2, "BYTE_ORDER", 8, 8, FALSE, FALSE);
+    set_channel_positions (out_caps, 2, undefined_positions[2 - 1]);
+    set_channel_positions (in_caps, 2, undefined_positions[2 - 1]);
+
+    RUN_CONVERSION ("2 channels, undefined layout, identity conversion, "
+        "int16 => int8", in, in_caps, out, out_caps);
+  }
+
+  /* 6 channels, NONE positions, int16 => int8 */
+  {
+    guint16 in[] = { 0x0000, 0x2000, 0x8000, 0x2000, 0x0000, 0xff00 };
+    guint8 out[] = { 0x00, 0x20, 0x80, 0x20, 0x00, 0xff };
+    GstCaps *in_caps = get_int_mc_caps (6, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *out_caps = get_int_mc_caps (6, "BYTE_ORDER", 8, 8, FALSE, FALSE);
+    set_channel_positions (out_caps, 6, undefined_positions[6 - 1]);
+    set_channel_positions (in_caps, 6, undefined_positions[6 - 1]);
+
+    RUN_CONVERSION ("6 channels, undefined layout, identity conversion, "
+        "int16 => int8", in, in_caps, out, out_caps);
+  }
+
+  /* 9 channels, NONE positions, int16 => int8 */
+  {
+    guint16 in[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
+        0x0000, 0xff00, 0x0000 };
+    guint8 out[] = { 0x00, 0xff, 0x00, 0x20, 0x80, 0x20, 0x00, 0xff, 0x00 };
+    GstCaps *in_caps = get_int_mc_caps (9, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *out_caps = get_int_mc_caps (9, "BYTE_ORDER", 8, 8, FALSE, FALSE);
+    set_channel_positions (out_caps, 9, undefined_positions[9 - 1]);
+    set_channel_positions (in_caps, 9, undefined_positions[9 - 1]);
+
+    RUN_CONVERSION ("9 channels, undefined layout, identity conversion, "
+        "int16 => int8", in, in_caps, out, out_caps);
+  }
+
+  /* (C) NO CONVERSION, SAME FORMAT */
+
+  /* 1 channel, NONE positions, int16 => int16 */
+  {
+    guint16 in[] = { 0x2000 };
+    guint16 out[] = { 0x2000 };
+    GstCaps *in_caps = get_int_mc_caps (1, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *out_caps = get_int_mc_caps (1, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    set_channel_positions (out_caps, 1, undefined_positions[1 - 1]);
+    set_channel_positions (in_caps, 1, undefined_positions[1 - 1]);
+
+    RUN_CONVERSION ("1 channel, undefined layout, identity conversion, "
+        "int16 => int16", in, in_caps, out, out_caps);
+  }
 
-Suite *
+  /* 2 channels, NONE positions, int16 => int16 */
+  {
+    guint16 in[] = { 0x8000, 0x2000 };
+    guint16 out[] = { 0x8000, 0x2000 };
+    GstCaps *in_caps = get_int_mc_caps (2, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *out_caps = get_int_mc_caps (2, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    set_channel_positions (out_caps, 2, undefined_positions[2 - 1]);
+    set_channel_positions (in_caps, 2, undefined_positions[2 - 1]);
+
+    RUN_CONVERSION ("2 channels, undefined layout, identity conversion, "
+        "int16 => int16", in, in_caps, out, out_caps);
+  }
+
+  /* 6 channels, NONE positions, int16 => int16 */
+  {
+    guint16 in[] = { 0x0000, 0x2000, 0x8000, 0x2000, 0x0000, 0xff00 };
+    guint16 out[] = { 0x0000, 0x2000, 0x8000, 0x2000, 0x0000, 0xff00 };
+    GstCaps *in_caps = get_int_mc_caps (6, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *out_caps = get_int_mc_caps (6, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    set_channel_positions (out_caps, 6, undefined_positions[6 - 1]);
+    set_channel_positions (in_caps, 6, undefined_positions[6 - 1]);
+
+    RUN_CONVERSION ("6 channels, undefined layout, identity conversion, "
+        "int16 => int16", in, in_caps, out, out_caps);
+  }
+
+  /* 9 channels, NONE positions, int16 => int16 */
+  {
+    guint16 in[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
+        0x0000, 0xff00, 0x0000 };
+    guint16 out[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
+        0x0000, 0xff00, 0x0000 };
+    GstCaps *in_caps = get_int_mc_caps (9, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *out_caps = get_int_mc_caps (9, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    set_channel_positions (out_caps, 9, undefined_positions[9 - 1]);
+    set_channel_positions (in_caps, 9, undefined_positions[9 - 1]);
+
+    RUN_CONVERSION ("9 channels, undefined layout, identity conversion, "
+        "int16 => int16", in, in_caps, out, out_caps);
+  }
+
+  /* (C) int16 => float */
+
+  /* 9 channels, NONE positions, int16 => float */
+  {
+    guint16 in[] = { 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
+        0x0000, 0x8000, 0x0000 };
+    gfloat out[] = { -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0 };
+    GstCaps *in_caps = get_int_mc_caps (9, "BYTE_ORDER", 16, 16, FALSE, FALSE);
+    GstCaps *out_caps = get_float_mc_caps (9, "BYTE_ORDER", 32, FALSE);
+    set_channel_positions (out_caps, 9, undefined_positions[9 - 1]);
+    set_channel_positions (in_caps, 9, undefined_positions[9 - 1]);
+
+    RUN_CONVERSION ("9 channels, undefined layout, identity conversion, "
+        "int16 => float", in, in_caps, out, out_caps);
+  }
+}
+
+GST_END_TEST;
+
+static Suite *
 audioconvert_suite (void)
 {
   Suite *s = suite_create ("audioconvert");
@@ -597,23 +852,9 @@ audioconvert_suite (void)
   tcase_add_test (tc_chain, test_multichannel_conversion);
   tcase_add_test (tc_chain, test_channel_remapping);
   tcase_add_test (tc_chain, test_caps_negotiation);
+  tcase_add_test (tc_chain, test_convert_undefined_multichannel);
 
   return s;
 }
 
-int
-main (int argc, char **argv)
-{
-  int nf;
-
-  Suite *s = audioconvert_suite ();
-  SRunner *sr = srunner_create (s);
-
-  gst_check_init (&argc, &argv);
-
-  srunner_run_all (sr, CK_NORMAL);
-  nf = srunner_ntests_failed (sr);
-  srunner_free (sr);
-
-  return nf;
-}
+GST_CHECK_MAIN (audioconvert);
