--- a/gst_plugins_base/gst-libs/gst/audio/multichannel.c Tue Aug 31 15:30:33 2010 +0300
+++ b/gst_plugins_base/gst-libs/gst/audio/multichannel.c Wed Sep 01 12:16:41 2010 +0100
@@ -16,53 +16,32 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
-/**
- * SECTION:gstmultichannel
- * @short_description: Support for multichannel audio elements
- *
- * This module contains some helper functions and a enum to work with
- * multichannel audio.
- */
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include "multichannel.h"
#define GST_AUDIO_CHANNEL_POSITIONS_FIELD_NAME "channel-positions"
-/**
- * gst_audio_check_channel_positions:
- * @pos: An array of #GstAudioChannelPosition.
- * @channels: The number of elements in @pos.
- *
- * This functions checks if the given channel positions are valid. Channel
- * positions are valid if:
- * <itemizedlist>
- * <listitem><para>No channel positions appears twice or all positions are %GST_AUDIO_CHANNEL_POSITION_NONE.
- * </para></listitem>
- * <listitem><para>Either all or none of the channel positions are %GST_AUDIO_CHANNEL_POSITION_NONE.
- * </para></listitem>
- * <listitem><para>%GST_AUDIO_CHANNEL_POSITION_FRONT_MONO and %GST_AUDIO_CHANNEL_POSITION_LEFT or %GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT don't appear together in the given positions.
- * </para></listitem>
- * </itemizedlist>
- *
- * Since: 0.10.20
- *
- * Returns: %TRUE if the given channel positions are valid
- * and %FALSE otherwise.
+/*
+ * This function checks if basic assumptions apply:
+ * - does each position occur at most once?
+ * - do conflicting positions occur?
+ * + front_mono vs. front_left/right
+ * + front_center vs. front_left/right_of_center
+ * + rear_center vs. rear_left/right
+ * It also adds some hacks that 0.8.x needs for compatibility:
+ * - if channels == 1, are we really mono?
+ * - if channels == 2, are we really stereo?
*/
-#ifdef __SYMBIAN32__
-EXPORT_C
-#endif
-gboolean
+static gboolean
gst_audio_check_channel_positions (const GstAudioChannelPosition * pos,
- guint channels)
+ gint channels)
{
gint i, n;
-
const struct
{
const GstAudioChannelPosition pos1[2];
@@ -72,18 +51,27 @@
{ {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
- GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}}, { {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}},
+ /* front center: 2 <-> 1 */
+ { {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}},
+ /* rear: 2 <-> 1 */
+ { {
+ GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
+ GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}}, { {
GST_AUDIO_CHANNEL_POSITION_INVALID}}
};
- g_return_val_if_fail (pos != NULL, FALSE);
- g_return_val_if_fail (channels > 0, FALSE);
+ 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 ||
pos[n] >= GST_AUDIO_CHANNEL_POSITION_NUM) {
- GST_WARNING ("Channel position %d for channel %d is invalid", pos[n], n);
+ g_warning ("Channel position %d for channel %d is invalid", pos[n], n);
return FALSE;
}
}
@@ -94,7 +82,7 @@
if (pos[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
for (n = 1; n < channels; ++n) {
if (pos[n] != GST_AUDIO_CHANNEL_POSITION_NONE) {
- GST_WARNING ("Either all channel positions must be defined, or all "
+ g_warning ("Either all channel positions must be defined, or all "
"be set to NONE, having only some defined is not allowed");
return FALSE;
}
@@ -115,13 +103,13 @@
/* NONE may not occur mixed with other channel positions */
if (i == GST_AUDIO_CHANNEL_POSITION_NONE && count > 0) {
- GST_WARNING ("Either all channel positions must be defined, or all "
+ 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) {
- GST_WARNING ("Channel position %d occurred %d times, not allowed",
+ g_warning ("Channel position %d occurred %d times, not allowed",
i, count);
return FALSE;
}
@@ -139,12 +127,21 @@
}
if (found1 && found2) {
- GST_WARNING ("Found conflicting channel positions %d/%d and %d",
+ g_warning ("Found conflicting channel positions %d/%d and %d",
conf[i].pos1[0], conf[i].pos1[1], conf[i].pos2[0]);
return FALSE;
}
}
+ /* Throw warning if we encounter an unusual 2-channel configuration,
+ * at least until someone finds a reason why we should not */
+ if (channels == 2 && (pos[0] != GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT ||
+ pos[1] != GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT)) {
+ g_warning ("channels=2 implies stereo, but channel positions are "
+ "< %d, %d>", pos[0], pos[1]);
+ return FALSE;
+ }
+
return TRUE;
}
@@ -239,13 +236,9 @@
gst_audio_get_channel_positions (GstStructure * str)
{
GstAudioChannelPosition *pos;
-
gint channels, n;
-
const GValue *pos_val_arr, *pos_val_entry;
-
gboolean res;
-
GType t;
/* get number of channels, general type checkups */
@@ -323,7 +316,6 @@
GValue pos_val_arr = { 0 }, pos_val_entry = {
0};
gint channels, n;
-
gboolean res;
/* get number of channels, checkups */
@@ -391,6 +383,11 @@
g_return_if_fail (res);
g_return_if_fail (channels > 0);
+ /* 0.8.x: channels=1 or channels=2 is mono/stereo, no positions needed
+ * there (we discard them anyway) */
+ if (channels == 1 || channels == 2)
+ return;
+
/* create the array of lists */
g_value_init (&pos_val_arr, GST_TYPE_ARRAY);
g_value_init (&pos_val_entry, GST_TYPE_AUDIO_CHANNEL_POSITION);
@@ -420,7 +417,6 @@
const GstAudioChannelPosition * pos, gint num_positions)
{
GstCaps *caps = gst_caps_new_empty ();
-
const GValue *chan_val;
chan_val = gst_structure_get_value (str, "channels");
@@ -428,7 +424,6 @@
gst_audio_set_structure_channel_positions_list (str, pos, num_positions);
} else if (G_VALUE_TYPE (chan_val) == GST_TYPE_LIST) {
gint size;
-
const GValue *sub_val;
size = gst_value_list_get_size (chan_val);
@@ -531,13 +526,9 @@
gst_audio_fixate_channel_positions (GstStructure * str)
{
GstAudioChannelPosition *pos;
-
gint channels, n, num_unfixed = 0, i, c;
-
const GValue *pos_val_arr, *pos_val_entry, *pos_val;
-
gboolean res, is_stereo = TRUE;
-
GType t;
/*
@@ -552,20 +543,19 @@
const GstAudioChannelPosition pos2[1];
} conf[] = {
/* front: mono <-> stereo */
- {
- {
- GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+ { {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
- GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}}, { {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}},
+ /* front center: 2 <-> 1 */
+ { {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
- GST_AUDIO_CHANNEL_POSITION_INVALID}}, { {
- GST_AUDIO_CHANNEL_POSITION_INVALID, GST_AUDIO_CHANNEL_POSITION_INVALID}, {
- GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}}, { {
+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}},
+ /* rear: 2 <-> 1 */
+ { {
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
- GST_AUDIO_CHANNEL_POSITION_INVALID}}, { {
- GST_AUDIO_CHANNEL_POSITION_INVALID, GST_AUDIO_CHANNEL_POSITION_INVALID}, {
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}}, { {
GST_AUDIO_CHANNEL_POSITION_INVALID, GST_AUDIO_CHANNEL_POSITION_INVALID}, {
GST_AUDIO_CHANNEL_POSITION_LFE}}, { {