From: Tim-Philipp Müller Date: Thu, 3 Aug 2006 14:16:06 +0000 (+0000) Subject: ext/alsa/: Add support for cards that (only) do more than 8 channels, like the Delta... X-Git-Tag: 1.19.3~511^2~11704 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ea41bfefd72f3f748510bf4474f361ce43f71873;p=platform%2Fupstream%2Fgstreamer.git 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). --- diff --git a/ChangeLog b/ChangeLog index b224404..9d1b6c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,21 @@ 2006-08-03 Tim-Philipp Müller + * 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 + * gst/typefind/gsttypefindfunctions.c: (plugin_init): Recognise ancient RealAudio files (see #349779). diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c index e91d479..ef17600 100644 --- a/ext/alsa/gstalsa.c +++ b/ext/alsa/gstalsa.c @@ -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); diff --git a/ext/alsa/gstalsasink.c b/ext/alsa/gstalsasink.c index 1913960..216c185 100644 --- a/ext/alsa/gstalsasink.c +++ b/ext/alsa/gstalsasink.c @@ -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 diff --git a/gst-libs/gst/audio/multichannel.c b/gst-libs/gst/audio/multichannel.c index a09153d..1fbf511 100644 --- a/gst-libs/gst/audio/multichannel.c +++ b/gst-libs/gst/audio/multichannel.c @@ -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); diff --git a/gst-libs/gst/audio/multichannel.h b/gst-libs/gst/audio/multichannel.h index 3138e55..8af0adf 100644 --- a/gst-libs/gst/audio/multichannel.h +++ b/gst-libs/gst/audio/multichannel.h @@ -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;