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
This commit is contained in:
Tim-Philipp Müller 2016-01-07 18:26:26 +00:00
parent 5b5398d613
commit a3019ffb63

View file

@ -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);
}