vorbis: Port to the new multichannel caps
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 20 Dec 2011 11:08:53 +0000 (12:08 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 5 Jan 2012 09:34:24 +0000 (10:34 +0100)
ext/vorbis/gstvorbiscommon.c
ext/vorbis/gstvorbiscommon.h
ext/vorbis/gstvorbisdec.c
ext/vorbis/gstvorbisdeclib.c
ext/vorbis/gstvorbisenc.c

index c4dd408..8134881 100644 (file)
@@ -26,7 +26,7 @@
 /* http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 */
 const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = {
   {                             /* Mono */
-      GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
+      GST_AUDIO_CHANNEL_POSITION_MONO},
   {                             /* Stereo */
         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
       GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
@@ -53,7 +53,7 @@ const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = {
         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
-        GST_AUDIO_CHANNEL_POSITION_LFE,
+        GST_AUDIO_CHANNEL_POSITION_LFE1,
       },
   {                             /* 6.1 Surround, in Vorbis spec since 2010-01-13 */
         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
@@ -62,7 +62,7 @@ const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = {
         GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
         GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
         GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
-      GST_AUDIO_CHANNEL_POSITION_LFE},
+      GST_AUDIO_CHANNEL_POSITION_LFE1},
   {                             /* 7.1 Surround, in Vorbis spec since 2010-01-13 */
         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
@@ -71,5 +71,71 @@ const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = {
         GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
-      GST_AUDIO_CHANNEL_POSITION_LFE},
+      GST_AUDIO_CHANNEL_POSITION_LFE1},
 };
+
+const GstAudioChannelPosition gst_vorbis_default_channel_positions[][8] = {
+  {                             /* Mono */
+      GST_AUDIO_CHANNEL_POSITION_MONO},
+  {                             /* Stereo */
+        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
+  {                             /* Stereo + Centre */
+        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+      GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER},
+  {                             /* Quadraphonic */
+        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
+      },
+  {                             /* Stereo + Centre + rear stereo */
+        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
+        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
+      },
+  {                             /* Full 5.1 Surround */
+        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,
+      },
+  {                             /* 6.1 Surround, in Vorbis spec since 2010-01-13 */
+        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_CENTER,
+        GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
+      },
+  {                             /* 7.1 Surround, in Vorbis spec since 2010-01-13 */
+        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_SIDE_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
+      },
+};
+
+#ifndef USE_TREMOLO
+/* gst[i] = vorbis[reorder_map[i]] */
+const gint gst_vorbis_reorder_map[][8] = {
+  {0},
+  {0, 1},
+  {0, 2, 1},
+  {0, 1, 2, 3},
+  {0, 2, 1, 3, 4},
+  {0, 2, 1, 4, 5, 3},
+  {0, 2, 1, 5, 6, 4, 3},
+  {0, 2, 1, 6, 7, 4, 5, 3}
+};
+#endif
index 563b8f7..64386a9 100644 (file)
 #define __GST_VORBIS_COMMON_H__
 
 #include <gst/gst.h>
-#include <gst/audio/multichannel.h>
+#include <gst/audio/audio.h>
 
 extern const GstAudioChannelPosition gst_vorbis_channel_positions[][8];
+extern const GstAudioChannelPosition gst_vorbis_default_channel_positions[][8];
+
+#ifndef USE_TREMOLO
+extern const gint gst_vorbis_reorder_map[][8];
+#endif
 
 #endif /* __GST_VORBIS_COMMON_H__ */
index 8a59660..1683f45 100644 (file)
@@ -44,7 +44,6 @@
 #include <string.h>
 #include <gst/audio/audio.h>
 #include <gst/tag/tag.h>
-#include <gst/audio/multichannel.h>
 
 #include "gstvorbiscommon.h"
 
@@ -230,14 +229,9 @@ vorbis_handle_identification_packet (GstVorbisDec * vd)
   GstCaps *caps;
   GstAudioInfo info;
 
-  gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
-      vd->vi.channels);
-
   switch (info.channels) {
     case 1:
     case 2:
-      /* nothing */
-      break;
     case 3:
     case 4:
     case 5:
@@ -246,20 +240,22 @@ vorbis_handle_identification_packet (GstVorbisDec * vd)
     case 8:
     {
       const GstAudioChannelPosition *pos;
-      gint i;
 
-      pos = gst_vorbis_channel_positions[info.channels - 1];
-      for (i = 0; i < info.channels; i++)
-        info.position[i] = pos[i];
+      pos = gst_vorbis_default_channel_positions[info.channels - 1];
+      gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
+          vd->vi.channels, pos);
       break;
     }
     default:{
+      GstAudioChannelPosition position[64];
       gint i, max_pos = MAX (info.channels, 64);
 
       GST_ELEMENT_WARNING (vd, STREAM, DECODE,
           (NULL), ("Using NONE channel layout for more than 8 channels"));
       for (i = 0; i < max_pos; i++)
-        info.position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
+        position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
+      gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
+          vd->vi.channels, position);
       break;
     }
   }
@@ -577,7 +573,12 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
 #endif
     goto wrong_samples;
 
