Skip to content
Snippets Groups Projects
Commit 07d23aa5 authored by George Kiagiadakis's avatar George Kiagiadakis
Browse files

audioconvert: implement support for converting between interleaved and non-interleaved layouts

parent d65398a0
No related branches found
No related tags found
No related merge requests found
......@@ -169,7 +169,7 @@ G_DEFINE_TYPE_WITH_CODE (GstAudioConvert, gst_audio_convert,
#define STATIC_CAPS \
GST_STATIC_CAPS (GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL) \
", layout = (string) interleaved")
", layout = (string) { interleaved, non-interleaved }")
static GstStaticPadTemplate gst_audio_convert_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
......@@ -307,6 +307,14 @@ remove_format_from_structure (GstCapsFeatures * features,
return TRUE;
}
static gboolean
remove_layout_from_structure (GstCapsFeatures * features,
GstStructure * structure, gpointer user_data G_GNUC_UNUSED)
{
gst_structure_remove_field (structure, "layout");
return TRUE;
}
static gboolean
remove_channels_from_structure (GstCapsFeatures * features, GstStructure * s,
gpointer user_data)
......@@ -352,6 +360,7 @@ gst_audio_convert_transform_caps (GstBaseTransform * btrans,
tmp = gst_caps_copy (caps);
gst_caps_map_in_place (tmp, remove_format_from_structure, NULL);
gst_caps_map_in_place (tmp, remove_layout_from_structure, NULL);
gst_caps_map_in_place (tmp, remove_channels_from_structure, btrans);
/* We can infer the required input / output channels based on the
......@@ -792,14 +801,17 @@ gst_audio_convert_transform (GstBaseTransform * base, GstBuffer * inbuf,
{
GstFlowReturn ret;
GstAudioConvert *this = GST_AUDIO_CONVERT (base);
GstMapInfo srcmap = { NULL, }, dstmap;
GstAudioMeta *meta;
GstAudioMapInfo srcmap, dstmap;
gint insize, outsize;
gboolean inbuf_writable;
GstAudioConverterFlags flags;
gsize samples;
/* get amount of samples to convert. */
samples = gst_buffer_get_size (inbuf) / this->in_info.bpf;
meta = gst_buffer_get_audio_meta (inbuf);
samples =
meta ? meta->samples : (gst_buffer_get_size (inbuf) / this->in_info.bpf);
/* get in/output sizes, to see if the buffers we got are of correct
* sizes */
......@@ -811,27 +823,32 @@ gst_audio_convert_transform (GstBaseTransform * base, GstBuffer * inbuf,
gst_buffer_resize (outbuf, 0, outsize);
if (inbuf != outbuf) {
gst_buffer_add_audio_meta (outbuf, this->out_info.finfo->format,
this->out_info.layout, this->out_info.channels, samples, NULL);
}
/* get src and dst data */
if (inbuf != outbuf) {
inbuf_writable = gst_buffer_is_writable (inbuf)
&& gst_buffer_n_memory (inbuf) == 1
&& gst_memory_is_writable (gst_buffer_peek_memory (inbuf, 0));
if (!gst_buffer_map (inbuf, &srcmap,
if (!gst_audio_buffer_map (inbuf, &srcmap,
inbuf_writable ? GST_MAP_READWRITE : GST_MAP_READ))
goto inmap_error;
} else {
inbuf_writable = TRUE;
}
if (!gst_buffer_map (outbuf, &dstmap, GST_MAP_WRITE))
if (!gst_audio_buffer_map (outbuf, &dstmap, GST_MAP_WRITE))
goto outmap_error;
/* check in and outsize */
if (inbuf != outbuf) {
if (srcmap.size < insize)
if (srcmap.n_planes * srcmap.plane_size < insize)
goto wrong_size;
}
if (dstmap.size < outsize)
if (dstmap.n_planes * dstmap.plane_size < outsize)
goto wrong_size;
/* and convert the samples */
......@@ -840,22 +857,24 @@ gst_audio_convert_transform (GstBaseTransform * base, GstBuffer * inbuf,
flags |= GST_AUDIO_CONVERTER_FLAG_IN_WRITABLE;
if (!GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) {
gpointer in[1] = { srcmap.data };
gpointer out[1] = { dstmap.data };
if (!gst_audio_converter_samples (this->convert, flags,
inbuf != outbuf ? in : out, samples, out, samples))
inbuf != outbuf ? srcmap.planes : dstmap.planes, samples,
dstmap.planes, samples))
goto convert_error;
} else {
/* Create silence buffer */
gst_audio_format_fill_silence (this->out_info.finfo, dstmap.data, outsize);
gint i;
for (i = 0; i < dstmap.n_planes; i++) {
gst_audio_format_fill_silence (this->out_info.finfo, dstmap.planes[i],
dstmap.plane_size);
}
}
ret = GST_FLOW_OK;
done:
gst_buffer_unmap (outbuf, &dstmap);
gst_audio_buffer_unmap (outbuf, &dstmap);
if (inbuf != outbuf)
gst_buffer_unmap (inbuf, &srcmap);
gst_audio_buffer_unmap (inbuf, &srcmap);
return ret;
......@@ -866,7 +885,8 @@ wrong_size:
(NULL),
("input/output buffers are of wrong size in: %" G_GSIZE_FORMAT " < %d"
" or out: %" G_GSIZE_FORMAT " < %d",
srcmap.size, insize, dstmap.size, outsize));
srcmap.n_planes * srcmap.plane_size, insize,
dstmap.n_planes * dstmap.plane_size, outsize));
ret = GST_FLOW_ERROR;
goto done;
}
......@@ -888,7 +908,7 @@ outmap_error:
GST_ELEMENT_ERROR (this, STREAM, FORMAT,
(NULL), ("failed to map output buffer"));
if (inbuf != outbuf)
gst_buffer_unmap (inbuf, &srcmap);
gst_audio_buffer_unmap (inbuf, &srcmap);
return GST_FLOW_ERROR;
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment