mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 21:21:12 +00:00
06d9d934f9
This allows metas to be serialized to be transmitted or stored. This is intended to be used for example by gdppay or unixfdsink. Implemented on GstCustomMeta, GstVideoMeta, GstReferenceTimestampMeta, and GstAudioMeta. Sponsored-by: Netflix Inc. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5355>
1725 lines
53 KiB
C
1725 lines
53 KiB
C
/* GStreamer
|
|
*
|
|
* unit tests for audio support library
|
|
*
|
|
* Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
|
|
* Copyright (C) 2011 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <gst/check/gstcheck.h>
|
|
|
|
#include <gst/audio/audio.h>
|
|
#include <string.h>
|
|
|
|
static GstBuffer *
|
|
make_buffer (guint8 ** _data)
|
|
{
|
|
GstBuffer *buf = gst_buffer_new ();
|
|
guint8 *data = (guint8 *) g_malloc (1000);
|
|
|
|
gst_buffer_append_memory (buf,
|
|
gst_memory_new_wrapped (0, data, 1000, 0, 1000, data, g_free));
|
|
if (_data)
|
|
*_data = data;
|
|
return buf;
|
|
}
|
|
|
|
static void
|
|
setup_segment (GstSegment * s, GstFormat fmt, guint64 start, guint64 stop,
|
|
guint64 stream_time)
|
|
{
|
|
gst_segment_init (s, fmt);
|
|
s->start = start;
|
|
s->stop = stop;
|
|
s->time = stream_time;
|
|
}
|
|
|
|
GST_START_TEST (test_buffer_clip_unsupported_format)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
guint8 *data;
|
|
|
|
/* If the format is not TIME or DEFAULT it should assert()
|
|
* FIXME: check if return value is the same as the input buffer.
|
|
* probably can't be done because the assert() does a SIGABRT.
|
|
*/
|
|
buf = make_buffer (&data);
|
|
setup_segment (&s, GST_FORMAT_PERCENT, 0, 10, 0);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 0 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 0;
|
|
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
|
|
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
|
|
|
|
ASSERT_CRITICAL (gst_audio_buffer_clip (buf, &s, 100, 1));
|
|
|
|
gst_buffer_unref (buf);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_time_start_and_stop)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstMapInfo map;
|
|
guint8 *data;
|
|
|
|
/* Clip start and end */
|
|
buf = make_buffer (&data);
|
|
setup_segment (&s, GST_FORMAT_TIME, 4 * GST_SECOND, 8 * GST_SECOND,
|
|
4 * GST_SECOND);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 800);
|
|
gst_buffer_map (ret, &map, GST_MAP_READ);
|
|
fail_unless (map.data == data + 200);
|
|
fail_unless (map.size == 400);
|
|
gst_buffer_unmap (ret, &map);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_time_start_and_stop_planar)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstAudioInfo info;
|
|
GstAudioBuffer abuf;
|
|
guint8 *data;
|
|
|
|
/* Clip start and end */
|
|
buf = make_buffer (&data);
|
|
|
|
gst_audio_info_init (&info);
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S8, 44100, 1, NULL);
|
|
info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
|
|
gst_buffer_add_audio_meta (buf, &info, 1000, NULL);
|
|
|
|
setup_segment (&s, GST_FORMAT_TIME, 4 * GST_SECOND, 8 * GST_SECOND,
|
|
4 * GST_SECOND);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 800);
|
|
gst_audio_buffer_map (&abuf, &info, ret, GST_MAP_READ);
|
|
fail_unless_equals_int (abuf.n_planes, 1);
|
|
fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&abuf), 400);
|
|
fail_unless_equals_pointer (abuf.planes[0], data + 200);
|
|
gst_audio_buffer_unmap (&abuf);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_time_start)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstMapInfo map;
|
|
guint8 *data;
|
|
|
|
/* Clip only start */
|
|
buf = make_buffer (&data);
|
|
setup_segment (&s, GST_FORMAT_TIME, 4 * GST_SECOND, 12 * GST_SECOND,
|
|
4 * GST_SECOND);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 8 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 1200);
|
|
gst_buffer_map (ret, &map, GST_MAP_READ);
|
|
fail_unless (map.data == data + 200);
|
|
fail_unless (map.size == 800);
|
|
gst_buffer_unmap (ret, &map);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_time_start_planar)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstAudioInfo info;
|
|
GstAudioMeta *meta;
|
|
GstAudioBuffer abuf;
|
|
guint8 *data;
|
|
|
|
/* Clip only start */
|
|
buf = make_buffer (&data);
|
|
|
|
gst_audio_info_init (&info);
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S8, 44100, 2, NULL);
|
|
info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
|
|
gst_buffer_add_audio_meta (buf, &info, 500, NULL);
|
|
|
|
setup_segment (&s, GST_FORMAT_TIME, 4 * GST_SECOND, 12 * GST_SECOND,
|
|
4 * GST_SECOND);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 5 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 700;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 2);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 3 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 700);
|
|
|
|
meta = gst_buffer_get_audio_meta (ret);
|
|
fail_unless (meta);
|
|
fail_unless_equals_int (meta->info.channels, 2);
|
|
fail_unless_equals_int (meta->samples, 300);
|
|
|
|
gst_audio_buffer_map (&abuf, &info, ret, GST_MAP_READ);
|
|
fail_unless_equals_int (abuf.n_planes, 2);
|
|
fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&abuf), 300);
|
|
fail_unless_equals_pointer (abuf.planes[0], data + 200);
|
|
fail_unless_equals_pointer (abuf.planes[1], data + 700);
|
|
gst_audio_buffer_unmap (&abuf);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_time_stop)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstMapInfo map;
|
|
guint8 *data;
|
|
|
|
/* Clip only stop */
|
|
buf = make_buffer (&data);
|
|
setup_segment (&s, GST_FORMAT_TIME, 2 * GST_SECOND, 10 * GST_SECOND,
|
|
2 * GST_SECOND);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 2 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 8 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 200);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 1000);
|
|
gst_buffer_map (ret, &map, GST_MAP_READ);
|
|
fail_unless (map.data == data);
|
|
fail_unless (map.size == 800);
|
|
gst_buffer_unmap (ret, &map);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_time_stop_planar)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstAudioInfo info;
|
|
GstAudioMeta *meta;
|
|
GstAudioBuffer abuf;
|
|
guint8 *data;
|
|
|
|
/* Clip only stop */
|
|
buf = make_buffer (&data);
|
|
|
|
gst_audio_info_init (&info);
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S8, 44100, 2, NULL);
|
|
info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
|
|
gst_buffer_add_audio_meta (buf, &info, 500, NULL);
|
|
|
|
setup_segment (&s, GST_FORMAT_TIME, 2 * GST_SECOND, 6 * GST_SECOND,
|
|
2 * GST_SECOND);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 5 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 700;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 2);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 2 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 200);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 600);
|
|
|
|
meta = gst_buffer_get_audio_meta (ret);
|
|
fail_unless (meta);
|
|
fail_unless_equals_int (meta->info.channels, 2);
|
|
fail_unless_equals_int (meta->samples, 400);
|
|
|
|
gst_audio_buffer_map (&abuf, &info, ret, GST_MAP_READ);
|
|
fail_unless_equals_int (abuf.n_planes, 2);
|
|
fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&abuf), 400);
|
|
fail_unless_equals_pointer (abuf.planes[0], data);
|
|
fail_unless_equals_pointer (abuf.planes[1], data + 500);
|
|
gst_audio_buffer_unmap (&abuf);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_time_outside)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
|
|
/* Buffer outside segment */
|
|
buf = make_buffer (NULL);
|
|
setup_segment (&s, GST_FORMAT_TIME, 12 * GST_SECOND, 20 * GST_SECOND,
|
|
12 * GST_SECOND);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret == NULL);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_time_start_and_stop_no_meta)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstMapInfo map;
|
|
guint8 *data;
|
|
|
|
/* Clip start and end but don't touch duration, offset and offset_end */
|
|
buf = make_buffer (&data);
|
|
setup_segment (&s, GST_FORMAT_TIME, 4 * GST_SECOND, 8 * GST_SECOND,
|
|
4 * GST_SECOND);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
|
|
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
|
|
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), GST_CLOCK_TIME_NONE);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), GST_BUFFER_OFFSET_NONE);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret),
|
|
GST_BUFFER_OFFSET_NONE);
|
|
gst_buffer_map (ret, &map, GST_MAP_READ);
|
|
fail_unless (map.data == data + 200);
|
|
fail_unless (map.size == 400);
|
|
gst_buffer_unmap (ret, &map);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_time_no_timestamp)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
|
|
/* If the buffer has no timestamp it should assert()
|
|
* FIXME: check if return value is the same as the input buffer.
|
|
* probably can't be done because the assert() does a SIGABRT.
|
|
*/
|
|
buf = make_buffer (NULL);
|
|
setup_segment (&s, GST_FORMAT_TIME, 0 * GST_SECOND, 10 * GST_SECOND,
|
|
0 * GST_SECOND);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
|
|
GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
|
|
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
|
|
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret == buf);
|
|
|
|
gst_buffer_unref (buf);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_time_handles_rounding)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstMapInfo map;
|
|
guint8 *data;
|
|
GstClockTime time_per_sample = GST_SECOND / 100;
|
|
|
|
/* Clip only stop */
|
|
buf = make_buffer (&data);
|
|
setup_segment (&s, GST_FORMAT_TIME, 2 * GST_SECOND, 10 * GST_SECOND,
|
|
2 * GST_SECOND);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
/* the max duration that still converts back to the same size of samples */
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND + (time_per_sample - 1);
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 2 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 8 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 200);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 1000);
|
|
gst_buffer_map (ret, &map, GST_MAP_READ);
|
|
fail_unless (map.data == data);
|
|
fail_unless (map.size == 800);
|
|
gst_buffer_unmap (ret, &map);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_samples_start_and_stop)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstMapInfo map;
|
|
guint8 *data;
|
|
|
|
/* Clip start and end */
|
|
buf = make_buffer (&data);
|
|
setup_segment (&s, GST_FORMAT_DEFAULT, 400, 800, 400);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 800);
|
|
gst_buffer_map (ret, &map, GST_MAP_READ);
|
|
fail_unless (map.data == data + 200);
|
|
fail_unless (map.size == 400);
|
|
gst_buffer_unmap (ret, &map);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_samples_start_and_stop_planar)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstAudioInfo info;
|
|
GstAudioMeta *meta;
|
|
GstAudioBuffer abuf;
|
|
guint8 *data;
|
|
|
|
/* Clip start and end */
|
|
buf = make_buffer (&data);
|
|
|
|
gst_audio_info_init (&info);
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S8, 44100, 2, NULL);
|
|
info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
|
|
gst_buffer_add_audio_meta (buf, &info, 500, NULL);
|
|
|
|
|
|
setup_segment (&s, GST_FORMAT_DEFAULT, 400, 600, 400);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 5 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 700;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 2);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 2 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 600);
|
|
|
|
meta = gst_buffer_get_audio_meta (ret);
|
|
fail_unless (meta);
|
|
fail_unless_equals_int (meta->info.channels, 2);
|
|
fail_unless_equals_int (meta->samples, 200);
|
|
|
|
gst_audio_buffer_map (&abuf, &info, ret, GST_MAP_READ);
|
|
fail_unless_equals_int (abuf.n_planes, 2);
|
|
fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&abuf), 200);
|
|
fail_unless_equals_pointer (abuf.planes[0], data + 200);
|
|
fail_unless_equals_pointer (abuf.planes[1], data + 700);
|
|
gst_audio_buffer_unmap (&abuf);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_samples_start)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstMapInfo map;
|
|
guint8 *data;
|
|
|
|
/* Clip only start */
|
|
buf = make_buffer (&data);
|
|
setup_segment (&s, GST_FORMAT_DEFAULT, 400, 1200, 400);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 8 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 1200);
|
|
gst_buffer_map (ret, &map, GST_MAP_READ);
|
|
fail_unless (map.data == data + 200);
|
|
fail_unless (map.size == 800);
|
|
gst_buffer_unmap (ret, &map);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_samples_stop)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstMapInfo map;
|
|
guint8 *data;
|
|
|
|
/* Clip only stop */
|
|
buf = make_buffer (&data);
|
|
setup_segment (&s, GST_FORMAT_DEFAULT, 200, 1000, 200);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 2 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 8 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 200);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 1000);
|
|
gst_buffer_map (ret, &map, GST_MAP_READ);
|
|
fail_unless (map.data == data);
|
|
fail_unless (map.size == 800);
|
|
gst_buffer_unmap (ret, &map);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_samples_outside)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
|
|
/* Buffer outside segment */
|
|
buf = make_buffer (NULL);
|
|
setup_segment (&s, GST_FORMAT_DEFAULT, 1200, 2000, 1200);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret == NULL);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_samples_start_and_stop_no_meta)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
GstMapInfo map;
|
|
guint8 *data;
|
|
|
|
/* Clip start and end but don't touch duration and offset_end */
|
|
buf = make_buffer (&data);
|
|
setup_segment (&s, GST_FORMAT_DEFAULT, 400, 800, 400);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
|
|
|
|
ret = gst_audio_buffer_clip (buf, &s, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), GST_CLOCK_TIME_NONE);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 800);
|
|
gst_buffer_map (ret, &map, GST_MAP_READ);
|
|
fail_unless (map.data == data + 200);
|
|
fail_unless (map.size == 400);
|
|
gst_buffer_unmap (ret, &map);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_clip_samples_no_timestamp)
|
|
{
|
|
GstSegment s;
|
|
GstBuffer *buf;
|
|
|
|
/* If the buffer has no offset it should assert() in DEFAULT format
|
|
* FIXME: check if return value is the same as the input buffer.
|
|
* probably can't be done because the assert() does a SIGABRT.
|
|
*/
|
|
buf = make_buffer (NULL);
|
|
setup_segment (&s, GST_FORMAT_DEFAULT, 0, 10, 0);
|
|
|
|
GST_BUFFER_TIMESTAMP (buf) = 0 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
|
|
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
|
|
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
|
|
|
|
ASSERT_CRITICAL (gst_audio_buffer_clip (buf, &s, 100, 1));
|
|
|
|
gst_buffer_unref (buf);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_truncate_samples_offset_end)
|
|
{
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
guint8 *data;
|
|
|
|
buf = make_buffer (&data);
|
|
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
|
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
|
GST_BUFFER_OFFSET (buf) = 200;
|
|
GST_BUFFER_OFFSET_END (buf) = 1200;
|
|
|
|
ret = gst_audio_buffer_truncate (buf, 4, 100, 100);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), GST_CLOCK_TIME_NONE);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), GST_CLOCK_TIME_NONE);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 300);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 400);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_buffer_truncate_samples_no_timestamp)
|
|
{
|
|
GstBuffer *buf;
|
|
GstBuffer *ret;
|
|
guint8 *data;
|
|
|
|
buf = make_buffer (&data);
|
|
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
|
|
GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
|
|
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
|
|
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
|
|
|
|
ret = gst_audio_buffer_truncate (buf, 4, 100, 1);
|
|
fail_unless (ret != NULL);
|
|
|
|
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), GST_CLOCK_TIME_NONE);
|
|
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), GST_CLOCK_TIME_NONE);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), GST_BUFFER_OFFSET_NONE);
|
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret),
|
|
GST_BUFFER_OFFSET_NONE);
|
|
|
|
gst_buffer_unref (ret);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_multichannel_checks)
|
|
{
|
|
GstAudioChannelPosition pos_2_mixed[2] = {
|
|
GST_AUDIO_CHANNEL_POSITION_MONO,
|
|
GST_AUDIO_CHANNEL_POSITION_NONE
|
|
};
|
|
GstAudioChannelPosition pos_2_none[2] = {
|
|
GST_AUDIO_CHANNEL_POSITION_NONE,
|
|
GST_AUDIO_CHANNEL_POSITION_NONE
|
|
};
|
|
GstAudioChannelPosition pos_2_flr[2] = {
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
|
|
};
|
|
GstAudioChannelPosition pos_2_frl[2] = {
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT
|
|
};
|
|
GstAudioChannelPosition pos_2_frr[2] = {
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
|
|
};
|
|
GstAudioChannelPosition pos_3_flrc[3] = {
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER
|
|
};
|
|
GstAudioChannelPosition pos_3_frcl[3] = {
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT
|
|
};
|
|
GstAudioInfo info, info2;
|
|
GstCaps *caps;
|
|
|
|
gst_audio_info_init (&info);
|
|
gst_audio_info_init (&info2);
|
|
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000, 2, NULL);
|
|
fail_unless (memcmp (&info.position, pos_2_flr, sizeof (pos_2_flr)) == 0);
|
|
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000, 2, pos_2_flr);
|
|
fail_unless (memcmp (&info.position, pos_2_flr, sizeof (pos_2_flr)) == 0);
|
|
caps = gst_audio_info_to_caps (&info);
|
|
fail_unless (gst_audio_info_from_caps (&info2, caps));
|
|
fail_unless (memcmp (&info, &info2, sizeof (info)) == 0);
|
|
gst_caps_unref (caps);
|
|
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000, 2, pos_2_none);
|
|
fail_unless (memcmp (&info.position, pos_2_none, sizeof (pos_2_none)) == 0);
|
|
caps = gst_audio_info_to_caps (&info);
|
|
fail_unless (gst_audio_info_from_caps (&info2, caps));
|
|
fail_unless (memcmp (&info, &info2, sizeof (info)) == 0);
|
|
gst_caps_unref (caps);
|
|
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000, 3, pos_3_flrc);
|
|
fail_unless (memcmp (&info.position, pos_3_flrc, sizeof (pos_3_flrc)) == 0);
|
|
caps = gst_audio_info_to_caps (&info);
|
|
fail_unless (gst_audio_info_from_caps (&info2, caps));
|
|
fail_unless (memcmp (&info, &info2, sizeof (info)) == 0);
|
|
gst_caps_unref (caps);
|
|
|
|
ASSERT_WARNING (gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000,
|
|
2, pos_2_frl));
|
|
ASSERT_WARNING (gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000,
|
|
2, pos_2_mixed));
|
|
ASSERT_WARNING (gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000,
|
|
2, pos_2_frr));
|
|
ASSERT_WARNING (gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000,
|
|
3, pos_3_frcl));
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
typedef struct
|
|
{
|
|
gint channels;
|
|
GstAudioChannelPosition from[32], to[32];
|
|
gint32 in[32], out[32];
|
|
gint32 plane_offsets[32];
|
|
gboolean fail;
|
|
} MultichannelReorderData;
|
|
|
|
GST_START_TEST (test_multichannel_reorder)
|
|
{
|
|
MultichannelReorderData tests[] = {
|
|
{1,
|
|
{GST_AUDIO_CHANNEL_POSITION_MONO},
|
|
{GST_AUDIO_CHANNEL_POSITION_MONO},
|
|
{0, 1, 2, 3},
|
|
{0, 1, 2, 3},
|
|
{0},
|
|
FALSE},
|
|
{1,
|
|
{GST_AUDIO_CHANNEL_POSITION_MONO},
|
|
{GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER},
|
|
{0, 1, 2, 3},
|
|
{0, 1, 2, 3},
|
|
{0},
|
|
TRUE},
|
|
{2,
|
|
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
|
|
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
|
|
{0, 1, 2, 3},
|
|
{0, 1, 2, 3},
|
|
{0, 1},
|
|
FALSE},
|
|
{2,
|
|
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
|
|
{GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT},
|
|
{0, 1, 2, 3},
|
|
{1, 0, 3, 2},
|
|
{1, 0},
|
|
FALSE},
|
|
{4,
|
|
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
|
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
|
|
{GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
|
|
{0, 1, 2, 3},
|
|
{1, 2, 0, 3},
|
|
{1, 2, 0, 3},
|
|
FALSE},
|
|
{4,
|
|
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
|
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
|
|
{GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER},
|
|
{0, 1, 2, 3},
|
|
{3, 0, 1, 2},
|
|
{3, 0, 1, 2},
|
|
FALSE},
|
|
{4,
|
|
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
|
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
|
|
{GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT},
|
|
{0, 1, 2, 3},
|
|
{3, 2, 1, 0},
|
|
{3, 2, 1, 0},
|
|
FALSE},
|
|
};
|
|
gint i, j;
|
|
GstBuffer *buf;
|
|
GstMapInfo map;
|
|
GstAudioInfo info;
|
|
GstAudioBuffer abuf;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (tests); i++) {
|
|
buf =
|
|
gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, tests[i].in,
|
|
sizeof (tests[i].in), 0, sizeof (tests[i].in), NULL, NULL);
|
|
|
|
if (tests[i].fail) {
|
|
fail_if (gst_audio_buffer_reorder_channels (buf, GST_AUDIO_FORMAT_S32,
|
|
tests[i].channels, tests[i].from, tests[i].to));
|
|
} else {
|
|
/* first interpret as interleaved */
|
|
|
|
fail_unless (gst_audio_buffer_reorder_channels (buf, GST_AUDIO_FORMAT_S32,
|
|
tests[i].channels, tests[i].from, tests[i].to));
|
|
|
|
gst_buffer_map (buf, &map, GST_MAP_READ);
|
|
fail_unless_equals_int (map.size, sizeof (tests[i].in));
|
|
fail_unless (memcmp (tests[i].out, map.data, map.size) == 0);
|
|
gst_buffer_unmap (buf, &map);
|
|
|
|
/* now interpret as planar */
|
|
|
|
gst_audio_info_init (&info);
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S32, 44100,
|
|
tests[i].channels, NULL);
|
|
info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
|
|
|
|
gst_buffer_add_audio_meta (buf, &info,
|
|
sizeof (tests[i].in) / (tests[i].channels * sizeof (gint32)), NULL);
|
|
|
|
fail_unless (gst_audio_buffer_reorder_channels (buf, GST_AUDIO_FORMAT_S32,
|
|
tests[i].channels, tests[i].from, tests[i].to));
|
|
|
|
fail_unless (gst_audio_buffer_map (&abuf, &info, buf, GST_MAP_READ));
|
|
fail_unless_equals_int (abuf.n_planes, tests[i].channels);
|
|
fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&abuf),
|
|
sizeof (tests[i].in) / tests[i].channels);
|
|
for (j = 0; j < abuf.n_planes; j++) {
|
|
fail_unless_equals_pointer (abuf.planes[j],
|
|
abuf.map_infos[0].data +
|
|
tests[i].plane_offsets[j] * GST_AUDIO_BUFFER_PLANE_SIZE (&abuf));
|
|
}
|
|
gst_audio_buffer_unmap (&abuf);
|
|
}
|
|
gst_buffer_unref (buf);
|
|
}
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_audio_format_s8)
|
|
{
|
|
GstAudioFormat fmt;
|
|
|
|
fmt = gst_audio_format_build_integer (TRUE, G_BYTE_ORDER, 8, 8);
|
|
fail_unless (fmt == GST_AUDIO_FORMAT_S8);
|
|
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_audio_format_u8)
|
|
{
|
|
GstAudioFormat fmt;
|
|
fmt = gst_audio_format_build_integer (FALSE, G_BYTE_ORDER, 8, 8);
|
|
fail_unless (fmt == GST_AUDIO_FORMAT_U8);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_fill_silence)
|
|
{
|
|
GstAudioInfo info;
|
|
GstAudioFormat f;
|
|
gint i;
|
|
guint8 test_silence[32];
|
|
|
|
for (f = GST_AUDIO_FORMAT_S8; f < GST_AUDIO_FORMAT_F64; f++) {
|
|
gst_audio_info_set_format (&info, f, 48000, 1, NULL);
|
|
|
|
gst_audio_format_info_fill_silence (info.finfo, test_silence,
|
|
GST_AUDIO_INFO_BPF (&info) * 4);
|
|
|
|
for (i = 0; i < 4; i++)
|
|
fail_unless (memcmp (test_silence + i * GST_AUDIO_INFO_BPF (&info),
|
|
info.finfo->silence, GST_AUDIO_INFO_BPF (&info)) == 0);
|
|
}
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_stream_align)
|
|
{
|
|
GstAudioStreamAlign *align;
|
|
guint i;
|
|
GstClockTime timestamp;
|
|
GstClockTime out_timestamp, out_duration;
|
|
gboolean discont;
|
|
|
|
align = gst_audio_stream_align_new (1000, 40 * GST_MSECOND, 1 * GST_SECOND);
|
|
|
|
for (i = 0; i < 500; i++) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 0;
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i == 0)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
|
|
/* Drift forwards by 1ms per 10ms buffer for the first 40 buffers.
|
|
* - after 40 buffers we're above alignment threshold
|
|
* - after 40 + 96 buffers we're at discont wait
|
|
*/
|
|
for (i = 0; i < 500; i++) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 0;
|
|
if (i > 0)
|
|
timestamp += 1 * GST_MSECOND * MIN (i, 40);
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i < 136) {
|
|
if (i == 0)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
} else {
|
|
if (i == 136)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp,
|
|
10 * GST_MSECOND * i + 40 * GST_MSECOND);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
}
|
|
|
|
/* Drift backwards by 1ms per 10ms buffer for the first 40 buffers.
|
|
* - after 40 buffers we're above alignment threshold
|
|
* - after 40 + 104 buffers we're at discont wait
|
|
*/
|
|
for (i = 0; i < 500; i++) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 0;
|
|
if (i > 0)
|
|
timestamp -= 1 * GST_MSECOND * MIN (i, 40);
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i < 144) {
|
|
if (i == 0)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
} else {
|
|
if (i == 144)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
|
|
fail_unless_equals_uint64 (out_timestamp,
|
|
10 * GST_MSECOND * i - 40 * GST_MSECOND);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
}
|
|
|
|
/* Shift all buffers but the first by 40ms
|
|
* - after 1 buffers we're above alignment threshold
|
|
* - after 97 buffers we're at discont wait
|
|
*/
|
|
for (i = 0; i < 500; i++) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 0;
|
|
if (i > 0)
|
|
timestamp += 40 * GST_MSECOND;
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i < 97) {
|
|
if (i == 0)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
} else {
|
|
if (i == 97)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp,
|
|
10 * GST_MSECOND * i + 40 * GST_MSECOND);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
}
|
|
|
|
/* Shift every second buffer by 40ms:
|
|
* - never discont!
|
|
*/
|
|
for (i = 0; i < 500; i++) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 0;
|
|
|
|
if (i % 2 == 0 && i > 0)
|
|
timestamp += 40 * GST_MSECOND;
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i == 0)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
|
|
/* Shift every buffer after 100 by 2s: discont at buffer 100
|
|
*/
|
|
for (i = 0; i < 500; i++) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 0;
|
|
if (i >= 100)
|
|
timestamp += 2 * GST_SECOND;
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i < 100) {
|
|
if (i == 0)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
} else {
|
|
if (i == 100)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp,
|
|
10 * GST_MSECOND * i + 2 * GST_SECOND);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
}
|
|
|
|
gst_audio_stream_align_free (align);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_stream_align_reverse)
|
|
{
|
|
GstAudioStreamAlign *align;
|
|
gint i;
|
|
GstClockTime timestamp;
|
|
GstClockTime out_timestamp, out_duration;
|
|
gboolean discont;
|
|
|
|
align = gst_audio_stream_align_new (-1000, 40 * GST_MSECOND, 1 * GST_SECOND);
|
|
|
|
for (i = 499; i >= 0; i--) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 499;
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i == 499)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
|
|
/* Drift forwards by 1ms per 10ms buffer for the first 40 buffers.
|
|
* - after 40 buffers we're above alignment threshold
|
|
* - after 40 + 100 buffers we're at discont wait
|
|
*/
|
|
for (i = 499; i >= 0; i--) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 499;
|
|
if (i < 499)
|
|
timestamp += 1 * GST_MSECOND * MIN (499 - i, 40);
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i >= 500 - 144) {
|
|
if (i == 499)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
} else {
|
|
if (i == 499 - 144)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp,
|
|
10 * GST_MSECOND * i + 40 * GST_MSECOND);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
}
|
|
|
|
/* Drift backwards by 1ms per 10ms buffer for the first 40 buffers.
|
|
* - after 40 buffers we're above alignment threshold
|
|
* - after 40 + 100 buffers we're at discont wait
|
|
*/
|
|
for (i = 499; i >= 4; i--) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 499;
|
|
if (i < 499)
|
|
timestamp -= 1 * GST_MSECOND * MIN (499 - i, 40);
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i >= 500 - 136) {
|
|
if (i == 499)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
} else {
|
|
if (i == 499 - 136)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
|
|
fail_unless_equals_uint64 (out_timestamp,
|
|
10 * GST_MSECOND * i - 40 * GST_MSECOND);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
}
|
|
|
|
/* Shift all buffers but the first by 40ms
|
|
* - after 1 buffers we're above alignment threshold
|
|
* - after 106 buffers we're at discont wait
|
|
*/
|
|
for (i = 499; i >= 0; i--) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 499;
|
|
if (i < 499)
|
|
timestamp += 40 * GST_MSECOND;
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i >= 500 - 105) {
|
|
if (i == 499)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
} else {
|
|
if (i == 499 - 105)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp,
|
|
10 * GST_MSECOND * i + 40 * GST_MSECOND);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
}
|
|
|
|
/* Shift every second buffer by 40ms:
|
|
* - never discont!
|
|
*/
|
|
for (i = 499; i >= 0; i--) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 499;
|
|
|
|
if (i % 2 == 0 && i < 499)
|
|
timestamp += 40 * GST_MSECOND;
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i == 499)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
|
|
/* Shift every buffer after 100 by 2s: discont at buffer 100
|
|
*/
|
|
for (i = 499; i >= 0; i--) {
|
|
timestamp = 10 * GST_MSECOND * i;
|
|
discont = i == 499;
|
|
if (i < 500 - 100)
|
|
timestamp += 2 * GST_SECOND;
|
|
|
|
discont =
|
|
gst_audio_stream_align_process (align, discont, timestamp, 10,
|
|
&out_timestamp, &out_duration, NULL);
|
|
|
|
if (i >= 500 - 100) {
|
|
if (i == 499)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
} else {
|
|
if (i == 499 - 100)
|
|
fail_unless (discont);
|
|
else
|
|
fail_unless (!discont);
|
|
fail_unless_equals_uint64 (out_timestamp,
|
|
10 * GST_MSECOND * i + 2 * GST_SECOND);
|
|
fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
|
|
}
|
|
}
|
|
|
|
gst_audio_stream_align_free (align);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
typedef struct
|
|
{
|
|
GstAudioFormat format;
|
|
GstAudioLayout layout;
|
|
gint channels;
|
|
gsize samples;
|
|
gsize plane_size;
|
|
gsize offsets[10];
|
|
gboolean add_meta;
|
|
gboolean use_offsets;
|
|
} AudioBufferTestData;
|
|
|
|
GST_START_TEST (test_audio_buffer_and_audio_meta)
|
|
{
|
|
AudioBufferTestData td[] = {
|
|
{GST_AUDIO_FORMAT_S24_32, GST_AUDIO_LAYOUT_NON_INTERLEAVED,
|
|
4, 60, 240, {10, 760, 510, 260}, TRUE, TRUE},
|
|
{GST_AUDIO_FORMAT_F32, GST_AUDIO_LAYOUT_NON_INTERLEAVED,
|
|
4, 60, 240, {0, 240, 480, 720}, TRUE, FALSE},
|
|
{GST_AUDIO_FORMAT_S16, GST_AUDIO_LAYOUT_INTERLEAVED,
|
|
4, 125, 1000, {0}, TRUE, FALSE},
|
|
{GST_AUDIO_FORMAT_S16, GST_AUDIO_LAYOUT_INTERLEAVED,
|
|
4, 125, 1000, {0}, FALSE, FALSE},
|
|
{GST_AUDIO_FORMAT_S8, GST_AUDIO_LAYOUT_INTERLEAVED,
|
|
8, 125, 1000, {0}, FALSE, FALSE},
|
|
{GST_AUDIO_FORMAT_U8, GST_AUDIO_LAYOUT_NON_INTERLEAVED,
|
|
8, 125, 125, {0, 125, 250, 375, 500, 625, 750, 875}, TRUE, FALSE},
|
|
{GST_AUDIO_FORMAT_U32, GST_AUDIO_LAYOUT_NON_INTERLEAVED,
|
|
10, 25, 100, {0, 100, 200, 300, 400, 500, 600, 700, 800, 900}, TRUE,
|
|
FALSE},
|
|
{GST_AUDIO_FORMAT_U32, GST_AUDIO_LAYOUT_INTERLEAVED,
|
|
10, 25, 1000, {0}, FALSE, FALSE},
|
|
};
|
|
gint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (td); i++) {
|
|
GstBuffer *buf;
|
|
guint8 *data;
|
|
GstAudioInfo info;
|
|
GstAudioMeta *meta;
|
|
GstAudioBuffer buffer;
|
|
gint j;
|
|
|
|
gst_audio_info_init (&info);
|
|
gst_audio_info_set_format (&info, td[i].format, 44100, td[i].channels,
|
|
NULL);
|
|
info.layout = td[i].layout;
|
|
|
|
buf = make_buffer (&data);
|
|
if (td[i].add_meta) {
|
|
meta = gst_buffer_add_audio_meta (buf, &info, td[i].samples,
|
|
td[i].use_offsets ? td[i].offsets : NULL);
|
|
|
|
fail_unless (meta);
|
|
fail_unless (GST_AUDIO_INFO_IS_VALID (&meta->info));
|
|
fail_unless (gst_audio_info_is_equal (&meta->info, &info));
|
|
fail_unless_equals_int (meta->info.finfo->format, td[i].format);
|
|
fail_unless_equals_int (meta->info.layout, td[i].layout);
|
|
fail_unless_equals_int (meta->info.channels, td[i].channels);
|
|
fail_unless_equals_int (meta->samples, td[i].samples);
|
|
|
|
if (td[i].layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
|
|
fail_unless (meta->offsets);
|
|
for (j = 0; j < td[i].channels; j++) {
|
|
fail_unless_equals_int (meta->offsets[j], td[i].offsets[j]);
|
|
}
|
|
} else {
|
|
fail_if (meta->offsets);
|
|
}
|
|
}
|
|
|
|
fail_unless (gst_audio_buffer_map (&buffer, &info, buf, GST_MAP_READ));
|
|
fail_unless_equals_pointer (buffer.buffer, buf);
|
|
fail_unless (GST_AUDIO_INFO_IS_VALID (&buffer.info));
|
|
fail_unless (gst_audio_info_is_equal (&buffer.info, &info));
|
|
fail_unless_equals_int (buffer.n_samples, td[i].samples);
|
|
|
|
if (td[i].layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
|
|
fail_unless_equals_int (buffer.n_planes, td[i].channels);
|
|
for (j = 0; j < td[i].channels; j++) {
|
|
fail_unless_equals_pointer (buffer.planes[j], data + td[i].offsets[j]);
|
|
}
|
|
} else {
|
|
fail_unless_equals_int (buffer.n_planes, 1);
|
|
fail_unless_equals_pointer (buffer.planes[0], data);
|
|
}
|
|
|
|
fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&buffer),
|
|
td[i].plane_size);
|
|
|
|
if (buffer.n_planes <= 8) {
|
|
fail_unless_equals_pointer (buffer.map_infos, buffer.priv_map_infos_arr);
|
|
fail_unless_equals_pointer (buffer.planes, buffer.priv_planes_arr);
|
|
} else {
|
|
fail_if (buffer.map_infos == buffer.priv_map_infos_arr);
|
|
fail_if (buffer.planes == buffer.priv_planes_arr);
|
|
}
|
|
|
|
gst_audio_buffer_unmap (&buffer);
|
|
gst_buffer_unref (buf);
|
|
}
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
typedef struct
|
|
{
|
|
const gchar *str;
|
|
GstAudioFormat format;
|
|
GstAudioLayout layout;
|
|
gint rate;
|
|
gint channels;
|
|
gboolean ret;
|
|
} AudioInfoFromCapsData;
|
|
|
|
GST_START_TEST (test_audio_info_from_caps)
|
|
{
|
|
static const AudioInfoFromCapsData format_list[] = {
|
|
/* raw format, positive */
|
|
{"audio/x-raw, format = (string) S8, layout = (string) non-interleaved, "
|
|
"rate = (int) 44100, channels = (int) 2", GST_AUDIO_FORMAT_S8,
|
|
GST_AUDIO_LAYOUT_NON_INTERLEAVED, 44100, 2, TRUE},
|
|
{"audio/x-raw, format = (string) U8, layout = (string) interleaved, "
|
|
"rate = (int) 44100, channels = (int) 1", GST_AUDIO_FORMAT_U8,
|
|
GST_AUDIO_LAYOUT_INTERLEAVED, 44100, 1, TRUE},
|
|
|
|
/* raw format, negative */
|
|
/* unknown format */
|
|
{"audio/x-raw, format = (string) foo, layout = (string) interleaved, "
|
|
"rate = (int) 44100, channels = (int) 2", GST_AUDIO_FORMAT_UNKNOWN,
|
|
GST_AUDIO_LAYOUT_INTERLEAVED, 0, 0, FALSE},
|
|
{"audio/x-raw, layout = (string) non-interleaved, "
|
|
"rate = (int) 44100, channels = (int) 2", GST_AUDIO_FORMAT_UNKNOWN,
|
|
GST_AUDIO_LAYOUT_INTERLEAVED, 0, 0, FALSE},
|
|
/* unknown layout */
|
|
{"audio/x-raw, format = (string) U8, "
|
|
"rate = (int) 44100, channels = (int) 2", GST_AUDIO_FORMAT_UNKNOWN,
|
|
GST_AUDIO_LAYOUT_INTERLEAVED, 0, 0, FALSE},
|
|
/* unknown rate */
|
|
{"audio/x-raw, format = (string) U8, layout = (string) interleaved, "
|
|
"channels = (int) 2", GST_AUDIO_FORMAT_UNKNOWN,
|
|
GST_AUDIO_LAYOUT_INTERLEAVED, 0, 0, FALSE},
|
|
/* unknown channels */
|
|
{"audio/x-raw, format = (string) U8, layout = (string) interleaved, "
|
|
"rate = (int) 44100", GST_AUDIO_FORMAT_UNKNOWN,
|
|
GST_AUDIO_LAYOUT_INTERLEAVED, 0, 0, FALSE},
|
|
/* video caps */
|
|
{"video/x-raw, format = (string) NV12",
|
|
GST_AUDIO_FORMAT_UNKNOWN, GST_AUDIO_LAYOUT_INTERLEAVED, 0, 0, FALSE},
|
|
|
|
/* encoded format, it allow empty fields */
|
|
{"audio/x-opus", GST_AUDIO_FORMAT_ENCODED,
|
|
GST_AUDIO_LAYOUT_INTERLEAVED, 0, 0, TRUE},
|
|
/* rate only */
|
|
{"audio/x-opus, rate = (int) 44100", GST_AUDIO_FORMAT_ENCODED,
|
|
GST_AUDIO_LAYOUT_INTERLEAVED, 44100, 0, TRUE},
|
|
/* channels only */
|
|
{"audio/x-opus, channels = (int) 2", GST_AUDIO_FORMAT_ENCODED,
|
|
GST_AUDIO_LAYOUT_INTERLEAVED, 0, 2, TRUE},
|
|
/* rate and channels */
|
|
{"audio/x-opus, rate = (int) 44100, channels = (int) 2",
|
|
GST_AUDIO_FORMAT_ENCODED, GST_AUDIO_LAYOUT_INTERLEAVED, 44100, 2, TRUE},
|
|
};
|
|
gint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (format_list); i++) {
|
|
GstAudioInfo info;
|
|
GstCaps *caps;
|
|
|
|
GST_LOG ("checking %dth format", i);
|
|
|
|
caps = gst_caps_from_string (format_list[i].str);
|
|
fail_unless (caps != NULL);
|
|
|
|
gst_audio_info_init (&info);
|
|
fail_unless_equals_int (gst_audio_info_from_caps (&info, caps),
|
|
format_list[i].ret);
|
|
|
|
if (format_list[i].ret) {
|
|
fail_unless_equals_int (GST_AUDIO_INFO_FORMAT (&info),
|
|
format_list[i].format);
|
|
fail_unless_equals_int (GST_AUDIO_INFO_LAYOUT (&info),
|
|
format_list[i].layout);
|
|
fail_unless_equals_int (GST_AUDIO_INFO_RATE (&info), format_list[i].rate);
|
|
fail_unless_equals_int (GST_AUDIO_INFO_CHANNELS (&info),
|
|
format_list[i].channels);
|
|
}
|
|
|
|
gst_caps_unref (caps);
|
|
}
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_audio_make_raw_caps)
|
|
{
|
|
GstCaps *caps, *expected;
|
|
GstAudioFormat f1[] = { GST_AUDIO_FORMAT_U8 };
|
|
GstAudioFormat f2[] = { GST_AUDIO_FORMAT_U8, GST_AUDIO_FORMAT_S8 };
|
|
|
|
caps =
|
|
gst_audio_make_raw_caps (f1, G_N_ELEMENTS (f1),
|
|
GST_AUDIO_LAYOUT_INTERLEAVED);
|
|
expected =
|
|
gst_caps_from_string
|
|
("audio/x-raw, format = (string) U8, rate = (int) [ 1, max ], channels = (int) [ 1, max ], layout = (string) interleaved");
|
|
fail_unless (gst_caps_is_equal (caps, expected));
|
|
gst_caps_unref (caps);
|
|
gst_caps_unref (expected);
|
|
|
|
caps =
|
|
gst_audio_make_raw_caps (f2, G_N_ELEMENTS (f2),
|
|
GST_AUDIO_LAYOUT_NON_INTERLEAVED);
|
|
expected =
|
|
gst_caps_from_string
|
|
("audio/x-raw, format = (string) { U8, S8 }, rate = (int) [ 1, max ], channels = (int) [ 1, max ], layout = (string) non-interleaved");
|
|
fail_unless (gst_caps_is_equal (caps, expected));
|
|
gst_caps_unref (caps);
|
|
gst_caps_unref (expected);
|
|
|
|
caps = gst_audio_make_raw_caps (NULL, 0, GST_AUDIO_LAYOUT_INTERLEAVED);
|
|
expected =
|
|
gst_caps_from_string
|
|
("audio/x-raw, format = (string) { S8, U8, S16LE, S16BE, U16LE, U16BE, S24_32LE, S24_32BE, U24_32LE, U24_32BE, S32LE, S32BE, U32LE, U32BE, S24LE, S24BE, U24LE, U24BE, S20LE, S20BE, U20LE, U20BE, S18LE, S18BE, U18LE, U18BE, F32LE, F32BE, F64LE, F64BE }, rate = (int) [ 1, max ], channels = (int) [ 1, max ], layout = (string) interleaved");
|
|
fail_unless (gst_caps_is_equal (caps, expected));
|
|
gst_caps_unref (caps);
|
|
gst_caps_unref (expected);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_audio_meta_serialize)
|
|
{
|
|
GstBuffer *buf;
|
|
GstAudioInfo info;
|
|
GstAudioMeta *meta;
|
|
|
|
GstAudioChannelPosition position[] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
|
|
};
|
|
gst_audio_info_init (&info);
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S32, 44100, 2, position);
|
|
info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
|
|
|
|
/* Add audio meta */
|
|
gsize samples = 1;
|
|
gsize buf_size = 4 * 2 * samples;
|
|
buf = gst_buffer_new_and_alloc (buf_size);
|
|
gsize offsets[] = { 0, buf_size / 2 };
|
|
meta = gst_buffer_add_audio_meta (buf, &info, samples, offsets);
|
|
|
|
/* Serialize */
|
|
GByteArray *data = g_byte_array_new ();
|
|
fail_unless (gst_meta_serialize_simple ((GstMeta *) meta, data));
|
|
gst_buffer_unref (buf);
|
|
|
|
/* Create a new buffer */
|
|
buf = gst_buffer_new_and_alloc (buf_size);
|
|
guint32 consumed;
|
|
meta = (GstAudioMeta *) gst_meta_deserialize (buf, data->data, data->len,
|
|
&consumed);
|
|
fail_unless (meta);
|
|
fail_unless (consumed == data->len);
|
|
g_byte_array_unref (data);
|
|
|
|
/* Check meta's content */
|
|
g_assert_cmpint (meta->info.finfo->format, ==, GST_AUDIO_FORMAT_S32);
|
|
g_assert_cmpint (meta->info.layout, ==, GST_AUDIO_LAYOUT_NON_INTERLEAVED);
|
|
g_assert_cmpint (meta->info.rate, ==, 44100);
|
|
g_assert_cmpint (meta->info.channels, ==, 2);
|
|
g_assert_cmpint (meta->info.position[0], ==,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT);
|
|
g_assert_cmpint (meta->info.position[1], ==,
|
|
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT);
|
|
g_assert_cmpuint (meta->samples, ==, samples);
|
|
g_assert_cmpuint (meta->offsets[0], ==, 0);
|
|
g_assert_cmpuint (meta->offsets[1], ==, buf_size / 2);
|
|
|
|
gst_buffer_unref (buf);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_audio_meta_serialize_65_chans)
|
|
{
|
|
GstBuffer *buf;
|
|
GstAudioInfo info;
|
|
GstAudioMeta *meta;
|
|
|
|
/* With more than 64 channels we cannot have positions */
|
|
gst_audio_info_init (&info);
|
|
gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S32, 44100, 65, NULL);
|
|
info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
|
|
|
|
/* Add audio meta */
|
|
gsize samples = 1;
|
|
gsize buf_size = 4 * 65 * samples;
|
|
buf = gst_buffer_new_and_alloc (buf_size);
|
|
gsize offsets[65];
|
|
for (int i = 0; i < 65; i++)
|
|
offsets[i] = i * samples * 4;
|
|
meta = gst_buffer_add_audio_meta (buf, &info, samples, offsets);
|
|
|
|
/* Serialize */
|
|
GByteArray *data = g_byte_array_new ();
|
|
fail_unless (gst_meta_serialize_simple ((GstMeta *) meta, data));
|
|
gst_buffer_unref (buf);
|
|
|
|
/* Create a new buffer */
|
|
buf = gst_buffer_new_and_alloc (buf_size);
|
|
guint32 consumed;
|
|
meta = (GstAudioMeta *) gst_meta_deserialize (buf, data->data, data->len,
|
|
&consumed);
|
|
fail_unless (meta);
|
|
fail_unless (consumed == data->len);
|
|
g_byte_array_unref (data);
|
|
|
|
/* Check meta's content */
|
|
g_assert_cmpint (meta->info.finfo->format, ==, GST_AUDIO_FORMAT_S32);
|
|
g_assert_cmpint (meta->info.layout, ==, GST_AUDIO_LAYOUT_NON_INTERLEAVED);
|
|
g_assert_cmpint (meta->info.rate, ==, 44100);
|
|
g_assert_cmpint (meta->info.channels, ==, 65);
|
|
g_assert_cmpuint (meta->samples, ==, samples);
|
|
for (int i = 0; i < 65; i++)
|
|
g_assert_cmpuint (meta->offsets[i], ==, i * samples * 4);
|
|
|
|
gst_buffer_unref (buf);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
static Suite *
|
|
audio_suite (void)
|
|
{
|
|
Suite *s = suite_create ("audio support library");
|
|
|
|
TCase *tc_chain = tcase_create ("general");
|
|
|
|
suite_add_tcase (s, tc_chain);
|
|
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_and_stop_planar);
|
|
tcase_add_test (tc_chain, test_buffer_clip_time_start);
|
|
tcase_add_test (tc_chain, test_buffer_clip_time_start_planar);
|
|
tcase_add_test (tc_chain, test_buffer_clip_time_stop);
|
|
tcase_add_test (tc_chain, test_buffer_clip_time_stop_planar);
|
|
tcase_add_test (tc_chain, test_buffer_clip_time_outside);
|
|
tcase_add_test (tc_chain, test_buffer_clip_time_start_and_stop_no_meta);
|
|
tcase_add_test (tc_chain, test_buffer_clip_time_no_timestamp);
|
|
tcase_add_test (tc_chain, test_buffer_clip_time_handles_rounding);
|
|
tcase_add_test (tc_chain, test_buffer_clip_samples_start_and_stop);
|
|
tcase_add_test (tc_chain, test_buffer_clip_samples_start_and_stop_planar);
|
|
tcase_add_test (tc_chain, test_buffer_clip_samples_start);
|
|
tcase_add_test (tc_chain, test_buffer_clip_samples_stop);
|
|
tcase_add_test (tc_chain, test_buffer_clip_samples_outside);
|
|
tcase_add_test (tc_chain, test_buffer_clip_samples_start_and_stop_no_meta);
|
|
tcase_add_test (tc_chain, test_buffer_clip_samples_no_timestamp);
|
|
tcase_add_test (tc_chain, test_buffer_truncate_samples_offset_end);
|
|
tcase_add_test (tc_chain, test_buffer_truncate_samples_no_timestamp);
|
|
tcase_add_test (tc_chain, test_multichannel_checks);
|
|
tcase_add_test (tc_chain, test_multichannel_reorder);
|
|
tcase_add_test (tc_chain, test_audio_format_s8);
|
|
tcase_add_test (tc_chain, test_audio_format_u8);
|
|
tcase_add_test (tc_chain, test_fill_silence);
|
|
tcase_add_test (tc_chain, test_stream_align);
|
|
tcase_add_test (tc_chain, test_stream_align_reverse);
|
|
tcase_add_test (tc_chain, test_audio_buffer_and_audio_meta);
|
|
tcase_add_test (tc_chain, test_audio_info_from_caps);
|
|
tcase_add_test (tc_chain, test_audio_make_raw_caps);
|
|
tcase_add_test (tc_chain, test_audio_meta_serialize);
|
|
tcase_add_test (tc_chain, test_audio_meta_serialize_65_chans);
|
|
|
|
return s;
|
|
}
|
|
|
|
GST_CHECK_MAIN (audio);
|