From 9e3bb0a0094fe25e6d79bf5c354e603c9d92dbe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 18 Dec 2024 19:45:27 +0200 Subject: [PATCH] audio: Add new gst_audio_reorder_channels_with_reorder_map() This allows reordering the samples with a pre-calculated reorder map instead of calculating it again every time. Part-of: --- girs/GstAudio-1.0.gir | 45 ++++++++++++ .../gst-libs/gst/audio/audio-channels.c | 71 ++++++++++++++----- .../gst-libs/gst/audio/audio-channels.h | 6 ++ 3 files changed, 105 insertions(+), 17 deletions(-) diff --git a/girs/GstAudio-1.0.gir b/girs/GstAudio-1.0.gir index 8f262cbfe7..3d5ff834ea 100644 --- a/girs/GstAudio-1.0.gir +++ b/girs/GstAudio-1.0.gir @@ -11616,6 +11616,12 @@ the @dither and @ns parameters. positions @to. @from and @to must contain the same number of positions and the same positions, only in a different order. +This function internally calls gst_audio_get_channel_reorder_map() and +gst_audio_reorder_channels_with_reorder_map(). It is more efficient to call +gst_audio_get_channel_reorder_map() once to retrieve the reorder map and +then call gst_audio_reorder_channels_with_reorder_map() with the same +reorder map until the channel positions change. + Note: this function assumes the audio data is in interleaved layout @@ -11656,6 +11662,45 @@ Note: this function assumes the audio data is in interleaved layout + + Reorders @data with the given @reorder_map. + +The reorder map can be retrieved for example with +gst_audio_get_channel_reorder_map(). + +Note: this function assumes the audio data is in interleaved layout + + + + + + + The pointer to + the memory. + + + + + + The size of the memory. + + + + The number of bytes per sample. + + + + The number of channels. + + + + The channel reorder map. + + + + + + Make a new resampler. diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/audio-channels.c b/subprojects/gst-plugins-base/gst-libs/gst/audio/audio-channels.c index ea1b533c7f..642049b980 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/audio-channels.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/audio-channels.c @@ -182,6 +182,52 @@ check_valid_channel_positions (const GstAudioChannelPosition * position, return TRUE; } +/** + * gst_audio_reorder_channels_with_reorder_map: + * @data: (array length=size) (element-type guint8): The pointer to + * the memory. + * @size: The size of the memory. + * @bps: The number of bytes per sample. + * @channels: The number of channels. + * @reorder_map: (array length=channels): The channel reorder map. + * + * Reorders @data with the given @reorder_map. + * + * The reorder map can be retrieved for example with + * gst_audio_get_channel_reorder_map(). + * + * Note: this function assumes the audio data is in interleaved layout + * + * Since: 1.26 + */ +void +gst_audio_reorder_channels_with_reorder_map (gpointer data, gsize size, + gint bps, gint channels, const gint * reorder_map) +{ + gint bpf = bps * channels; + guint8 *ptr = data; + gsize n; + + g_return_if_fail (data != NULL); + g_return_if_fail (size % (bps * channels) == 0); + g_return_if_fail (bps > 0); + g_return_if_fail (bps <= 64); + g_return_if_fail (channels > 0); + g_return_if_fail (channels <= 64); + g_return_if_fail (reorder_map != NULL); + + n = size / bpf; + for (gsize i = 0; i < n; i++) { + guint8 tmp[64 * 8]; + + memcpy (tmp, ptr, bpf); + for (gint j = 0; j < channels; j++) + memcpy (ptr + reorder_map[j] * bps, tmp + j * bps, bps); + + ptr += bpf; + } +} + /** * gst_audio_reorder_channels: * @data: (array length=size) (element-type guint8): The pointer to @@ -196,6 +242,12 @@ check_valid_channel_positions (const GstAudioChannelPosition * position, * positions @to. @from and @to must contain the same number of * positions and the same positions, only in a different order. * + * This function internally calls gst_audio_get_channel_reorder_map() and + * gst_audio_reorder_channels_with_reorder_map(). It is more efficient to call + * gst_audio_get_channel_reorder_map() once to retrieve the reorder map and + * then call gst_audio_reorder_channels_with_reorder_map() with the same + * reorder map until the channel positions change. + * * Note: this function assumes the audio data is in interleaved layout * * Returns: %TRUE if the reordering was possible. @@ -206,11 +258,7 @@ gst_audio_reorder_channels (gpointer data, gsize size, GstAudioFormat format, const GstAudioChannelPosition * to) { const GstAudioFormatInfo *info; - gint i, j, n; gint reorder_map[64] = { 0, }; - guint8 *ptr; - gint bpf, bps; - guint8 tmp[64 * 8]; info = gst_audio_format_get_info (format); @@ -234,19 +282,8 @@ gst_audio_reorder_channels (gpointer data, gsize size, GstAudioFormat format, if (!gst_audio_get_channel_reorder_map (channels, from, to, reorder_map)) return FALSE; - bps = info->width / 8; - bpf = bps * channels; - ptr = data; - - n = size / bpf; - for (i = 0; i < n; i++) { - - memcpy (tmp, ptr, bpf); - for (j = 0; j < channels; j++) - memcpy (ptr + reorder_map[j] * bps, tmp + j * bps, bps); - - ptr += bpf; - } + gst_audio_reorder_channels_with_reorder_map (data, size, info->width / 8, + channels, reorder_map); return TRUE; } diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/audio-channels.h b/subprojects/gst-plugins-base/gst-libs/gst/audio/audio-channels.h index 0089257b12..c0b63d472d 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/audio-channels.h +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/audio-channels.h @@ -145,6 +145,12 @@ gboolean gst_audio_reorder_channels (gpointer data, gsize size, const GstAudioChannelPosition * from, const GstAudioChannelPosition * to); +GST_AUDIO_API +void gst_audio_reorder_channels_with_reorder_map (gpointer data, gsize size, + gint bps, + gint channels, + const gint *reorder_map); + GST_AUDIO_API gboolean gst_audio_channel_positions_to_valid_order (GstAudioChannelPosition *position, gint channels);