mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-27 09:38:17 +00:00
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:
parent
a17d466338
commit
ea41bfefd7
5 changed files with 83 additions and 10 deletions
16
ChangeLog
16
ChangeLog
|
@ -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>
|
2006-08-03 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* gst/typefind/gsttypefindfunctions.c: (plugin_init):
|
* gst/typefind/gsttypefindfunctions.c: (plugin_init):
|
||||||
|
|
|
@ -174,7 +174,7 @@ caps_add_channel_configuration (GstCaps * caps,
|
||||||
GstStructure *s = NULL;
|
GstStructure *s = NULL;
|
||||||
gint c;
|
gint c;
|
||||||
|
|
||||||
if (min_chans == max_chans) {
|
if (min_chans == max_chans && max_chans <= 2) {
|
||||||
s = get_channel_free_structure (in_structure);
|
s = get_channel_free_structure (in_structure);
|
||||||
gst_structure_set (s, "channels", G_TYPE_INT, max_chans, NULL);
|
gst_structure_set (s, "channels", G_TYPE_INT, max_chans, NULL);
|
||||||
gst_caps_append_structure (caps, s);
|
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
|
/* 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
|
* alsa might work around that/fix it somehow. Can we tell alsa
|
||||||
* what our channel layout is like? */
|
* what our channel layout is like? */
|
||||||
if (max_chans >= 3) {
|
if (max_chans >= 3 && min_chans <= 3) {
|
||||||
GstAudioChannelPosition pos_21[3] = {
|
GstAudioChannelPosition pos_21[3] = {
|
||||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
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 */
|
/* 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) {
|
if (max_chans >= c) {
|
||||||
s = get_channel_free_structure (in_structure);
|
s = get_channel_free_structure (in_structure);
|
||||||
gst_structure_set (s, "channels", G_TYPE_INT, c, NULL);
|
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);
|
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 *
|
static GstCaps *
|
||||||
|
@ -259,8 +274,20 @@ gst_alsa_detect_channels (GstObject * obj, snd_pcm_hw_params_t * hw_params,
|
||||||
max_chans = temp;
|
max_chans = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
min_chans = MAX (min_chans, 1);
|
/* pro cards seem to return large numbers for min_channels */
|
||||||
max_chans = MIN (GST_ALSA_MAX_CHANNELS, max_chans);
|
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, "Min. channels = %d (%d)", min_chans, min);
|
||||||
GST_DEBUG_OBJECT (obj, "Max. channels = %d (%d)", max_chans, max);
|
GST_DEBUG_OBJECT (obj, "Max. channels = %d (%d)", max_chans, max);
|
||||||
|
|
|
@ -119,18 +119,18 @@ static GstStaticPadTemplate alsasink_sink_factory =
|
||||||
"signed = (boolean) { TRUE, FALSE }, "
|
"signed = (boolean) { TRUE, FALSE }, "
|
||||||
"width = (int) 32, "
|
"width = (int) 32, "
|
||||||
"depth = (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, "
|
"audio/x-raw-int, "
|
||||||
"endianness = (int) { " ALSA_SINK_FACTORY_ENDIANNESS " }, "
|
"endianness = (int) { " ALSA_SINK_FACTORY_ENDIANNESS " }, "
|
||||||
"signed = (boolean) { TRUE, FALSE }, "
|
"signed = (boolean) { TRUE, FALSE }, "
|
||||||
"width = (int) 16, "
|
"width = (int) 16, "
|
||||||
"depth = (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, "
|
"audio/x-raw-int, "
|
||||||
"signed = (boolean) { TRUE, FALSE }, "
|
"signed = (boolean) { TRUE, FALSE }, "
|
||||||
"width = (int) 8, "
|
"width = (int) 8, "
|
||||||
"depth = (int) 8, "
|
"depth = (int) 8, "
|
||||||
"rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 8 ]")
|
"rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]")
|
||||||
);
|
);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -65,14 +65,32 @@ gst_audio_check_channel_positions (const GstAudioChannelPosition * pos,
|
||||||
GST_AUDIO_CHANNEL_POSITION_INVALID}}
|
GST_AUDIO_CHANNEL_POSITION_INVALID}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
g_assert (pos != NULL && channels > 0);
|
||||||
|
|
||||||
/* check for invalid channel positions */
|
/* check for invalid channel positions */
|
||||||
for (n = 0; n < channels; n++) {
|
for (n = 0; n < channels; n++) {
|
||||||
if (pos[n] == GST_AUDIO_CHANNEL_POSITION_INVALID) {
|
if (pos[n] <= GST_AUDIO_CHANNEL_POSITION_INVALID ||
|
||||||
g_warning ("Position %d is invalid, not allowed", n);
|
pos[n] >= GST_AUDIO_CHANNEL_POSITION_NUM) {
|
||||||
|
g_warning ("Channel position %d is invalid, not allowed", n);
|
||||||
return FALSE;
|
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 */
|
/* check for multiple position occurrences */
|
||||||
for (i = GST_AUDIO_CHANNEL_POSITION_INVALID + 1;
|
for (i = GST_AUDIO_CHANNEL_POSITION_INVALID + 1;
|
||||||
i < GST_AUDIO_CHANNEL_POSITION_NUM; i++) {
|
i < GST_AUDIO_CHANNEL_POSITION_NUM; i++) {
|
||||||
|
@ -83,6 +101,13 @@ gst_audio_check_channel_positions (const GstAudioChannelPosition * pos,
|
||||||
count++;
|
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) {
|
if (count > 1) {
|
||||||
g_warning ("Channel position %d occurred %d times, not allowed",
|
g_warning ("Channel position %d occurred %d times, not allowed",
|
||||||
i, count);
|
i, count);
|
||||||
|
|
|
@ -51,6 +51,11 @@ typedef enum {
|
||||||
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
|
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
|
||||||
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
|
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 */
|
/* don't use - counter */
|
||||||
GST_AUDIO_CHANNEL_POSITION_NUM
|
GST_AUDIO_CHANNEL_POSITION_NUM
|
||||||
} GstAudioChannelPosition;
|
} GstAudioChannelPosition;
|
||||||
|
|
Loading…
Reference in a new issue