summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gst/aiff/aiffparse.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/gst/aiff/aiffparse.c b/gst/aiff/aiffparse.c
index 7ca19c6ea..5600a7eb8 100644
--- a/gst/aiff/aiffparse.c
+++ b/gst/aiff/aiffparse.c
@@ -816,11 +816,14 @@ too_small:
}
+#define _P(pos) (G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_ ##pos)
+
static GstCaps *
gst_aiff_parse_create_caps (GstAiffParse * aiff)
{
GstCaps *caps = NULL;
const gchar *format = NULL;
+ guint64 channel_mask;
if (aiff->floating_point) {
if (aiff->endianness == G_BIG_ENDIAN) {
@@ -858,6 +861,44 @@ gst_aiff_parse_create_caps (GstAiffParse * aiff)
"rate", G_TYPE_INT, aiff->rate, NULL);
}
+ if (aiff->channels > 2) {
+ GST_FIXME_OBJECT (aiff, "using fallback channel layout for %d channels",
+ aiff->channels);
+
+ /* based on AIFF-1.3.pdf */
+ switch (aiff->channels) {
+ case 1:
+ channel_mask = 0;
+ break;
+ case 2:
+ channel_mask = _P (FRONT_LEFT) | _P (FRONT_RIGHT);
+ break;
+ case 3:
+ channel_mask = _P (FRONT_LEFT) | _P (FRONT_RIGHT) | _P (FRONT_CENTER);
+ break;
+ case 4:
+ /* lists both this and 'quad' but doesn't say how to distinguish the two */
+ channel_mask =
+ _P (FRONT_LEFT) | _P (FRONT_RIGHT) | _P (REAR_LEFT) |
+ _P (REAR_RIGHT);
+ break;
+ case 6:
+ channel_mask =
+ _P (FRONT_LEFT) | _P (FRONT_LEFT_OF_CENTER) | _P (FRONT_CENTER) |
+ _P (FRONT_RIGHT) | _P (FRONT_RIGHT_OF_CENTER) | _P (LFE1);
+ break;
+ default:
+ channel_mask = gst_audio_channel_get_fallback_mask (aiff->channels);
+ break;
+ }
+
+
+ if (channel_mask != 0) {
+ gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
+ NULL);
+ }
+ }
+
GST_DEBUG_OBJECT (aiff, "Created caps: %" GST_PTR_FORMAT, caps);
return caps;
@@ -1050,6 +1091,11 @@ gst_aiff_parse_stream_headers (GstAiffParse * aiff)
}
break;
}
+ case GST_MAKE_FOURCC ('C', 'H', 'A', 'N'):{
+ GST_FIXME_OBJECT (aiff, "Handle CHAN chunk with channel layouts");
+ gst_aiff_parse_ignore_chunk (aiff, tag, size);
+ break;
+ }
default:
gst_aiff_parse_ignore_chunk (aiff, tag, size);
}