From d19f5467ccb046b79b3c795e041f9dbb8e4f5828 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 5 Mar 2012 12:29:26 +0100 Subject: [PATCH] audio: add helper function to convert mask to channel positions ... as there may be other than raw audio formats using a channel mask, and there is already one to convert the other way around. --- gst-libs/gst/audio/audio.c | 83 ++++++++++++++++++++++++++++++++------ gst-libs/gst/audio/audio.h | 3 ++ 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/audio/audio.c b/gst-libs/gst/audio/audio.c index defa099347..86c9fdf492 100644 --- a/gst-libs/gst/audio/audio.c +++ b/gst-libs/gst/audio/audio.c @@ -572,19 +572,8 @@ gst_audio_info_from_caps (GstAudioInfo * info, const GstCaps * caps) for (i = 0; i < MIN (64, channels); i++) position[i] = GST_AUDIO_CHANNEL_POSITION_NONE; } else { - gint j; - - j = 0; - for (i = 0; i < 64; i++) { - if ((channel_mask & (G_GUINT64_CONSTANT (1) << i))) { - position[j] = default_channel_order[i]; - if (default_channel_order[i] == GST_AUDIO_CHANNEL_POSITION_INVALID) - goto invalid_channel_mask; - j++; - } - } - - if (j != channels) + if (!gst_audio_channel_positions_from_mask (channels, channel_mask, + position)) goto invalid_channel_mask; } @@ -1121,6 +1110,74 @@ gst_audio_channel_positions_to_mask (const GstAudioChannelPosition * position, channel_mask); } +/** + * gst_audio_channel_positions_from_mask: + * @channels: The number of channels + * @channel_mask: The input channel_mask + * @position: The %GstAudioChannelPositions + * @caps: a #GstCaps + * + * Convert the @channels present in @channel_mask to a @position array + * (which should have at least @channels entries ensured by caller). + * If @channel_mask is set to 0, it is considered as 'not present' for purpose + * of conversion. + * + * Returns: %TRUE if channel and channel mask are valid and could be converted + */ +gboolean +gst_audio_channel_positions_from_mask (gint channels, guint64 channel_mask, + GstAudioChannelPosition * position) +{ + g_return_val_if_fail (position != NULL, FALSE); + g_return_val_if_fail (channels != 0, FALSE); + + GST_DEBUG ("converting %d channels for " + " channel mask 0x%016" G_GINT64_MODIFIER "x"); + + if (!channel_mask) { + if (channels == 1) { + position[0] = GST_AUDIO_CHANNEL_POSITION_MONO; + } else if (channels == 2) { + position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; + position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; + } else { + goto no_channel_mask; + } + } else { + gint i, j; + + j = 0; + for (i = 0; i < 64; i++) { + if ((channel_mask & (G_GUINT64_CONSTANT (1) << i))) { + if (j < channels) + position[j] = default_channel_order[i]; + if (default_channel_order[i] == GST_AUDIO_CHANNEL_POSITION_INVALID) + goto invalid_channel_mask; + j++; + } + } + + if (j != channels) + goto invalid_channel_mask; + } + + return TRUE; + + /* ERROR */ +no_channel_mask: + { + GST_ERROR ("no channel-mask property given"); + return FALSE; + } +invalid_channel_mask: + { + GST_ERROR ("Invalid channel mask 0x%016" G_GINT64_MODIFIER + "x for %d channels", channel_mask, channels); + return FALSE; + } +} + + /** * gst_audio_get_channel_reorder_map: * @channels: The number of channels. diff --git a/gst-libs/gst/audio/audio.h b/gst-libs/gst/audio/audio.h index f1a3d11e86..c2e811bcf9 100644 --- a/gst-libs/gst/audio/audio.h +++ b/gst-libs/gst/audio/audio.h @@ -556,6 +556,9 @@ gboolean gst_audio_check_valid_channel_positions (const GstAudioChannelPos gboolean gst_audio_channel_positions_to_mask (const GstAudioChannelPosition *position, gint channels, guint64 *channel_mask); +gboolean gst_audio_channel_positions_from_mask (gint channels, guint64 channel_mask, + GstAudioChannelPosition * position); + gboolean gst_audio_get_channel_reorder_map (gint channels, const GstAudioChannelPosition * from, const GstAudioChannelPosition * to,