diff options
Diffstat (limited to 'tests/check/pipelines')
-rw-r--r-- | tests/check/pipelines/effectv.c | 146 | ||||
-rw-r--r-- | tests/check/pipelines/flacdec.c | 247 | ||||
-rw-r--r-- | tests/check/pipelines/simple-launch-lines.c | 284 | ||||
-rw-r--r-- | tests/check/pipelines/tagschecking.c | 354 | ||||
-rw-r--r-- | tests/check/pipelines/wavenc.c | 201 | ||||
-rw-r--r-- | tests/check/pipelines/wavpack.c | 217 |
6 files changed, 1449 insertions, 0 deletions
diff --git a/tests/check/pipelines/effectv.c b/tests/check/pipelines/effectv.c new file mode 100644 index 0000000..1e8d96f --- /dev/null +++ b/tests/check/pipelines/effectv.c @@ -0,0 +1,146 @@ +/* GStreamer + * + * Copyright (C) <2009> 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gst/check/gstcheck.h> +#include <string.h> + +typedef struct +{ + GMainLoop *loop; + gboolean eos; +} OnMessageUserData; + +static void +on_message_cb (GstBus * bus, GstMessage * message, gpointer user_data) +{ + OnMessageUserData *d = user_data; + + switch (GST_MESSAGE_TYPE (message)) { + case GST_MESSAGE_ERROR: + case GST_MESSAGE_WARNING: + g_assert_not_reached (); + break; + case GST_MESSAGE_EOS: + g_main_loop_quit (d->loop); + d->eos = TRUE; + break; + default: + break; + } +} + +static void +run_test (const gchar * pipeline_string) +{ + GstElement *pipeline; + GstBus *bus; + GMainLoop *loop; + OnMessageUserData omud = { NULL, }; + GstStateChangeReturn ret; + + GST_DEBUG ("Testing pipeline '%s'", pipeline_string); + + pipeline = gst_parse_launch (pipeline_string, NULL); + fail_unless (pipeline != NULL); + g_object_set (G_OBJECT (pipeline), "async-handling", TRUE, NULL); + + loop = g_main_loop_new (NULL, FALSE); + + bus = gst_element_get_bus (pipeline); + fail_unless (bus != NULL); + gst_bus_add_signal_watch (bus); + + omud.loop = loop; + omud.eos = FALSE; + + g_signal_connect (bus, "message", (GCallback) on_message_cb, &omud); + + gst_object_unref (bus); + + ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); + fail_unless (ret == GST_STATE_CHANGE_SUCCESS + || ret == GST_STATE_CHANGE_ASYNC); + + g_main_loop_run (loop); + + fail_unless (gst_element_set_state (pipeline, + GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS); + + fail_unless (omud.eos == TRUE); + + gst_object_unref (pipeline); + g_main_loop_unref (loop); +} + +#define CREATE_TEST(element) \ +GST_START_TEST (test_##element) \ +{ \ + gchar *pipeline; \ + \ + pipeline = g_strdup_printf ("videotestsrc num-buffers=100 ! " \ + "ffmpegcolorspace ! " \ + " %s ! " \ + " fakesink", #element); \ + \ + run_test (pipeline); \ + g_free (pipeline); \ +} \ +\ +GST_END_TEST; + +CREATE_TEST (agingtv); +CREATE_TEST (dicetv); +CREATE_TEST (edgetv); +CREATE_TEST (optv); +CREATE_TEST (quarktv); +CREATE_TEST (radioactv); +CREATE_TEST (revtv); +CREATE_TEST (rippletv); +CREATE_TEST (shagadelictv); +CREATE_TEST (streaktv); +CREATE_TEST (vertigotv); +CREATE_TEST (warptv); + +static Suite * +effectv_suite (void) +{ + Suite *s = suite_create ("effectv"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_set_timeout (tc_chain, 180); + + tcase_add_test (tc_chain, test_agingtv); + tcase_add_test (tc_chain, test_dicetv); + tcase_add_test (tc_chain, test_edgetv); + tcase_add_test (tc_chain, test_optv); + tcase_add_test (tc_chain, test_quarktv); + tcase_add_test (tc_chain, test_radioactv); + tcase_add_test (tc_chain, test_revtv); + tcase_add_test (tc_chain, test_rippletv); + tcase_add_test (tc_chain, test_shagadelictv); + tcase_add_test (tc_chain, test_streaktv); + tcase_add_test (tc_chain, test_vertigotv); + tcase_add_test (tc_chain, test_warptv); + + return s; +} + +GST_CHECK_MAIN (effectv); diff --git a/tests/check/pipelines/flacdec.c b/tests/check/pipelines/flacdec.c new file mode 100644 index 0000000..ce8546e --- /dev/null +++ b/tests/check/pipelines/flacdec.c @@ -0,0 +1,247 @@ +/* GStreamer + * Copyright (C) 2009 Thomas Vander Stichele <thomas at apestaart dot org> + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gst/check/gstcheck.h> +#include <glib/gstdio.h> + +static guint16 +buffer_get_first_sample (GstBuffer * buf) +{ + GstStructure *s; + gint w, d, c, r, e; + + fail_unless (buf != NULL, "NULL buffer"); + fail_unless (GST_BUFFER_CAPS (buf) != NULL, "buffer without caps"); + + /* log buffer details */ + GST_DEBUG ("buffer with size=%u, caps=%" GST_PTR_FORMAT, + GST_BUFFER_SIZE (buf), GST_BUFFER_CAPS (buf)); + GST_MEMDUMP ("buffer data from decoder", GST_BUFFER_DATA (buf), + GST_BUFFER_SIZE (buf)); + + /* make sure it's the format we expect */ + s = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0); + fail_unless_equals_string (gst_structure_get_name (s), "audio/x-raw-int"); + fail_unless (gst_structure_get_int (s, "width", &w)); + fail_unless_equals_int (w, 16); + fail_unless (gst_structure_get_int (s, "depth", &d)); + fail_unless_equals_int (d, 16); + fail_unless (gst_structure_get_int (s, "rate", &r)); + fail_unless_equals_int (r, 44100); + fail_unless (gst_structure_get_int (s, "channels", &c)); + fail_unless_equals_int (c, 1); + fail_unless (gst_structure_get_int (s, "endianness", &e)); + if (e == G_BIG_ENDIAN) + return GST_READ_UINT16_BE (GST_BUFFER_DATA (buf)); + else + return GST_READ_UINT16_LE (GST_BUFFER_DATA (buf)); +} + +GST_START_TEST (test_decode) +{ + GstElement *pipeline; + GstElement *appsink; + GstBuffer *buffer = NULL; + guint16 first_sample = 0; + guint size = 0; + gchar *path = + g_build_filename (GST_TEST_FILES_PATH, "audiotestsrc.flac", NULL); + gchar *pipe_desc = + g_strdup_printf ("filesrc location=\"%s\" ! flacdec ! appsink name=sink", + path); + + pipeline = gst_parse_launch (pipe_desc, NULL); + fail_unless (pipeline != NULL); + + g_free (path); + g_free (pipe_desc); + + appsink = gst_bin_get_by_name (GST_BIN (pipeline), "sink"); + fail_unless (appsink != NULL); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + do { + g_signal_emit_by_name (appsink, "pull-buffer", &buffer); + if (buffer == NULL) + break; + if (first_sample == 0) + first_sample = buffer_get_first_sample (buffer); + GST_DEBUG ("buffer: %d\n", buffer->size); + GST_DEBUG ("buffer: %04x\n", buffer_get_first_sample (buffer)); + size += buffer->size; + + gst_buffer_unref (buffer); + buffer = NULL; + } + while (TRUE); + + /* audiotestsrc with samplesperbuffer 1024 and 10 num-buffers */ + fail_unless_equals_int (size, 20480); + fail_unless_equals_int (first_sample, 0x066a); + + gst_element_set_state (pipeline, GST_STATE_NULL); + g_object_unref (pipeline); + g_object_unref (appsink); +} + +GST_END_TEST; + +GST_START_TEST (test_decode_seek_full) +{ + GstElement *pipeline; + GstElement *appsink; + GstEvent *event; + GstBuffer *buffer = NULL; + guint16 first_sample = 0; + guint size = 0; + gchar *path = + g_build_filename (GST_TEST_FILES_PATH, "audiotestsrc.flac", NULL); + gchar *pipe_desc = + g_strdup_printf ("filesrc location=\"%s\" ! flacdec ! appsink name=sink", + path); + + pipeline = gst_parse_launch (pipe_desc, NULL); + fail_unless (pipeline != NULL); + + g_free (pipe_desc); + g_free (path); + + appsink = gst_bin_get_by_name (GST_BIN (pipeline), "sink"); + fail_unless (appsink != NULL); + + gst_element_set_state (pipeline, GST_STATE_PAUSED); + gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + + /* do a seek that should give us the complete output */ + event = gst_event_new_seek (1.0, GST_FORMAT_DEFAULT, GST_SEEK_FLAG_FLUSH, + GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 20480); + fail_unless (gst_element_send_event (appsink, event)); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + do { + g_signal_emit_by_name (appsink, "pull-buffer", &buffer); + if (buffer == NULL) + break; + if (first_sample == 0) + first_sample = buffer_get_first_sample (buffer); + size += buffer->size; + + gst_buffer_unref (buffer); + buffer = NULL; + } + while (TRUE); + + /* file was generated with audiotestsrc + * with 1024 samplesperbuffer and 10 num-buffers in 16 bit audio */ + fail_unless_equals_int (size, 20480); + fail_unless_equals_int (first_sample, 0x066a); + + gst_element_set_state (pipeline, GST_STATE_NULL); + + g_object_unref (pipeline); + g_object_unref (appsink); +} + +GST_END_TEST; + +GST_START_TEST (test_decode_seek_partial) +{ + GstElement *pipeline; + GstElement *appsink; + GstEvent *event; + GstBuffer *buffer = NULL; + guint size = 0; + guint16 first_sample = 0; + gchar *path = + g_build_filename (GST_TEST_FILES_PATH, "audiotestsrc.flac", NULL); + gchar *pipe_desc = + g_strdup_printf ("filesrc location=\"%s\" ! flacdec ! appsink name=sink", + path); + + pipeline = gst_parse_launch (pipe_desc, NULL); + fail_unless (pipeline != NULL); + + g_free (path); + g_free (pipe_desc); + + appsink = gst_bin_get_by_name (GST_BIN (pipeline), "sink"); + fail_unless (appsink != NULL); + + gst_element_set_state (pipeline, GST_STATE_PAUSED); + gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + + /* do a partial seek to get the first 1024 samples or 2048 bytes */ + event = gst_event_new_seek (1.0, GST_FORMAT_DEFAULT, GST_SEEK_FLAG_FLUSH, + GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 1024); + GST_DEBUG ("seeking"); + fail_unless (gst_element_send_event (appsink, event)); + GST_DEBUG ("seeked"); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + do { + GST_DEBUG ("pulling buffer"); + g_signal_emit_by_name (appsink, "pull-buffer", &buffer); + GST_DEBUG ("pulled buffer %p", buffer); + if (buffer == NULL) + break; + if (first_sample == 0) { + fail_unless_equals_int (GST_BUFFER_OFFSET (buffer), 0L); + first_sample = buffer_get_first_sample (buffer); + } + size += buffer->size; + + gst_buffer_unref (buffer); + buffer = NULL; + } + while (TRUE); + + fail_unless_equals_int (size, 2048); + fail_unless_equals_int (first_sample, 0x066a); + + gst_element_set_state (pipeline, GST_STATE_NULL); + + g_object_unref (pipeline); + g_object_unref (appsink); +} + +GST_END_TEST; + + +static Suite * +flacdec_suite (void) +{ + Suite *s = suite_create ("flacdec"); + + TCase *tc_chain = tcase_create ("linear"); + + /* time out after 60s, not the default 3 */ + tcase_set_timeout (tc_chain, 60); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_decode); + tcase_add_test (tc_chain, test_decode_seek_full); + tcase_add_test (tc_chain, test_decode_seek_partial); + + return s; +} + +GST_CHECK_MAIN (flacdec); diff --git a/tests/check/pipelines/simple-launch-lines.c b/tests/check/pipelines/simple-launch-lines.c new file mode 100644 index 0000000..c1c12ed --- /dev/null +++ b/tests/check/pipelines/simple-launch-lines.c @@ -0,0 +1,284 @@ +/* GStreamer + * Copyright (C) 2005 Andy Wingo <wingo@pobox.com> + * + * simple_launch_lines.c: Unit test for simple pipelines + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gst/check/gstcheck.h> + +#ifndef GST_DISABLE_PARSE + +static GstElement * +setup_pipeline (const gchar * pipe_descr) +{ + GstElement *pipeline; + + pipeline = gst_parse_launch (pipe_descr, NULL); + g_return_val_if_fail (GST_IS_PIPELINE (pipeline), NULL); + return pipeline; +} + +/* + * run_pipeline: + * @pipe: the pipeline to run + * @desc: the description for use in messages + * @events: is a mask of expected events + * @tevent: is the expected terminal event. + * + * the poll call will time out after half a second. + */ +static void +run_pipeline (GstElement * pipe, const gchar * descr, + GstMessageType events, GstMessageType tevent, GstState target_state) +{ + GstBus *bus; + GstMessage *message; + GstMessageType revent; + GstStateChangeReturn ret; + + g_assert (pipe); + bus = gst_element_get_bus (pipe); + g_assert (bus); + + fail_if (gst_element_set_state (pipe, target_state) == + GST_STATE_CHANGE_FAILURE, "Could not set pipeline %s to playing", descr); + ret = gst_element_get_state (pipe, NULL, NULL, 10 * GST_SECOND); + if (ret == GST_STATE_CHANGE_ASYNC) { + g_critical ("Pipeline '%s' failed to go to PAUSED fast enough", descr); + goto done; + } else if ((ret != GST_STATE_CHANGE_SUCCESS) + && (ret != GST_STATE_CHANGE_NO_PREROLL)) { + g_critical ("Pipeline '%s' failed to go into PAUSED state (%s)", descr, + gst_element_state_change_return_get_name (ret)); + goto done; + } + + while (1) { + message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); + + /* always have to pop the message before getting back into poll */ + if (message) { + revent = GST_MESSAGE_TYPE (message); + gst_message_unref (message); + } else { + revent = GST_MESSAGE_UNKNOWN; + } + + if (revent == tevent) { + break; + } else if (revent == GST_MESSAGE_UNKNOWN) { + g_critical ("Unexpected timeout in gst_bus_poll, looking for %d: %s", + tevent, descr); + break; + } else if (revent & events) { + continue; + } + g_critical + ("Unexpected message received of type %d, '%s', looking for %d: %s", + revent, gst_message_type_get_name (revent), tevent, descr); + } + +done: + fail_if (gst_element_set_state (pipe, GST_STATE_NULL) == + GST_STATE_CHANGE_FAILURE, "Could not set pipeline %s to NULL", descr); + gst_element_get_state (pipe, NULL, NULL, GST_CLOCK_TIME_NONE); + gst_object_unref (pipe); + + gst_bus_set_flushing (bus, TRUE); + gst_object_unref (bus); +} + +GST_START_TEST (test_rtp_payloaders) +{ + const gchar *s; + + /* FIXME: going to playing would be nice, but thet leads to lot of failure */ + GstState target_state = GST_STATE_PAUSED; + + /* we use is-live here to avoid preroll */ +#define PIPELINE_STRING(bufcount, bufsize, pl, dpl) "fakesrc is-live=true num-buffers=" bufcount " filltype=2 sizetype=2 sizemax=" bufsize " ! " pl " ! " dpl " ! fakesink" +#define DEFAULT_BUFCOUNT "5" +#define DEFAULT_BUFSIZE "16" + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtpilbcpay", + "rtpilbcdepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtpgsmpay", + "rtpgsmdepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + /* This one needs a bit different buffer size than others or it doesn't work. */ + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, "52", "rtpamrpay", "rtpamrdepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtppcmapay", + "rtppcmadepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtppcmupay", + "rtppcmudepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtpmpapay", + "rtpmpadepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtph263ppay", + "rtph263pdepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtph263pay", + "rtph263depay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtph264pay", + "rtph264depay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtpL16pay", + "rtpL16depay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtpmp2tpay", + "rtpmp2tdepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtpmp4vpay", + "rtpmp4vdepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtpmp4gpay", + "rtpmp4gdepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + /* Cannot be tested with fakesrc becouse speex payloader requires a valid header?! */ + /* + s = PIPELINE_STRING(DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtpspeexpay", "rtpspeexdepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + */ + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtptheorapay", + "rtptheoradepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = PIPELINE_STRING (DEFAULT_BUFCOUNT, DEFAULT_BUFSIZE, "rtpvorbispay", + "rtpvorbisdepay"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + /*s = FAKESRC " ! ! rtpac3depay ! " FAKESINK */ + /*s = FAKESRC " ! ! asteriskh263 ! " FAKESINK; */ + /*s = FAKESRC " ! ! rtpmpvdepay ! " FAKESINK; */ + /*s = FAKESRC " ! ! rtpmp4adepay ! " FAKESINK; */ + /*s = FAKESRC " ! ! rtpsv3vdepay ! " FAKESINK; */ +} + +GST_END_TEST +GST_START_TEST (test_video_encoders_decoders) +{ + const gchar *s; + GstState target_state = GST_STATE_PLAYING; + + /* no is-live on the source because we actually want to preroll since + * run_pipeline only goes into PAUSED */ +#define ENC_DEC_PIPELINE_STRING(bufcount, enc, dec) "videotestsrc num-buffers=" bufcount " ! " enc " ! " dec " ! fakesink" +#define DEFAULT_BUFCOUNT "5" + + s = ENC_DEC_PIPELINE_STRING (DEFAULT_BUFCOUNT, "jpegenc", "jpegdec"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = ENC_DEC_PIPELINE_STRING (DEFAULT_BUFCOUNT, "pngenc", "pngdec"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); + + s = ENC_DEC_PIPELINE_STRING (DEFAULT_BUFCOUNT, "smokeenc", "smokedec"); + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN, target_state); +} + +GST_END_TEST +#endif /* #ifndef GST_DISABLE_PARSE */ +static Suite * +simple_launch_lines_suite (void) +{ + Suite *s = suite_create ("Pipelines"); + TCase *tc_chain = tcase_create ("linear"); + + /* time out after 60s, not the default 3 */ + tcase_set_timeout (tc_chain, 60); + + suite_add_tcase (s, tc_chain); +#ifndef GST_DISABLE_PARSE + tcase_add_test (tc_chain, test_rtp_payloaders); + tcase_add_test (tc_chain, test_video_encoders_decoders); +#endif + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = simple_launch_lines_suite (); + SRunner *sr = srunner_create (s); + + gst_check_init (&argc, &argv); + + srunner_run_all (sr, CK_NORMAL); + nf = srunner_ntests_failed (sr); + srunner_free (sr); + + return nf; +} diff --git a/tests/check/pipelines/tagschecking.c b/tests/check/pipelines/tagschecking.c new file mode 100644 index 0000000..d851b3f --- /dev/null +++ b/tests/check/pipelines/tagschecking.c @@ -0,0 +1,354 @@ +/* GStreamer + * Copyright (C) 2008 Nokia Corporation. (contact <stefan.kost@nokia.com>) + * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gst/check/gstcheck.h> + +static GstTagList *received_tags = NULL; + +static gboolean +bus_handler (GstBus * bus, GstMessage * message, gpointer data) +{ + GMainLoop *loop = (GMainLoop *) data; + + switch (message->type) { + case GST_MESSAGE_EOS: + g_main_loop_quit (loop); + break; + case GST_MESSAGE_WARNING: + case GST_MESSAGE_ERROR:{ + GError *gerror; + + gchar *debug; + + gst_message_parse_error (message, &gerror, &debug); + gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); + g_error_free (gerror); + g_free (debug); + g_main_loop_quit (loop); + break; + } + case GST_MESSAGE_TAG:{ + if (received_tags == NULL) { + gst_message_parse_tag (message, &received_tags); + } else { + GstTagList *tl = NULL, *ntl = NULL; + + gst_message_parse_tag (message, &tl); + if (tl) { + ntl = gst_tag_list_merge (received_tags, tl, GST_TAG_MERGE_PREPEND); + if (ntl) { + GST_LOG ("taglists merged: %" GST_PTR_FORMAT, ntl); + gst_tag_list_free (received_tags); + received_tags = ntl; + } + gst_tag_list_free (tl); + } + } + break; + } + default: + break; + } + + return TRUE; +} + +/* + * Creates a pipeline in the form: + * fakesrc num-buffers=1 ! caps ! muxer ! filesink location=file + * + * And sets the tags in tag_str into the muxer via tagsetter. + */ +static void +test_mux_tags (const gchar * tag_str, const gchar * caps, + const gchar * muxer, const gchar * file) +{ + GstElement *pipeline; + GstBus *bus; + GMainLoop *loop; + GstTagList *sent_tags; + GstElement *mux; + GstTagSetter *setter; + gchar *launch_str; + guint bus_watch = 0; + + GST_DEBUG ("testing xmp muxing on : %s", muxer); + + launch_str = g_strdup_printf ("fakesrc num-buffers=1 ! %s ! %s name=mux ! " + "filesink location=%s name=sink", caps, muxer, file); + pipeline = gst_parse_launch (launch_str, NULL); + g_free (launch_str); + fail_unless (pipeline != NULL); + + mux = gst_bin_get_by_name (GST_BIN (pipeline), "mux"); + fail_unless (mux != NULL); + + loop = g_main_loop_new (NULL, TRUE); + fail_unless (loop != NULL); + + bus = gst_element_get_bus (pipeline); + fail_unless (bus != NULL); + bus_watch = gst_bus_add_watch (bus, bus_handler, loop); + gst_object_unref (bus); + + gst_element_set_state (pipeline, GST_STATE_READY); + + setter = GST_TAG_SETTER (mux); + fail_unless (setter != NULL); + sent_tags = gst_structure_from_string (tag_str, NULL); + fail_unless (sent_tags != NULL); + gst_tag_setter_merge_tags (setter, sent_tags, GST_TAG_MERGE_REPLACE); + gst_tag_list_free (sent_tags); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + g_main_loop_run (loop); + + gst_element_set_state (pipeline, GST_STATE_NULL); + + g_main_loop_unref (loop); + g_object_unref (mux); + g_object_unref (pipeline); + g_source_remove (bus_watch); +} + +/* + * Makes a pipeline in the form: + * filesrc location=file ! demuxer ! fakesink + * + * And gets the tags that are posted on the bus to compare + * with the tags in 'tag_str' + */ +static void +test_demux_tags (const gchar * tag_str, const gchar * demuxer, + const gchar * file) +{ + GstElement *pipeline; + GstBus *bus; + GMainLoop *loop; + GstTagList *sent_tags; + gint i, j, n_recv, n_sent; + const gchar *name_sent, *name_recv; + const GValue *value_sent, *value_recv; + gboolean found; + gint comparison; + GstElement *demux; + gchar *launch_str; + guint bus_watch = 0; + + GST_DEBUG ("testing tags : %s", tag_str); + + if (received_tags) { + gst_tag_list_free (received_tags); + received_tags = NULL; + } + + launch_str = g_strdup_printf ("filesrc location=%s ! %s name=demux ! " + "fakesink", file, demuxer); + pipeline = gst_parse_launch (launch_str, NULL); + g_free (launch_str); + fail_unless (pipeline != NULL); + + demux = gst_bin_get_by_name (GST_BIN (pipeline), "demux"); + fail_unless (demux != NULL); + + loop = g_main_loop_new (NULL, TRUE); + fail_unless (loop != NULL); + + bus = gst_element_get_bus (pipeline); + fail_unless (bus != NULL); + bus_watch = gst_bus_add_watch (bus, bus_handler, loop); + gst_object_unref (bus); + + sent_tags = gst_structure_from_string (tag_str, NULL); + fail_unless (sent_tags != NULL); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + g_main_loop_run (loop); + + GST_DEBUG ("mainloop done : %p", received_tags); + + /* verify tags */ + fail_unless (received_tags != NULL); + n_recv = gst_structure_n_fields (received_tags); + n_sent = gst_structure_n_fields (sent_tags); + fail_unless (n_recv >= n_sent); + /* FIXME: compare taglits values */ + for (i = 0; i < n_sent; i++) { + name_sent = gst_structure_nth_field_name (sent_tags, i); + value_sent = gst_structure_get_value (sent_tags, name_sent); + found = FALSE; + for (j = 0; j < n_recv; j++) { + name_recv = gst_structure_nth_field_name (received_tags, j); + if (!strcmp (name_sent, name_recv)) { + value_recv = gst_structure_get_value (received_tags, name_recv); + comparison = gst_value_compare (value_sent, value_recv); + if (comparison != GST_VALUE_EQUAL) { + gchar *vs = g_strdup_value_contents (value_sent); + gchar *vr = g_strdup_value_contents (value_recv); + GST_DEBUG ("sent = %s:'%s', recv = %s:'%s'", + G_VALUE_TYPE_NAME (value_sent), vs, + G_VALUE_TYPE_NAME (value_recv), vr); + g_free (vs); + g_free (vr); + } + fail_unless (comparison == GST_VALUE_EQUAL, + "tag item %s has been received with different type or value", + name_sent); + found = TRUE; + break; + } + } + fail_unless (found, "tag item %s is lost", name_sent); + } + + gst_tag_list_free (received_tags); + received_tags = NULL; + gst_tag_list_free (sent_tags); + + gst_element_set_state (pipeline, GST_STATE_NULL); + + g_main_loop_unref (loop); + g_object_unref (demux); + g_object_unref (pipeline); + g_source_remove (bus_watch); +} + +/* + * Tests if the muxer/demuxer pair can serialize the tags in 'tag_str' + * to a file and recover them correctly. + * + * 'caps' are used to assure the muxer accepts the fake buffer fakesrc + * will send to it. + */ +static void +test_tags (const gchar * tag_str, const gchar * caps, const gchar * muxer, + const gchar * demuxer) +{ + gchar *tmpfile; + gchar *tmp; + + tmp = g_strdup_printf ("%s%d", "gst-check-xmp-test-", g_random_int ()); + tmpfile = g_build_filename (g_get_tmp_dir (), tmp, NULL); + g_free (tmp); + + GST_DEBUG ("testing tags : %s", tag_str); + test_mux_tags (tag_str, caps, muxer, tmpfile); + test_demux_tags (tag_str, demuxer, tmpfile); + g_free (tmpfile); +} + +#define H264_CAPS "video/x-h264, width=(int)320, height=(int)240," \ + " framerate=(fraction)30/1, codec_data=(buffer)" \ + "01401592ffe10017674d401592540a0fd8088000000300" \ + "8000001e478b175001000468ee3c80, stream-format=(string)avc" + +#define COMMON_TAGS \ + "taglist,title=test_title," \ + "artist=test_artist," \ + "keywords=\"key1,key2\"," \ + "description=test_desc" + +GST_START_TEST (test_common_tags) +{ + if (!gst_default_registry_check_feature_version ("qtdemux", 0, 10, 23)) { + GST_INFO ("Skipping test, qtdemux either not available or too old"); + return; + } + test_tags (COMMON_TAGS, H264_CAPS, "qtmux", "qtdemux"); + test_tags (COMMON_TAGS, H264_CAPS, "mp4mux", "qtdemux"); + test_tags (COMMON_TAGS, H264_CAPS, "gppmux", "qtdemux"); +} + +GST_END_TEST; + +#define GEO_LOCATION_TAGS \ + "taglist,geo-location-country=Brazil," \ + "geo-location-city=\"Campina Grande\"," \ + "geo-location-sublocation=Bodocongo," \ + "geo-location-latitude=-12.125," \ + "geo-location-longitude=56.75," \ + "geo-location-elevation=327.5" + +GST_START_TEST (test_geo_location_tags) +{ + if (!gst_default_registry_check_feature_version ("qtdemux", 0, 10, 23)) { + GST_INFO ("Skipping test, qtdemux either not available or too old"); + return; + } + test_tags (GEO_LOCATION_TAGS, H264_CAPS, "qtmux", "qtdemux"); + test_tags (GEO_LOCATION_TAGS, H264_CAPS, "mp4mux", "qtdemux"); + test_tags (GEO_LOCATION_TAGS, H264_CAPS, "gppmux", "qtdemux"); +} + +GST_END_TEST; + + +#define USER_TAGS \ + "taglist,user-rating=(uint)85" + +GST_START_TEST (test_user_tags) +{ + if (!gst_default_registry_check_feature_version ("qtdemux", 0, 10, 23)) { + GST_INFO ("Skipping test, qtdemux either not available or too old"); + return; + } + + test_tags (USER_TAGS, H264_CAPS, "qtmux", "qtdemux"); + test_tags (USER_TAGS, H264_CAPS, "mp4mux", "qtdemux"); + test_tags (USER_TAGS, H264_CAPS, "gppmux", "qtdemux"); +} + +GST_END_TEST; + +static Suite * +metadata_suite (void) +{ + Suite *s = suite_create ("tagschecking"); + + TCase *tc_chain = tcase_create ("general"); + + /* time out after 60s, not the default 3 */ + tcase_set_timeout (tc_chain, 60); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_common_tags); + tcase_add_test (tc_chain, test_geo_location_tags); + tcase_add_test (tc_chain, test_user_tags); + + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = metadata_suite (); + + SRunner *sr = srunner_create (s); + + gst_check_init (&argc, &argv); + + srunner_run_all (sr, CK_NORMAL); + nf = srunner_ntests_failed (sr); + srunner_free (sr); + + return nf; +} diff --git a/tests/check/pipelines/wavenc.c b/tests/check/pipelines/wavenc.c new file mode 100644 index 0000000..c5344a7 --- /dev/null +++ b/tests/check/pipelines/wavenc.c @@ -0,0 +1,201 @@ +/* GStreamer + * + * unit test for wavenc + * + * Copyright (C) <2010> Stefan Kost <ensonic@users.sf.net> + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gst/check/gstcheck.h> +#include <gst/audio/multichannel.h> + +static gboolean +bus_handler (GstBus * bus, GstMessage * message, gpointer data) +{ + GMainLoop *loop = (GMainLoop *) data; + + switch (message->type) { + case GST_MESSAGE_EOS: + g_main_loop_quit (loop); + break; + case GST_MESSAGE_WARNING: + case GST_MESSAGE_ERROR:{ + GError *gerror; + gchar *debug; + + gst_message_parse_error (message, &gerror, &debug); + gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); + gst_message_unref (message); + g_error_free (gerror); + g_free (debug); + g_main_loop_quit (loop); + break; + } + default: + break; + } + + return TRUE; +} + +/* + * gst-launch \ + * audiotestsrc freq=440 num-buffers=100 ! interleave name=i ! audioconvert ! wavenc ! filesink location=/tmp/mc.wav \ + * audiotestsrc freq=880 num-buffers=100 ! i. + * ... + * + * http://www.microsoft.com/whdc/device/audio/multichaud.mspx + */ + +static void +make_n_channel_wav (const gint channels, const GValueArray * arr) +{ + GstElement *pipeline; + GstElement **audiotestsrc, *interleave, *wavenc, *conv, *fakesink; + GstBus *bus; + GMainLoop *loop; + guint i; + guint bus_watch = 0; + + audiotestsrc = g_new0 (GstElement *, channels); + + pipeline = gst_pipeline_new ("pipeline"); + fail_unless (pipeline != NULL); + + interleave = gst_element_factory_make ("interleave", NULL); + fail_unless (interleave != NULL); + g_object_set (interleave, "channel-positions", arr, NULL); + gst_bin_add (GST_BIN (pipeline), interleave); + + if (G_BYTE_ORDER == G_BIG_ENDIAN) { + /* we're not here to test orc; audioconvert misbehaves on ppc32 */ + g_setenv ("ORC_CODE", "backup", 1); + conv = gst_element_factory_make ("audioconvert", NULL); + } else { + conv = gst_element_factory_make ("identity", NULL); + } + fail_unless (conv != NULL); + gst_bin_add (GST_BIN (pipeline), conv); + fail_unless (gst_element_link (interleave, conv)); + + wavenc = gst_element_factory_make ("wavenc", NULL); + fail_unless (wavenc != NULL); + gst_bin_add (GST_BIN (pipeline), wavenc); + fail_unless (gst_element_link (conv, wavenc)); + + fakesink = gst_element_factory_make ("fakesink", NULL); + fail_unless (fakesink != NULL); + gst_bin_add (GST_BIN (pipeline), fakesink); + fail_unless (gst_element_link (wavenc, fakesink)); + + for (i = 0; i < channels; i++) { + audiotestsrc[i] = gst_element_factory_make ("audiotestsrc", NULL); + fail_unless (audiotestsrc[i] != NULL); + g_object_set (G_OBJECT (audiotestsrc[i]), "wave", 0, "freq", 440.0 * i, + "num-buffers", 100, NULL); + gst_bin_add (GST_BIN (pipeline), audiotestsrc[i]); + fail_unless (gst_element_link (audiotestsrc[i], interleave)); + } + + loop = g_main_loop_new (NULL, TRUE); + fail_unless (loop != NULL); + + bus = gst_element_get_bus (pipeline); + fail_unless (bus != NULL); + bus_watch = gst_bus_add_watch (bus, bus_handler, loop); + gst_object_unref (bus); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + g_main_loop_run (loop); + gst_element_set_state (pipeline, GST_STATE_NULL); + + gst_object_unref (pipeline); + g_free (audiotestsrc); + + g_main_loop_unref (loop); + g_source_remove (bus_watch); +} + +GST_START_TEST (test_encode_stereo) +{ + GValueArray *arr; + GValue val = { 0, }; + + arr = g_value_array_new (2); + g_value_init (&val, GST_TYPE_AUDIO_CHANNEL_POSITION); + g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT); + g_value_array_append (arr, &val); + g_value_reset (&val); + g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT); + g_value_array_append (arr, &val); + g_value_unset (&val); + + make_n_channel_wav (2, arr); + g_value_array_free (arr); +} + +GST_END_TEST; + +#if 0 +GST_START_TEST (test_encode_multichannel) +{ + GValueArray *arr; + GValue val = { 0, }; + + arr = g_value_array_new (6); + g_value_init (&val, GST_TYPE_AUDIO_CHANNEL_POSITION); + g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT); + g_value_array_append (arr, &val); + g_value_reset (&val); + g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT); + g_value_array_append (arr, &val); + g_value_reset (&val); + g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER); + g_value_array_append (arr, &val); + g_value_reset (&val); + g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_LFE); + g_value_array_append (arr, &val); + g_value_reset (&val); + g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT); + g_value_array_append (arr, &val); + g_value_reset (&val); + g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT); + g_value_array_append (arr, &val); + g_value_unset (&val); + + make_n_channel_wav (6); +} + +GST_END_TEST; +#endif + +static Suite * +wavenc_suite (void) +{ + Suite *s = suite_create ("wavenc"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_encode_stereo); + /* FIXME: improve wavenc + tcase_add_test (tc_chain, test_encode_multichannel); + */ + + return s; +} + +GST_CHECK_MAIN (wavenc); diff --git a/tests/check/pipelines/wavpack.c b/tests/check/pipelines/wavpack.c new file mode 100644 index 0000000..6a166b2 --- /dev/null +++ b/tests/check/pipelines/wavpack.c @@ -0,0 +1,217 @@ +/* GStreamer + * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org> + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gst/check/gstcheck.h> +#include <gst/base/gstadapter.h> + +static gboolean +bus_handler (GstBus * bus, GstMessage * message, gpointer data) +{ + GMainLoop *loop = (GMainLoop *) data; + + switch (message->type) { + case GST_MESSAGE_EOS: + g_main_loop_quit (loop); + break; + case GST_MESSAGE_WARNING: + case GST_MESSAGE_ERROR:{ + GError *gerror; + gchar *debug; + + gst_message_parse_error (message, &gerror, &debug); + gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); + gst_message_unref (message); + g_error_free (gerror); + g_free (debug); + g_main_loop_quit (loop); + break; + } + case GST_MESSAGE_ELEMENT: + { + const GstStructure *s = gst_message_get_structure (message); + + const gchar *name = gst_structure_get_name (s); + + fail_unless (strcmp (name, "imperfect-timestamp") != 0); + fail_unless (strcmp (name, "imperfect-offset") != 0); + break; + } + default: + break; + } + + return TRUE; +} + +static gboolean had_first_buffer = FALSE; + +static void +identity_handoff (GstElement * object, GstBuffer * buffer, gpointer user_data) +{ + GstAdapter *adapter = GST_ADAPTER (user_data); + + gst_adapter_push (adapter, gst_buffer_ref (buffer)); +} + +static void +fakesink_handoff (GstElement * object, GstBuffer * buffer, GstPad * pad, + gpointer user_data) +{ + GstAdapter *adapter = GST_ADAPTER (user_data); + + /* Don't allow the second buffer with offset=0 as it's the decoded + * rewrite of the first + */ + if (had_first_buffer == FALSE && GST_BUFFER_OFFSET (buffer) == 0) + had_first_buffer = TRUE; + else if (GST_BUFFER_OFFSET (buffer) == 0) + return; + + gst_adapter_push (adapter, gst_buffer_ref (buffer)); +} + +GST_START_TEST (test_encode_decode) +{ + GstElement *pipeline; + GstElement *audiotestsrc, *identity1, *wavpackenc, *identity2, *wavpackdec, + *identity3, *fakesink; + GstAdapter *srcadapter, *sinkadapter; + GstBus *bus; + GMainLoop *loop; + GstBuffer *in, *out; + guint bus_watch = 0; + + srcadapter = gst_adapter_new (); + fail_unless (srcadapter != NULL); + sinkadapter = gst_adapter_new (); + fail_unless (sinkadapter != NULL); + + pipeline = gst_pipeline_new ("pipeline"); + fail_unless (pipeline != NULL); + + audiotestsrc = gst_element_factory_make ("audiotestsrc", "src"); + fail_unless (audiotestsrc != NULL); + g_object_set (G_OBJECT (audiotestsrc), "wave", 0, "freq", 440.0, + "num-buffers", 2000, NULL); + + identity1 = gst_element_factory_make ("identity", "identity1"); + fail_unless (identity1 != NULL); + g_object_set (G_OBJECT (identity1), "signal-handoffs", TRUE, NULL); + g_signal_connect (G_OBJECT (identity1), "handoff", + G_CALLBACK (identity_handoff), srcadapter); + + wavpackenc = gst_element_factory_make ("wavpackenc", "enc"); + fail_unless (wavpackenc != NULL); + + identity2 = gst_element_factory_make ("identity", "identity2"); + fail_unless (identity2 != NULL); + g_object_set (G_OBJECT (identity2), "check-imperfect-timestamp", TRUE, + "check-imperfect-offset", TRUE, NULL); + + wavpackdec = gst_element_factory_make ("wavpackdec", "dec"); + fail_unless (wavpackdec != NULL); + + identity3 = gst_element_factory_make ("identity", "identity3"); + fail_unless (identity3 != NULL); + g_object_set (G_OBJECT (identity3), "check-imperfect-timestamp", TRUE, + "check-imperfect-offset", TRUE, NULL); + + fakesink = gst_element_factory_make ("fakesink", "sink"); + fail_unless (fakesink != NULL); + g_object_set (G_OBJECT (fakesink), "signal-handoffs", TRUE, NULL); + g_signal_connect (G_OBJECT (fakesink), "handoff", + G_CALLBACK (fakesink_handoff), sinkadapter); + + gst_bin_add_many (GST_BIN (pipeline), audiotestsrc, identity1, wavpackenc, + identity2, wavpackdec, identity3, fakesink, NULL); + + fail_unless (gst_element_link_many (audiotestsrc, identity1, wavpackenc, + identity2, wavpackdec, identity3, fakesink, NULL)); + + loop = g_main_loop_new (NULL, TRUE); + fail_unless (loop != NULL); + + bus = gst_element_get_bus (pipeline); + fail_unless (bus != NULL); + bus_watch = gst_bus_add_watch (bus, bus_handler, loop); + gst_object_unref (bus); + + had_first_buffer = FALSE; + gst_element_set_state (pipeline, GST_STATE_PLAYING); + g_main_loop_run (loop); + gst_element_set_state (pipeline, GST_STATE_NULL); + + fail_unless (had_first_buffer == TRUE); + fail_unless (gst_adapter_available (srcadapter) > 0); + fail_unless (gst_adapter_available (sinkadapter) > 0); + fail_unless_equals_int (gst_adapter_available (srcadapter), + gst_adapter_available (sinkadapter)); + + in = gst_adapter_take_buffer (srcadapter, gst_adapter_available (srcadapter)); + fail_unless (in != NULL); + out = + gst_adapter_take_buffer (sinkadapter, + gst_adapter_available (sinkadapter)); + fail_unless (out != NULL); + + fail_unless_equals_int (GST_BUFFER_SIZE (in), GST_BUFFER_SIZE (out)); + fail_unless (memcmp (GST_BUFFER_DATA (in), GST_BUFFER_DATA (out), + GST_BUFFER_SIZE (in)) == 0); + + gst_buffer_unref (in); + gst_buffer_unref (out); + g_object_unref (pipeline); + g_main_loop_unref (loop); + g_object_unref (srcadapter); + g_object_unref (sinkadapter); + g_source_remove (bus_watch); +} + +GST_END_TEST; + +static Suite * +wavpack_suite (void) +{ + Suite *s = suite_create ("Wavpack"); + TCase *tc_chain = tcase_create ("linear"); + + /* time out after 60s, not the default 3 */ + tcase_set_timeout (tc_chain, 60); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_encode_decode); + + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + Suite *s = wavpack_suite (); + SRunner *sr = srunner_create (s); + + gst_check_init (&argc, &argv); + + srunner_run_all (sr, CK_NORMAL); + nf = srunner_ntests_failed (sr); + srunner_free (sr); + + return nf; +} |