From 5b788a8a66080dc2a66b91ce49fa77019596b124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 16 Feb 2006 11:44:43 +0000 Subject: [PATCH] gst-libs/gst/audio/multichannel.c: When we have more than 2 channels, but no channel layout is specified in the caps,... Original commit message from CVS: * gst-libs/gst/audio/multichannel.c: (gst_audio_get_channel_positions): When we have more than 2 channels, but no channel layout is specified in the caps, return some default channel layout to the caller and warn about about a possibly buggy element (could be buggy filtercaps as well of course) (#317038). --- ChangeLog | 9 +++ gst-libs/gst/audio/multichannel.c | 97 +++++++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index a1864cf389..7eaa33ebd4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-02-16 Tim-Philipp Müller + + * gst-libs/gst/audio/multichannel.c: + (gst_audio_get_channel_positions): + When we have more than 2 channels, but no channel layout is + specified in the caps, return some default channel layout + to the caller and warn about about a possibly buggy element + (could be buggy filtercaps as well of course) (#317038). + 2006-02-16 Tim-Philipp Müller * pkgconfig/gstreamer-plugins-base-uninstalled.pc.in: diff --git a/gst-libs/gst/audio/multichannel.c b/gst-libs/gst/audio/multichannel.c index 583213412a..fee9bc2448 100644 --- a/gst-libs/gst/audio/multichannel.c +++ b/gst-libs/gst/audio/multichannel.c @@ -119,6 +119,74 @@ gst_audio_check_channel_positions (const GstAudioChannelPosition * pos, return TRUE; } +/* FIXME: these default positions may or may not be correct. In any + * case, they are mostly just a fallback for buggy plugins, so it + * should not really matter too much */ +#define NUM_DEF_CHANS 8 +static const GstAudioChannelPosition + default_positions[NUM_DEF_CHANS][NUM_DEF_CHANS] = { + /* 1 channel */ + { + GST_AUDIO_CHANNEL_POSITION_FRONT_MONO, + }, + /* 2 channels */ + { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + /* 3 channels (2.1) */ + { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE, /* or FRONT_CENTER for 3.0? */ + }, + /* 4 channels (4.0 or 3.1?) */ + { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + /* 5 channels */ + { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + }, + /* 6 channels */ + { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE, + }, + /* 7 channels */ + { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + /* 8 channels */ + { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + } +}; + /** * gst_audio_get_channel_positions: * @str: A #GstStructure to retrieve channel positions from. @@ -153,19 +221,26 @@ gst_audio_get_channel_positions (GstStructure * str) /* The following checks are here to retain compatibility for plugins not * implementing this property. They expect that channels=1 implies mono - * and channels=2 implies stereo, so we follow that. - * This might be removed during 0.9.x. */ - if (!pos_val_arr && (channels == 1 || channels == 2)) { - pos = g_new (GstAudioChannelPosition, channels); - if (channels == 1) { - pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO; - } else { - pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; - pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; + * and channels=2 implies stereo, so we follow that. */ + if (pos_val_arr == NULL) { + /* channel layouts for 1 and 2 channels are implicit, don't warn */ + if (channels > 2) { + g_warning ("Failed to retrieve channel layout from caps. This usually " + "means there is a GStreamer element that does not implement " + "multichannel audio correctly. Please file a bug."); } - return pos; + + /* just return some default channel layout if we have one */ + if (channels >= 1 && channels <= NUM_DEF_CHANS) { + const GstAudioChannelPosition *p; + + p = default_positions[channels - 1]; + return g_memdup (p, channels * sizeof (GstAudioChannelPosition)); + } + + return NULL; } - g_return_val_if_fail (pos_val_arr != NULL, NULL); + g_return_val_if_fail (gst_value_array_get_size (pos_val_arr) == channels, NULL); for (n = 0; n < channels; n++) {