libs: audio: implement planar buffer support in gst_audio_buffer_reorder_channels()

https://bugzilla.gnome.org/show_bug.cgi?id=796743
This commit is contained in:
George Kiagiadakis 2018-02-13 13:24:32 +02:00
parent 09171b11ac
commit e1bc49923f

View file

@ -196,6 +196,8 @@ 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.
*
* Note: this function assumes the audio data is in interleaved layout
*
* Returns: %TRUE if the reordering was possible.
*/
gboolean
@ -248,6 +250,31 @@ gst_audio_reorder_channels (gpointer data, gsize size, GstAudioFormat format,
return TRUE;
}
static gboolean
gst_audio_meta_reorder_channels (GstAudioMeta * meta,
const GstAudioChannelPosition * from, const GstAudioChannelPosition * to)
{
gint reorder_map[64] = { 0, };
gsize tmp_offsets[64] = { 0, };
gint i;
g_return_val_if_fail (meta, FALSE);
g_return_val_if_fail (meta->info.channels > 0, FALSE);
g_return_val_if_fail (meta->info.channels <= 64, FALSE);
g_return_val_if_fail (meta->offsets != NULL, FALSE);
if (!gst_audio_get_channel_reorder_map (meta->info.channels, from, to,
reorder_map))
return FALSE;
memcpy (tmp_offsets, meta->offsets, meta->info.channels * sizeof (gsize));
for (i = 0; i < meta->info.channels; i++) {
meta->offsets[reorder_map[i]] = tmp_offsets[i];
}
return TRUE;
}
/**
* gst_audio_buffer_reorder_channels:
* @buffer: The buffer to reorder.
@ -269,7 +296,8 @@ gst_audio_buffer_reorder_channels (GstBuffer * buffer,
const GstAudioChannelPosition * from, const GstAudioChannelPosition * to)
{
GstMapInfo info;
gboolean ret;
GstAudioMeta *meta;
gboolean ret = TRUE;
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
g_return_val_if_fail (gst_buffer_is_writable (buffer), FALSE);
@ -277,15 +305,20 @@ gst_audio_buffer_reorder_channels (GstBuffer * buffer,
if (gst_audio_channel_positions_equal (from, to, channels))
return TRUE;
if (!gst_buffer_map (buffer, &info, GST_MAP_READWRITE))
return FALSE;
meta = gst_buffer_get_audio_meta (buffer);
if (meta && meta->info.layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
g_return_val_if_fail (channels == meta->info.channels, FALSE);
ret =
gst_audio_reorder_channels (info.data, info.size, format, channels, from,
to);
ret = gst_audio_meta_reorder_channels (meta, from, to);
} else {
if (!gst_buffer_map (buffer, &info, GST_MAP_READWRITE))
return FALSE;
gst_buffer_unmap (buffer, &info);
ret = gst_audio_reorder_channels (info.data, info.size, format, channels,
from, to);
gst_buffer_unmap (buffer, &info);
}
return ret;
}