-#ifndef USE_TREMOLO
+#ifdef USE_TREMOLO
+  if (vd->info.channels < 9)
+    gst_audio_reorder_channels (data, size, GST_VORBIS_AUDIO_FORMAT,
+        vd->info.channels, gst_vorbis_channel_positions[vd->info.channels - 1],
+        gst_vorbis_default_channel_positions[vd->info.channels - 1]);
+#else
   /* copy samples in buffer */
   vd->copy_samples ((vorbis_sample_t *) data, pcm,
       sample_count, vd->info.channels);
index 66a2ee3..a28ba37 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <string.h>
 #include "gstvorbisdeclib.h"
+#include "gstvorbiscommon.h"
 
 #ifndef TREMOR
 /* These samples can be outside of the float -1.0 -- 1.0 range, this
@@ -65,7 +66,8 @@ copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
   gint i;
 
   for (i = 0; i < channels; i++) {
-    memcpy (out, in[i], samples * sizeof (float));
+    memcpy (out, in[gst_vorbis_reorder_map[channels - 1][i]],
+        samples * sizeof (float));
     out += samples;
   }
 #else
@@ -73,7 +75,7 @@ copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
 
   for (j = 0; j < samples; j++) {
     for (i = 0; i < channels; i++) {
-      *out++ = in[i][j];
+      *out++ = in[gst_vorbis_reorder_map[channels - 1][i]][j];
     }
   }
 #endif
@@ -165,7 +167,7 @@ copy_samples_16 (vorbis_sample_t * _out, vorbis_sample_t ** _in, guint samples,
 
   for (j = 0; j < samples; j++) {
     for (i = 0; i < channels; i++) {
-      *out++ = CLIP_TO_15 (in[i][j] >> 9);
+      *out++ = CLIP_TO_15 (in[gst_vorbis_reorder_map[channels - 1][i]][j] >> 9);
     }
   }
 }
index c699d5f..518b604 100644 (file)
@@ -50,7 +50,6 @@
 
 #include <gst/gsttagsetter.h>
 #include <gst/tag/tag.h>
-#include <gst/audio/multichannel.h>
 #include <gst/audio/audio.h>
 #include "gstvorbisenc.h"
 
@@ -264,30 +263,19 @@ gst_vorbis_enc_generate_sink_caps (void)
           "rate", GST_TYPE_INT_RANGE, 1, 200000,
           "channels", G_TYPE_INT, 1, NULL));
 
-  gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
-          "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
-          "rate", GST_TYPE_INT_RANGE, 1, 200000,
-          "channels", G_TYPE_INT, 2, NULL));
-
-  for (i = 3; i <= 8; i++) {
-    GValue chanpos = { 0 };
-    GValue pos = { 0 };
+  for (i = 2; i <= 8; i++) {
     GstStructure *structure;
-
-    g_value_init (&chanpos, GST_TYPE_ARRAY);
-    g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION);
+    guint64 channel_mask = 0;
+    const GstAudioChannelPosition *pos = gst_vorbis_channel_positions[i - 1];
 
     for (c = 0; c < i; c++) {
-      g_value_set_enum (&pos, gst_vorbis_channel_positions[i - 1][c]);
-      gst_value_array_append_value (&chanpos, &pos);
+      channel_mask |= pos[i];
     }
-    g_value_unset (&pos);
 
     structure = gst_structure_new ("audio/x-raw",
         "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
-        "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i, NULL);
-    gst_structure_set_value (structure, "channel-positions", &chanpos);
-    g_value_unset (&chanpos);
+        "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i,
+        "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL);
 
     gst_caps_append_structure (caps, structure);
   }
@@ -295,7 +283,8 @@ gst_vorbis_enc_generate_sink_caps (void)
   gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
           "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
           "rate", GST_TYPE_INT_RANGE, 1, 200000,
-          "channels", GST_TYPE_INT_RANGE, 9, 255, NULL));
+          "channels", GST_TYPE_INT_RANGE, 9, 255,
+          "channel-mask", GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL));
 
   return caps;
 }
@@ -765,9 +754,22 @@ gst_vorbis_enc_handle_frame (GstAudioEncoder * enc, GstBuffer * buffer)
   vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
 
   /* deinterleave samples, write the buffer data */
-  for (i = 0; i < size; i++) {
-    for (j = 0; j < vorbisenc->channels; j++) {
-      vorbis_buffer[j][i] = *ptr++;
+  if (vorbisenc->channels < 2 || vorbisenc->channels > 8) {
+    for (i = 0; i < size; i++) {
+      for (j = 0; j < vorbisenc->channels; j++) {
+        vorbis_buffer[j][i] = *ptr++;
+      }
+    }
+  } else {
+    gint i, j;
+
+    /* Reorder */
+    for (i = 0; i < size; i++) {
+      for (j = 0; j < vorbisenc->channels; j++) {
+        vorbis_buffer[gst_vorbis_reorder_map[vorbisenc->channels - 1][j]][i] =
+            ptr[j];
+      }
+      ptr += vorbisenc->channels;
     }
   }