ext/alsa/: Add support for cards that (only) do more than 8 channels, like the Delta 44 (#345188).

Original commit message from CVS:
* 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).
This commit is contained in:
Tim-Philipp Müller 2006-08-03 14:16:06 +00:00
parent a17d466338
commit ea41bfefd7
5 changed files with 83 additions and 10 deletions

View file

@ -1,3 +1,19 @@
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):

View file

@ -174,7 +174,7 @@ caps_add_channel_configuration (GstCaps * caps,
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);
@ -197,7 +197,7 @@ caps_add_channel_configuration (GstCaps * caps,
/* 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,
@ -211,7 +211,7 @@ caps_add_channel_configuration (GstCaps * caps,
}
/* 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);
@ -219,6 +219,21 @@ caps_add_channel_configuration (GstCaps * caps,
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 *
@ -259,8 +274,20 @@ gst_alsa_detect_channels (GstObject * obj, snd_pcm_hw_params_t * hw_params,
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);

View file

@ -119,18 +119,18 @@ static GstStaticPadTemplate alsasink_sink_factory =
"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

View file

@ -65,14 +65,32 @@ gst_audio_check_channel_positions (const GstAudioChannelPosition * pos,
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++) {
@ -83,6 +101,13 @@ gst_audio_check_channel_positions (const GstAudioChannelPosition * pos,
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);

View file

@ -51,6 +51,11 @@ typedef enum {
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;