2006-08-03 Tim-Philipp Müller <tim at centricular dot net>
+ * ext/alsa/gstalsa.c: (caps_add_channel_configuration),
+ (gst_alsa_detect_channels):
+ * ext/alsa/gstalsasink.c:
+ Add support for cards that (only) do more than 8 channels,
+ like the Delta 44 (#345188).
+
+ * gst-libs/gst/audio/multichannel.c:
+ (gst_audio_check_channel_positions):
+ * gst-libs/gst/audio/multichannel.h:
+ API: add GST_AUDIO_CHANNEL_POSITION_NONE, which stands for an
+ unspecified channel position and cannot be combined with any
+ of the other audio channel positions; adjust position layout
+ checks accordingly (#345188).
+
+2006-08-03 Tim-Philipp Müller <tim at centricular dot net>
+
* gst/typefind/gsttypefindfunctions.c: (plugin_init):
Recognise ancient RealAudio files (see #349779).
GstStructure *s = NULL;
gint c;
- if (min_chans == max_chans) {
+ if (min_chans == max_chans && max_chans <= 2) {
s = get_channel_free_structure (in_structure);
gst_structure_set (s, "channels", G_TYPE_INT, max_chans, NULL);
gst_caps_append_structure (caps, s);
/* don't know whether to use 2.1 or 3.0 here - but I suspect
* alsa might work around that/fix it somehow. Can we tell alsa
* what our channel layout is like? */
- if (max_chans >= 3) {
+ if (max_chans >= 3 && min_chans <= 3) {
GstAudioChannelPosition pos_21[3] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
}
/* everything else (4, 6, 8 channels) needs a channel layout */
- for (c = 4; c <= 8; c += 2) {
+ for (c = MAX (4, min_chans); c <= 8; c += 2) {
if (max_chans >= c) {
s = get_channel_free_structure (in_structure);
gst_structure_set (s, "channels", G_TYPE_INT, c, NULL);
gst_caps_append_structure (caps, s);
}
}
+
+ for (c = MAX (9, min_chans); c <= max_chans; ++c) {
+ GstAudioChannelPosition *ch_layout;
+ guint i;
+
+ ch_layout = g_new (GstAudioChannelPosition, c);
+ for (i = 0; i < c; ++i) {
+ ch_layout[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
+ }
+ s = get_channel_free_structure (in_structure);
+ gst_structure_set (s, "channels", G_TYPE_INT, c, NULL);
+ gst_audio_set_channel_positions (s, ch_layout);
+ gst_caps_append_structure (caps, s);
+ g_free (ch_layout);
+ }
}
static GstCaps *
max_chans = temp;
}
- min_chans = MAX (min_chans, 1);
- max_chans = MIN (GST_ALSA_MAX_CHANNELS, max_chans);
+ /* pro cards seem to return large numbers for min_channels */
+ if (min_chans > GST_ALSA_MAX_CHANNELS) {
+ GST_DEBUG_OBJECT (obj, "min_chans = %u, looks like a pro card", min_chans);
+ if (max_chans < min_chans) {
+ max_chans = min_chans;
+ } else {
+ /* only support [max_chans; max_chans] for these cards for now
+ * to avoid inflating the source caps with loads of structures ... */
+ min_chans = max_chans;
+ }
+ } else {
+ min_chans = MAX (min_chans, 1);
+ max_chans = MIN (GST_ALSA_MAX_CHANNELS, max_chans);
+ }
GST_DEBUG_OBJECT (obj, "Min. channels = %d (%d)", min_chans, min);
GST_DEBUG_OBJECT (obj, "Max. channels = %d (%d)", max_chans, max);
"signed = (boolean) { TRUE, FALSE }, "
"width = (int) 32, "
"depth = (int) 32, "
- "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 8 ]; "
+ "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]; "
"audio/x-raw-int, "
"endianness = (int) { " ALSA_SINK_FACTORY_ENDIANNESS " }, "
"signed = (boolean) { TRUE, FALSE }, "
"width = (int) 16, "
"depth = (int) 16, "
- "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 8 ]; "
+ "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]; "
"audio/x-raw-int, "
"signed = (boolean) { TRUE, FALSE }, "
"width = (int) 8, "
"depth = (int) 8, "
- "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 8 ]")
+ "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]")
);
static void
GST_AUDIO_CHANNEL_POSITION_INVALID}}
};
+ g_assert (pos != NULL && channels > 0);
+
/* check for invalid channel positions */
for (n = 0; n < channels; n++) {
- if (pos[n] == GST_AUDIO_CHANNEL_POSITION_INVALID) {
- g_warning ("Position %d is invalid, not allowed", n);
+ if (pos[n] <= GST_AUDIO_CHANNEL_POSITION_INVALID ||
+ pos[n] >= GST_AUDIO_CHANNEL_POSITION_NUM) {
+ g_warning ("Channel position %d is invalid, not allowed", n);
return FALSE;
}
}
+ /* either all channel positions are NONE or all are defined,
+ * but having only some channel positions NONE and others not
+ * is not allowed */
+ if (pos[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
+ for (n = 1; n < channels; ++n) {
+ if (pos[n] != GST_AUDIO_CHANNEL_POSITION_NONE) {
+ g_warning ("Either all channel positions must be defined, or all "
+ "be set to NONE, having only some defined is not allowed");
+ return FALSE;
+ }
+ }
+ /* all positions are NONE, we are done here */
+ return TRUE;
+ }
+
/* check for multiple position occurrences */
for (i = GST_AUDIO_CHANNEL_POSITION_INVALID + 1;
i < GST_AUDIO_CHANNEL_POSITION_NUM; i++) {
count++;
}
+ /* NONE may not occur mixed with other channel positions */
+ if (i == GST_AUDIO_CHANNEL_POSITION_NONE && count > 0) {
+ g_warning ("Either all channel positions must be defined, or all "
+ "be set to NONE, having only some defined is not allowed");
+ return FALSE;
+ }
+
if (count > 1) {
g_warning ("Channel position %d occurred %d times, not allowed",
i, count);
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
+ /* for multi-channel input and output with more than 8 channels,
+ * incompatible with all other positions, either all positions
+ * are defined or all positions are undefined, but can't mix'n'match */
+ GST_AUDIO_CHANNEL_POSITION_NONE,
+
/* don't use - counter */
GST_AUDIO_CHANNEL_POSITION_NUM
} GstAudioChannelPosition;