summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.com>2016-01-07 18:26:26 +0000
committerTim-Philipp Müller <tim@centricular.com>2016-02-21 12:20:10 +0000
commita3019ffb63b1213cbad10abafa4e0ee9cd53c66b (patch)
tree9bad315135f7d5dbba5070c37680d2e279fd344f /gst
parent5b5398d613fb8ffdeb420bfd578eceaf4d3445e8 (diff)
downloadgstreamer-plugins-bad-a3019ffb63b1213cbad10abafa4e0ee9cd53c66b.tar.gz
aiffparse: fix negotiation errors with multi-channel files
Set fallback channel layout on files with more than two channels. Not clear where to retrieve the real layout from or what the default layout is for AIFF files, the spec only seems to specify some layout for up to 6 channels and the file in question doesn't have a CHAN chunk. https://bugzilla.gnome.org/show_bug.cgi?id=676425
Diffstat (limited to 'gst')
-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);
}