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 @to. @from and @to must contain the same number of
* positions and the same positions, only in a different order. * 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. * Returns: %TRUE if the reordering was possible.
*/ */
gboolean gboolean
@ -248,6 +250,31 @@ gst_audio_reorder_channels (gpointer data, gsize size, GstAudioFormat format,
return TRUE; 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: * gst_audio_buffer_reorder_channels:
* @buffer: The buffer to reorder. * @buffer: The buffer to reorder.
@ -269,7 +296,8 @@ gst_audio_buffer_reorder_channels (GstBuffer * buffer,
const GstAudioChannelPosition * from, const GstAudioChannelPosition * to) const GstAudioChannelPosition * from, const GstAudioChannelPosition * to)
{ {
GstMapInfo info; 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_IS_BUFFER (buffer), FALSE);
g_return_val_if_fail (gst_buffer_is_writable (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)) if (gst_audio_channel_positions_equal (from, to, channels))
return TRUE; return TRUE;
if (!gst_buffer_map (buffer, &info, GST_MAP_READWRITE)) meta = gst_buffer_get_audio_meta (buffer);
return FALSE; if (meta && meta->info.layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
g_return_val_if_fail (channels == meta->info.channels, FALSE);
ret = ret = gst_audio_meta_reorder_channels (meta, from, to);
gst_audio_reorder_channels (info.data, info.size, format, channels, from, } else {
to); 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; return ret;
} }