...
 
......@@ -80,6 +80,7 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
gint rate, gint bpf)
{
GstBuffer *ret;
GstAudioMeta *meta;
GstClockTime timestamp = GST_CLOCK_TIME_NONE, duration = GST_CLOCK_TIME_NONE;
guint64 offset = GST_BUFFER_OFFSET_NONE, offset_end = GST_BUFFER_OFFSET_NONE;
gsize trim, size, osize;
......@@ -98,8 +99,11 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
* Calculate the missing values for the calculations,
* they won't be changed later though. */
meta = gst_buffer_get_audio_meta (buffer);
/* these variables measure samples */
trim = 0;
osize = size = gst_buffer_get_size (buffer);
osize = size = meta ? meta->samples : (gst_buffer_get_size (buffer) / bpf);
/* no data, nothing to clip */
if (!size)
......@@ -111,7 +115,7 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
duration = GST_BUFFER_DURATION (buffer);
} else {
change_duration = FALSE;
duration = gst_util_uint64_scale (size / bpf, GST_SECOND, rate);
duration = gst_util_uint64_scale (size, GST_SECOND, rate);
}
if (GST_BUFFER_OFFSET_IS_VALID (buffer)) {
......@@ -125,7 +129,7 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
offset_end = GST_BUFFER_OFFSET_END (buffer);
} else {
change_offset_end = FALSE;
offset_end = offset + size / bpf;
offset_end = offset + size;
}
if (segment->format == GST_FORMAT_TIME) {
......@@ -149,8 +153,8 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
diff = gst_util_uint64_scale (diff, rate, GST_SECOND);
if (change_offset)
offset += diff;
trim += diff * bpf;
size -= diff * bpf;
trim += diff;
size -= diff;
}
diff = stop - cstop;
......@@ -161,7 +165,7 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
diff = gst_util_uint64_scale (diff, rate, GST_SECOND);
if (change_offset_end)
offset_end -= diff;
size -= diff * bpf;
size -= diff;
}
} else {
gst_buffer_unref (buffer);
......@@ -188,8 +192,8 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
if (change_duration)
duration -= gst_util_uint64_scale (diff, GST_SECOND, rate);
trim += diff * bpf;
size -= diff * bpf;
trim += diff;
size -= diff;
}
diff = stop - cstop;
......@@ -199,7 +203,7 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
if (change_duration)
duration -= gst_util_uint64_scale (diff, GST_SECOND, rate);
size -= diff * bpf;
size -= diff;
}
} else {
gst_buffer_unref (buffer);
......@@ -218,8 +222,34 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
ret = gst_buffer_make_writable (ret);
GST_BUFFER_DURATION (ret) = duration;
}
} else if (meta && meta->layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
/* modify only the meta to avoid making copies of the planes */
gint i;
ret = gst_buffer_make_writable (buffer);
meta = gst_buffer_get_audio_meta (buffer);
meta->samples = size;
for (i = 0; i < meta->channels; i++) {
meta->offsets[i] += trim * bpf / meta->channels;
}
GST_BUFFER_TIMESTAMP (ret) = timestamp;
if (change_duration)
GST_BUFFER_DURATION (ret) = duration;
if (change_offset)
GST_BUFFER_OFFSET (ret) = offset;
if (change_offset_end)
GST_BUFFER_OFFSET_END (ret) = offset_end;
} else {
/* Get a writable buffer and apply all changes */
/* resize the buffer, effectively cutting out all
* the samples that are no longer relevant */
/* convert samples to bytes */
trim *= bpf;
size *= bpf;
GST_DEBUG ("trim %" G_GSIZE_FORMAT " size %" G_GSIZE_FORMAT, trim, size);
ret = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, trim, size);
gst_buffer_unref (buffer);
......
......@@ -304,3 +304,165 @@ gst_audio_clipping_meta_get_info (void)
}
return audio_clipping_meta_info;
}
static gboolean
gst_audio_meta_init (GstMeta * meta, gpointer params, GstBuffer * buffer)
{
GstAudioMeta *ameta = (GstAudioMeta *) meta;
ameta->format = GST_AUDIO_FORMAT_UNKNOWN;
ameta->layout = GST_AUDIO_LAYOUT_INTERLEAVED;
ameta->channels = ameta->samples = 0;
ameta->offsets = NULL;
return TRUE;
}
static void
gst_audio_meta_free (GstMeta * meta, GstBuffer * buffer)
{
GstAudioMeta *ameta = (GstAudioMeta *) meta;
if (ameta->offsets)
g_slice_free1 (ameta->channels * sizeof (gsize), ameta->offsets);
}
static gboolean
gst_audio_meta_transform (GstBuffer * dest, GstMeta * meta,
GstBuffer * buffer, GQuark type, gpointer data)
{
GstAudioMeta *smeta, *dmeta;
smeta = (GstAudioMeta *) meta;
if (GST_META_TRANSFORM_IS_COPY (type)) {
dmeta = gst_buffer_add_audio_meta (dest, smeta->format, smeta->layout,
smeta->channels, smeta->samples, smeta->offsets);
if (!dmeta)
return FALSE;
} else {
/* return FALSE, if transform type is not supported */
return FALSE;
}
return TRUE;
}
GstAudioMeta *
gst_buffer_add_audio_meta (GstBuffer * buffer, GstAudioFormat format,
GstAudioLayout layout, gint channels, gint samples, gsize offsets[])
{
GstAudioMeta *meta;
gint i;
g_return_val_if_fail (format != GST_AUDIO_FORMAT_UNKNOWN, NULL);
meta =
(GstAudioMeta *) gst_buffer_add_meta (buffer, GST_AUDIO_META_INFO, NULL);
meta->format = format;
meta->layout = layout;
meta->channels = channels;
meta->samples = samples;
if (layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
meta->offsets = g_slice_alloc (channels * sizeof (gsize));
if (offsets) {
for (i = 0; i < channels; i++)
meta->offsets[i] = offsets[i];
} else {
/* default offsets assume channels are laid out sequentially in memory */
const GstAudioFormatInfo *finfo =
gst_audio_format_get_info (meta->format);
for (i = 0; i < channels; i++)
meta->offsets[i] = i * samples * finfo->width / 8;
}
}
return meta;
}
gboolean
gst_audio_buffer_map (GstBuffer * buffer, GstAudioMapInfo * info,
GstMapFlags flags)
{
GstAudioMeta *meta = NULL;
gboolean ret = TRUE;
gint i;
meta = gst_buffer_get_audio_meta (buffer);
if (!meta || meta->layout == GST_AUDIO_LAYOUT_INTERLEAVED) {
/* interleaved */
if (!gst_buffer_map (buffer, &info->map_info, flags))
return FALSE;
info->n_planes = 1;
info->plane_size = info->map_info.size;
info->planes = g_slice_alloc (info->n_planes * sizeof (gpointer));
info->planes[0] = info->map_info.data;
} else {
/* non-interleaved */
const GstAudioFormatInfo *finfo = gst_audio_format_get_info (meta->format);
if (!gst_buffer_map (buffer, &info->map_info, flags))
return FALSE;
info->n_planes = meta->channels;
info->plane_size = meta->samples * finfo->width / 8;
if (info->n_planes * info->plane_size > info->map_info.size) {
GST_ERROR ("Invalid buffer size according to its attached GstAudioMeta");
gst_buffer_unmap (buffer, &info->map_info);
return FALSE;
}
info->planes = g_slice_alloc (info->n_planes * sizeof (gpointer));
for (i = 0; i < meta->channels; i++)
info->planes[i] = info->map_info.data + meta->offsets[i];
}
return ret;
}
void
gst_audio_buffer_unmap (GstBuffer * buffer, GstAudioMapInfo * info)
{
gst_buffer_unmap (buffer, &info->map_info);
g_slice_free1 (info->n_planes * sizeof (gpointer), info->planes);
memset (info, 0, sizeof (GstAudioMapInfo));
}
GType
gst_audio_meta_api_get_type (void)
{
static volatile GType type;
static const gchar *tags[] = {
GST_META_TAG_AUDIO_STR, GST_META_TAG_AUDIO_CHANNELS_STR,
GST_META_TAG_AUDIO_RATE_STR, NULL
};
if (g_once_init_enter (&type)) {
GType _type = gst_meta_api_type_register ("GstAudioMetaAPI", tags);
g_once_init_leave (&type, _type);
}
return type;
}
const GstMetaInfo *
gst_audio_meta_get_info (void)
{
static const GstMetaInfo *audio_meta_info = NULL;
if (g_once_init_enter ((GstMetaInfo **) & audio_meta_info)) {
const GstMetaInfo *meta = gst_meta_register (GST_AUDIO_META_API_TYPE,
"GstAudioMeta", sizeof (GstAudioMeta),
gst_audio_meta_init,
gst_audio_meta_free,
gst_audio_meta_transform);
g_once_init_leave ((GstMetaInfo **) & audio_meta_info,
(GstMetaInfo *) meta);
}
return audio_meta_info;
}
......@@ -125,6 +125,60 @@ GstAudioClippingMeta * gst_buffer_add_audio_clipping_meta (GstBuffer *buffer,
guint64 start,
guint64 end);
#define GST_AUDIO_META_API_TYPE (gst_audio_meta_api_get_type())
#define GST_AUDIO_META_INFO (gst_audio_meta_get_info())
typedef struct _GstAudioMeta GstAudioMeta;
typedef struct {
gint n_planes;
gsize plane_size;
gpointer *planes;
GstMapInfo map_info;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
} GstAudioMapInfo;
struct _GstAudioMeta {
GstMeta meta;
GstAudioFormat format;
GstAudioLayout layout;
gint channels;
gint samples;
gsize *offsets;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
GST_EXPORT
GType gst_audio_meta_api_get_type (void);
GST_EXPORT
const GstMetaInfo * gst_audio_meta_get_info (void);
#define gst_buffer_get_audio_meta(b) \
((GstAudioMeta*)gst_buffer_get_meta((b), GST_AUDIO_META_API_TYPE))
GST_EXPORT
GstAudioMeta * gst_buffer_add_audio_meta (GstBuffer *buffer,
GstAudioFormat format,
GstAudioLayout layout,
gint channels, gint samples,
gsize offsets[]);
GST_EXPORT
gboolean gst_audio_buffer_map (GstBuffer *buffer, GstAudioMapInfo *info,
GstMapFlags flags);
GST_EXPORT
void gst_audio_buffer_unmap (GstBuffer *buffer, GstAudioMapInfo *info);
G_END_DECLS
#endif /* __GST_AUDIO_META_H__ */
......@@ -267,8 +267,6 @@ gst_audio_convert_dispose (GObject * obj)
gst_audio_converter_free (this->convert);
this->convert = NULL;
}
g_clear_pointer (&this->in, g_free);
g_clear_pointer (&this->out, g_free);
g_value_unset (&this->mix_matrix);
......@@ -776,19 +774,6 @@ gst_audio_convert_set_caps (GstBaseTransform * base, GstCaps * incaps,
this->in_info = in_info;
this->out_info = out_info;
/* allocate arrays to hold channel pointers */
g_free (this->in);
if (in_info.layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED)
this->in = g_malloc0 (in_info.channels * sizeof (gpointer));
else
this->in = g_malloc0 (sizeof (gpointer));
g_free (this->out);
if (out_info.layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED)
this->out = g_malloc0 (out_info.channels * sizeof (gpointer));
else
this->out = g_malloc0 (sizeof (gpointer));
return TRUE;
/* ERRORS */
......@@ -816,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 */
......@@ -835,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 */
......@@ -864,41 +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)) {
gint i;
/* TODO use GstAudioMeta */
if (inbuf != outbuf) {
this->in[0] = srcmap.data;
if (this->in_info.layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
for (i = 1; i < this->in_info.channels; i++) {
this->in[i] =
srcmap.data + i * samples * this->in_info.finfo->width / 8;
}
}
}
this->out[0] = dstmap.data;
if (this->out_info.layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
for (i = 1; i < this->out_info.channels; i++) {
this->out[i] =
dstmap.data + i * samples * this->out_info.finfo->width / 8;
}
}
if (!gst_audio_converter_samples (this->convert, flags,
inbuf != outbuf ? this->in : this->out, samples,
this->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;
......@@ -909,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;
}
......@@ -931,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;
}
}
......
......@@ -53,7 +53,6 @@ struct _GstAudioConvert
GstAudioInfo in_info;
GstAudioInfo out_info;
GstAudioConverter *convert;
gpointer *in, *out;
};
struct _GstAudioConvertClass
......
......@@ -548,8 +548,7 @@ gst_audio_resample_push_drain (GstAudioResample * resample, guint history_len)
GstFlowReturn res;
gint outsize;
gsize out_len;
GstMapInfo map;
gpointer out[1];
GstAudioMapInfo map;
g_assert (resample->converter != NULL);
......@@ -565,13 +564,15 @@ gst_audio_resample_push_drain (GstAudioResample * resample, guint history_len)
outsize = out_len * resample->in.bpf;
outbuf = gst_buffer_new_and_alloc (outsize);
gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
gst_buffer_add_audio_meta (outbuf, resample->out.finfo->format,
resample->out.layout, resample->out.channels, out_len, NULL);
gst_audio_buffer_map (outbuf, &map, GST_MAP_WRITE);
out[0] = map.data;
gst_audio_converter_samples (resample->converter, 0, NULL, history_len,
out, out_len);
map.planes, out_len);
gst_buffer_unmap (outbuf, &map);
gst_audio_buffer_unmap (outbuf, &map);
/* time */
if (GST_CLOCK_TIME_IS_VALID (resample->t0)) {
......@@ -703,7 +704,7 @@ static GstFlowReturn
gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
GstBuffer * outbuf)
{
GstMapInfo in_map, out_map;
GstAudioMapInfo in_map, out_map;
gsize outsize;
guint32 in_len;
guint32 out_len;
......@@ -711,16 +712,19 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
gst_audio_converter_get_max_latency (resample->converter) * 2;
gboolean inbuf_writable;
in_len = gst_buffer_get_size (inbuf) / resample->in.bpf;
out_len = gst_buffer_get_size (outbuf) / resample->out.bpf;
inbuf_writable = gst_buffer_is_writable (inbuf)
&& gst_buffer_n_memory (inbuf) == 1
&& gst_memory_is_writable (gst_buffer_peek_memory (inbuf, 0));
gst_buffer_map (inbuf, &in_map,
inbuf_writable ? GST_MAP_READWRITE : GST_MAP_READ);
gst_buffer_map (outbuf, &out_map, GST_MAP_WRITE);
gst_buffer_add_audio_meta (outbuf, resample->out.finfo->format,
resample->out.layout, resample->out.channels, out_len, NULL);
in_len = in_map.size / resample->in.bpf;
out_len = out_map.size / resample->out.bpf;
gst_audio_buffer_map (inbuf, &in_map,
inbuf_writable ? GST_MAP_READWRITE : GST_MAP_READ);
gst_audio_buffer_map (outbuf, &out_map, GST_MAP_WRITE);
if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) {
resample->num_nongap_samples = 0;
......@@ -749,7 +753,7 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
else
out_len = 0;
memset (out_map.data, 0, out_map.size);
memset (out_map.map_info.data, 0, out_map.map_info.size);
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
resample->num_gap_samples += in_len;
}
......@@ -771,17 +775,14 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
}
{
/* process */
gpointer in[1], out[1];
GstAudioConverterFlags flags;
flags = 0;
if (inbuf_writable)
flags |= GST_AUDIO_CONVERTER_FLAG_IN_WRITABLE;
in[0] = in_map.data;
out[0] = out_map.data;
gst_audio_converter_samples (resample->converter, flags, in, in_len,
out, out_len);
gst_audio_converter_samples (resample->converter, flags, in_map.planes,
in_len, out_map.planes, out_len);
}
}
......@@ -809,8 +810,8 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
resample->samples_out += out_len;
resample->samples_in += in_len;
gst_buffer_unmap (inbuf, &in_map);
gst_buffer_unmap (outbuf, &out_map);
gst_audio_buffer_unmap (inbuf, &in_map);
gst_audio_buffer_unmap (outbuf, &out_map);
outsize = out_len * resample->in.bpf;
......
......@@ -1437,6 +1437,10 @@ gst_audio_test_src_fill (GstBaseSrc * basesrc, guint64 offset,
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_GAP);
}
gst_buffer_add_audio_meta (buffer, src->info.finfo->format,
src->info.layout, src->info.channels, src->generate_samples_per_buffer,
NULL);
return GST_FLOW_OK;
}
......
......@@ -53,6 +53,108 @@ setup_segment (GstSegment * s, GstFormat fmt, guint64 start, guint64 stop,
s->time = stream_time;
}
GST_START_TEST (test_audio_meta_offsets)
{
GstBuffer *buf;
guint8 *data;
GstAudioMeta *meta;
GstAudioMapInfo map;
gsize offsets[4] = { 10, 760, 510, 260 };
buf = make_buffer (&data);
meta = gst_buffer_add_audio_meta (buf, GST_AUDIO_FORMAT_S24_32,
GST_AUDIO_LAYOUT_NON_INTERLEAVED, 4, 60, offsets);
fail_unless_equals_int (meta->format, GST_AUDIO_FORMAT_S24_32);
fail_unless_equals_int (meta->layout, GST_AUDIO_LAYOUT_NON_INTERLEAVED);
fail_unless_equals_int (meta->channels, 4);
fail_unless_equals_int (meta->samples, 60);
fail_unless (meta->offsets);
fail_unless_equals_int (meta->offsets[0], 10);
fail_unless_equals_int (meta->offsets[1], 760);
fail_unless_equals_int (meta->offsets[2], 510);
fail_unless_equals_int (meta->offsets[3], 260);
gst_audio_buffer_map (buf, &map, GST_MAP_READ);
fail_unless_equals_int (map.n_planes, 4);
fail_unless_equals_int (map.plane_size, 240);
fail_unless_equals_pointer (map.planes[0], data + 10);
fail_unless_equals_pointer (map.planes[1], data + 760);
fail_unless_equals_pointer (map.planes[2], data + 510);
fail_unless_equals_pointer (map.planes[3], data + 260);
gst_audio_buffer_unmap (buf, &map);
fail_unless_equals_int (map.n_planes, 0);
fail_unless_equals_int (map.plane_size, 0);
fail_unless_equals_pointer (map.planes, NULL);
}
GST_END_TEST;
GST_START_TEST (test_audio_meta_no_offsets)
{
GstBuffer *buf;
guint8 *data;
GstAudioMeta *meta;
GstAudioMapInfo map;
buf = make_buffer (&data);
meta = gst_buffer_add_audio_meta (buf, GST_AUDIO_FORMAT_F32,
GST_AUDIO_LAYOUT_NON_INTERLEAVED, 4, 60, NULL);
fail_unless_equals_int (meta->format, GST_AUDIO_FORMAT_F32);
fail_unless_equals_int (meta->layout, GST_AUDIO_LAYOUT_NON_INTERLEAVED);
fail_unless_equals_int (meta->channels, 4);
fail_unless_equals_int (meta->samples, 60);
fail_unless (meta->offsets);
fail_unless_equals_int (meta->offsets[0], 0);
fail_unless_equals_int (meta->offsets[1], 240);
fail_unless_equals_int (meta->offsets[2], 480);
fail_unless_equals_int (meta->offsets[3], 720);
gst_audio_buffer_map (buf, &map, GST_MAP_READ);
fail_unless_equals_int (map.n_planes, 4);
fail_unless_equals_int (map.plane_size, 240);
fail_unless_equals_pointer (map.planes[0], data);
fail_unless_equals_pointer (map.planes[1], data + 240);
fail_unless_equals_pointer (map.planes[2], data + 480);
fail_unless_equals_pointer (map.planes[3], data + 720);
gst_audio_buffer_unmap (buf, &map);
fail_unless_equals_int (map.n_planes, 0);
fail_unless_equals_int (map.plane_size, 0);
fail_unless_equals_pointer (map.planes, NULL);
}
GST_END_TEST;
GST_START_TEST (test_audio_meta_interleaved)
{
GstBuffer *buf;
guint8 *data;
GstAudioMeta *meta;
GstAudioMapInfo map;
buf = make_buffer (&data);
meta = gst_buffer_add_audio_meta (buf, GST_AUDIO_FORMAT_S16,
GST_AUDIO_LAYOUT_INTERLEAVED, 4, 125, NULL);
fail_unless_equals_int (meta->format, GST_AUDIO_FORMAT_S16);
fail_unless_equals_int (meta->layout, GST_AUDIO_LAYOUT_INTERLEAVED);
fail_unless_equals_int (meta->channels, 4);
fail_unless_equals_int (meta->samples, 125);
fail_if (meta->offsets);
gst_audio_buffer_map (buf, &map, GST_MAP_READ);
fail_unless_equals_int (map.n_planes, 1);
fail_unless_equals_int (map.plane_size, 1000);
fail_unless_equals_pointer (map.planes[0], data);
gst_audio_buffer_unmap (buf, &map);
fail_unless_equals_int (map.n_planes, 0);
fail_unless_equals_int (map.plane_size, 0);
fail_unless_equals_pointer (map.planes, NULL);
}
GST_END_TEST;
GST_START_TEST (test_buffer_clip_unsupported_format)
{
GstSegment s;
......@@ -1073,6 +1175,9 @@ audio_suite (void)
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_audio_meta_offsets);
tcase_add_test (tc_chain, test_audio_meta_no_offsets);
tcase_add_test (tc_chain, test_audio_meta_interleaved);
tcase_add_test (tc_chain, test_buffer_clip_unsupported_format);
tcase_add_test (tc_chain, test_buffer_clip_time_start_and_stop);
tcase_add_test (tc_chain, test_buffer_clip_time_start);
......