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>
|
||||
|
||||
* gst/typefind/gsttypefindfunctions.c: (plugin_init):
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue