ext/flac/: Set the channel layout when decoding FLAC files with more than 2 channels...
authorSebastian Dröge <slomo@circular-chaos.org>
Sun, 25 May 2008 16:09:39 +0000 (16:09 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Sun, 25 May 2008 16:09:39 +0000 (16:09 +0000)
Original commit message from CVS:
* ext/flac/Makefile.am:
* ext/flac/gstflacdec.c: (gst_flac_dec_write):
Set the channel layout when decoding FLAC files with more than 2
channels as defined by the FLAC spec. Fixes bug #534570.
Also don't try to decode left/side, right/side and mid/side files
as we don't support this at all.

ChangeLog
ext/flac/Makefile.am
ext/flac/gstflacdec.c

index c7348db..ad659a5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-05-25  Sebastian Dröge  <slomo@circular-chaos.org>
+
+       * ext/flac/Makefile.am:
+       * ext/flac/gstflacdec.c: (gst_flac_dec_write):
+       Set the channel layout when decoding FLAC files with more than 2
+       channels as defined by the FLAC spec. Fixes bug #534570.
+
+       Also don't try to decode left/side, right/side and mid/side files
+       as we don't support this at all.
+
 2008-05-24  Tim-Philipp Müller  <tim.muller at collabora co uk>
 
        * configure.ac:
index 982e76f..2723680 100644 (file)
@@ -4,6 +4,7 @@ libgstflac_la_SOURCES = gstflac.c gstflacdec.c gstflacenc.c
 libgstflac_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
 libgstflac_la_LIBADD = \
        $(GST_PLUGINS_BASE_LIBS) -lgsttag-$(GST_MAJORMINOR) \
+       -lgstaudio-$(GST_MAJORMINOR) \
        $(GST_BASE_LIBS) $(GST_LIBS) $(FLAC_LIBS)
 libgstflac_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
index fe78c77..d220518 100644 (file)
 #include <gst/gst-i18n-plugin.h>
 #include <gst/gsttagsetter.h>
 #include <gst/base/gsttypefindhelper.h>
-
+#include <gst/audio/multichannel.h>
 #include <gst/tag/tag.h>
 
+/* Taken from http://flac.sourceforge.net/format.html#frame_header */
+static const GstAudioChannelPosition channel_positions[8][8] = {
+  {GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
+  {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
+        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+      GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
+        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+      GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
+        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}, {
+        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
+        GST_AUDIO_CHANNEL_POSITION_LFE,
+        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+      GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
+  /* FIXME: 7/8 channel layouts are not defined in the FLAC specs */
+  {
+        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
+        GST_AUDIO_CHANNEL_POSITION_LFE,
+      GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
+        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
+        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
+        GST_AUDIO_CHANNEL_POSITION_LFE,
+        GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
+      GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}
+};
+
 GST_DEBUG_CATEGORY_STATIC (flacdec_debug);
 #define GST_CAT_DEFAULT flacdec_debug
 
@@ -1043,6 +1085,13 @@ gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
       goto done;
   }
 
+  /* TODO: we don't support left/side, right/side and mid/side */
+  if (frame->header.channel_assignment != FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT) {
+    GST_ERROR_OBJECT (flacdec, "unsupported channel assignment: %s\n",
+        FLAC__ChannelAssignmentString[frame->header.channel_assignment]);
+    return GST_FLOW_ERROR;
+  }
+
   if (!GST_PAD_CAPS (flacdec->srcpad)) {
     GstCaps *caps;
 
@@ -1057,6 +1106,12 @@ gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
         "rate", G_TYPE_INT, frame->header.sample_rate,
         "channels", G_TYPE_INT, channels, NULL);
 
+    if (channels > 2) {
+      GstStructure *s = gst_caps_get_structure (caps, 0);
+
+      gst_audio_set_channel_positions (s, channel_positions[channels - 1]);
+    }
+
     flacdec->depth = depth;
     flacdec->width = width;
     flacdec->channels = channels;