summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <edward.hervey@collabora.co.uk>2011-02-02 18:10:52 +0100
committerEdward Hervey <bilboed@bilboed.com>2011-02-09 11:02:03 +0100
commit2422274c652ff2947af895872fe6f7cfad8fc424 (patch)
tree42c91233dd8c2e3eff6462fb9df0640175311f9b
parent1c91a255a57653b5964469c786ff4094818292fd (diff)
tests: First go at testing seeking
Still needs more checks though
-rw-r--r--tests/check/Makefile.am3
-rw-r--r--tests/check/gnl/seek.c504
2 files changed, 506 insertions, 1 deletions
diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am
index eda5386..44cd53f 100644
--- a/tests/check/Makefile.am
+++ b/tests/check/Makefile.am
@@ -24,7 +24,8 @@ check_PROGRAMS = \
gnl/complex \
gnl/gnlsource \
gnl/gnloperation \
- gnl/gnlcomposition
+ gnl/gnlcomposition \
+ gnl/seek
noinst_HEADERS = \
gnl/common.h
diff --git a/tests/check/gnl/seek.c b/tests/check/gnl/seek.c
new file mode 100644
index 0000000..921c08b
--- /dev/null
+++ b/tests/check/gnl/seek.c
@@ -0,0 +1,504 @@
+#include "common.h"
+
+typedef struct _SeekInfo
+{
+ GstClockTime position; /* Seek value and segment position */
+ GstClockTime start; /* Segment start */
+ GstClockTime stop; /* Segment stop */
+ gboolean expect_failure; /* Whether we expect the seek to fail or not */
+} SeekInfo;
+
+static SeekInfo *
+new_seek_info (GstClockTime position, GstClockTime start, GstClockTime stop,
+ gboolean expect_failure)
+{
+ SeekInfo *info = g_new0 (SeekInfo, 1);
+
+ info->position = position;
+ info->start = start;
+ info->stop = stop;
+ info->expect_failure = expect_failure;
+
+ return info;
+}
+
+static void
+fill_pipeline_and_check (GstElement * comp, GList * segments, GList * seeks)
+{
+ GstElement *pipeline, *sink;
+ CollectStructure *collect;
+ GstBus *bus;
+ GstMessage *message;
+ gboolean carry_on = TRUE;
+ gboolean have_seeked = FALSE;
+ GstPad *sinkpad;
+ GList *ltofree = seeks;
+
+ pipeline = gst_pipeline_new ("test_pipeline");
+ sink = gst_element_factory_make_or_warn ("fakesink", "sink");
+ fail_if (sink == NULL);
+
+ gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL);
+
+ /* Shared data */
+ collect = g_new0 (CollectStructure, 1);
+ collect->comp = comp;
+ collect->sink = sink;
+
+ /* Expected segments */
+ collect->expected_segments = segments;
+
+ g_signal_connect (G_OBJECT (comp), "pad-added",
+ G_CALLBACK (composition_pad_added_cb), collect);
+
+ sinkpad = gst_element_get_pad (sink, "sink");
+ gst_pad_add_event_probe (sinkpad, G_CALLBACK (sinkpad_event_probe), collect);
+ gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (sinkpad_buffer_probe),
+ collect);
+
+ bus = gst_element_get_bus (GST_ELEMENT (pipeline));
+
+ GST_DEBUG ("Setting pipeline to PLAYING");
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE);
+
+ GST_DEBUG ("Let's poll the bus");
+
+ while (carry_on) {
+ message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10);
+ if (message) {
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_EOS:
+ /* we should check if we really finished here */
+ GST_WARNING ("Got an EOS");
+ carry_on = FALSE;
+ break;
+ case GST_MESSAGE_SEGMENT_START:
+ case GST_MESSAGE_SEGMENT_DONE:
+ /* We shouldn't see any segement messages, since we didn't do a segment seek */
+ GST_WARNING ("Saw a Segment start/stop");
+ fail_if (TRUE);
+ break;
+ case GST_MESSAGE_ERROR:
+ GST_WARNING ("Saw an ERROR");
+ fail_if (TRUE);
+ break;
+ case GST_MESSAGE_ASYNC_DONE:
+ GST_DEBUG ("prerolling done");
+ if (seeks == NULL) {
+ carry_on = FALSE;
+ break;
+ }
+ while (seeks) {
+ SeekInfo *sinfo = (SeekInfo *) seeks->data;
+
+ seeks = seeks->next;
+
+ if (!sinfo->expect_failure)
+ collect->expected_segments =
+ g_list_append (collect->expected_segments, segment_new (1.0,
+ GST_FORMAT_TIME, sinfo->start, sinfo->stop,
+ sinfo->position));
+
+ /* Seek to 0.5s */
+ GST_DEBUG ("Seeking to %" GST_TIME_FORMAT ", Expecting (%"
+ GST_TIME_FORMAT " %" GST_TIME_FORMAT ")",
+ GST_TIME_ARGS (sinfo->position), GST_TIME_ARGS (sinfo->start),
+ GST_TIME_ARGS (sinfo->stop));
+ fail_unless_equals_int (gst_element_seek_simple (pipeline,
+ GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, sinfo->position),
+ !sinfo->expect_failure);
+ if (!sinfo->expect_failure) {
+ g_free (sinfo);
+ break;
+ }
+ GST_DEBUG ("Seek failed as expected");
+ if (seeks == NULL)
+ carry_on = FALSE;
+ g_free (sinfo);
+ }
+ break;
+ default:
+ break;
+ }
+ gst_mini_object_unref (GST_MINI_OBJECT (message));
+ }
+ }
+
+ GST_DEBUG ("Setting pipeline to READY");
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
+
+ fail_if (collect->expected_segments != NULL);
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE);
+
+ ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "main pipeline", 1, 2);
+ gst_object_unref (pipeline);
+ ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2);
+ gst_object_unref (bus);
+
+ g_list_free (ltofree);
+ g_free (collect);
+}
+
+static void
+test_simplest_full ()
+{
+ GstElement *comp, *source1;
+ guint64 start, stop;
+ gint64 duration;
+ GList *segments = NULL;
+ GList *seeks = NULL;
+
+ comp =
+ gst_element_factory_make_or_warn ("gnlcomposition", "test_composition");
+ fail_if (comp == NULL);
+
+ /*
+ Source 1
+ Start : 0s
+ Duration : 1s
+ Media start : 5s
+ Media Duartion : 1s
+ Priority : 1
+ */
+ source1 =
+ videotest_gnl_src_full ("source1", 0, 1 * GST_SECOND, 5 * GST_SECOND,
+ 1 * GST_SECOND, 3, 1);
+ fail_if (source1 == NULL);
+ check_start_stop_duration (source1, 0, 1 * GST_SECOND, 1 * GST_SECOND);
+
+ /* Add one source */
+
+ gst_bin_add (GST_BIN (comp), source1);
+ check_start_stop_duration (comp, 0, 1 * GST_SECOND, 1 * GST_SECOND);
+
+ ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
+
+ /* Expected segments */
+ segments = g_list_append (segments,
+ segment_new (1.0, GST_FORMAT_TIME, 5 * GST_SECOND, 6 * GST_SECOND, 0));
+
+ seeks =
+ g_list_append (seeks, new_seek_info (0.5 * GST_SECOND, 5.5 * GST_SECOND,
+ 6 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (0 * GST_SECOND, 5 * GST_SECOND,
+ 6 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (GST_SECOND - 1, 6 * GST_SECOND - 1,
+ 6 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (GST_SECOND, 6 * GST_SECOND,
+ 6 * GST_SECOND, TRUE));
+ seeks =
+ g_list_append (seeks, new_seek_info (0.5 * GST_SECOND, 5.5 * GST_SECOND,
+ 6 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (0 * GST_SECOND, 5 * GST_SECOND,
+ 6 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (GST_SECOND - 1, 6 * GST_SECOND - 1,
+ 6 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (GST_SECOND, 6 * GST_SECOND,
+ 6 * GST_SECOND, TRUE));
+
+ fill_pipeline_and_check (comp, segments, seeks);
+}
+
+static void
+test_one_after_other_full ()
+{
+ GstElement *comp, *source1, *source2;
+ guint64 start, stop;
+ gint64 duration;
+ GList *segments = NULL, *seeks = NULL;
+
+ comp =
+ gst_element_factory_make_or_warn ("gnlcomposition", "test_composition");
+ fail_if (comp == NULL);
+
+ /* TOPOLOGY
+ *
+ * 0 1 2 3 4 5 | Priority
+ * ----------------------------------------------------------------------------
+ * [5 source1 ][2 source2 ] | 1
+ *
+ * */
+
+ /*
+ Source 1
+ Start : 0s
+ Duration : 1s
+ Media start : 5s
+ Media Duartion : 1s
+ Priority : 1
+ */
+ source1 =
+ videotest_gnl_src_full ("source1", 0, 1 * GST_SECOND, 5 * GST_SECOND,
+ 1 * GST_SECOND, 3, 1);
+ fail_if (source1 == NULL);
+ check_start_stop_duration (source1, 0, 1 * GST_SECOND, 1 * GST_SECOND);
+
+ /*
+ Source 2
+ Start : 1s
+ Duration : 1s
+ Media start : 2s
+ Media Duration : 1s
+ Priority : 1
+ */
+ source2 = videotest_gnl_src_full ("source2", 1 * GST_SECOND, 1 * GST_SECOND,
+ 2 * GST_SECOND, 1 * GST_SECOND, 2, 1);
+ fail_if (source2 == NULL);
+ check_start_stop_duration (source2, 1 * GST_SECOND, 2 * GST_SECOND,
+ 1 * GST_SECOND);
+
+ /* Add sources */
+ gst_bin_add (GST_BIN (comp), source1);
+ gst_bin_add (GST_BIN (comp), source2);
+ check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND);
+
+ ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
+ ASSERT_OBJECT_REFCOUNT (source2, "source2", 1);
+
+
+ /* Expected segments */
+ segments = g_list_append (segments,
+ segment_new (1.0, GST_FORMAT_TIME, 5 * GST_SECOND, 6 * GST_SECOND, 0));
+
+ seeks =
+ g_list_append (seeks, new_seek_info (0.5 * GST_SECOND, 5.5 * GST_SECOND,
+ 6 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (0 * GST_SECOND, 5 * GST_SECOND,
+ 6 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (GST_SECOND - 1, 6 * GST_SECOND - 1,
+ 6 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (GST_SECOND, 2 * GST_SECOND,
+ 3 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (2 * GST_SECOND - 1,
+ 3 * GST_SECOND - 1, 3 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (2 * GST_SECOND, 3 * GST_SECOND,
+ 3 * GST_SECOND, TRUE));
+
+
+ fill_pipeline_and_check (comp, segments, seeks);
+}
+
+static void
+test_one_under_another_full ()
+{
+ GstElement *comp, *source1, *source2;
+ guint64 start, stop;
+ gint64 duration;
+ GList *segments = NULL, *seeks = NULL;
+
+ comp =
+ gst_element_factory_make_or_warn ("gnlcomposition", "test_composition");
+ fail_if (comp == NULL);
+
+ /* TOPOLOGY
+ *
+ * 0 1 2 3 4 5 | Priority
+ * ----------------------------------------------------------------------------
+ * [ source1 ] | 1
+ * [ source2 ] | 2
+ *
+ * */
+
+ /*
+ Source 1
+ Start : 0s
+ Duration : 2s
+ Priority : 1
+ */
+ source1 = videotest_gnl_src ("source1", 0, 2 * GST_SECOND, 3, 1);
+ fail_if (source1 == NULL);
+ check_start_stop_duration (source1, 0, 2 * GST_SECOND, 2 * GST_SECOND);
+
+ /*
+ Source 2
+ Start : 1s
+ Duration : 2s
+ Priority : 2
+ */
+ source2 = videotest_gnl_src ("source2", 1 * GST_SECOND, 2 * GST_SECOND, 2, 2);
+ fail_if (source2 == NULL);
+ check_start_stop_duration (source2, 1 * GST_SECOND, 3 * GST_SECOND,
+ 2 * GST_SECOND);
+
+ /* Add two sources */
+
+ gst_bin_add (GST_BIN (comp), source1);
+ gst_bin_add (GST_BIN (comp), source2);
+ check_start_stop_duration (comp, 0, 3 * GST_SECOND, 3 * GST_SECOND);
+
+ /* Expected segments */
+ segments = g_list_append (segments,
+ segment_new (1.0, GST_FORMAT_TIME, 0, GST_SECOND, 0));
+
+
+ /* Hit source1 */
+ seeks =
+ g_list_append (seeks, new_seek_info (0.5 * GST_SECOND, 0.5 * GST_SECOND,
+ 1 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (0 * GST_SECOND, 0 * GST_SECOND,
+ 1 * GST_SECOND, FALSE));
+ /* Hit source1 over source2 */
+ seeks =
+ g_list_append (seeks, new_seek_info (1 * GST_SECOND, 1 * GST_SECOND,
+ 2 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (1.5 * GST_SECOND, 1.5 * GST_SECOND,
+ 2 * GST_SECOND, FALSE));
+ /* Hit source2 */
+ seeks =
+ g_list_append (seeks, new_seek_info (2 * GST_SECOND, 2 * GST_SECOND,
+ 3 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (2.5 * GST_SECOND, 2.5 * GST_SECOND,
+ 3 * GST_SECOND, FALSE));
+
+ fill_pipeline_and_check (comp, segments, seeks);
+}
+
+static void
+test_one_bin_after_other_full ()
+{
+ GstElement *comp, *source1, *source2;
+ guint64 start, stop;
+ gint64 duration;
+ GList *segments = NULL, *seeks = NULL;
+
+ comp =
+ gst_element_factory_make_or_warn ("gnlcomposition", "test_composition");
+ fail_if (comp == NULL);
+
+ /*
+ Source 1
+ Start : 0s
+ Duration : 1s
+ Priority : 1
+ */
+ source1 = videotest_in_bin_gnl_src ("source1", 0, 1 * GST_SECOND, 3, 1);
+ fail_if (source1 == NULL);
+ check_start_stop_duration (source1, 0, 1 * GST_SECOND, 1 * GST_SECOND);
+
+ /*
+ Source 2
+ Start : 1s
+ Duration : 1s
+ Priority : 1
+ */
+ source2 =
+ videotest_in_bin_gnl_src ("source2", 1 * GST_SECOND, 1 * GST_SECOND, 2,
+ 1);
+ fail_if (source2 == NULL);
+ check_start_stop_duration (source2, 1 * GST_SECOND, 2 * GST_SECOND,
+ 1 * GST_SECOND);
+
+ /* Add one source */
+
+ gst_bin_add (GST_BIN (comp), source1);
+ check_start_stop_duration (comp, 0, 1 * GST_SECOND, 1 * GST_SECOND);
+
+ ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
+
+ /* Second source */
+
+ gst_bin_add (GST_BIN (comp), source2);
+ check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND);
+
+ ASSERT_OBJECT_REFCOUNT (source2, "source2", 1);
+
+ /* Expected segments */
+ segments = g_list_append (segments,
+ segment_new (1.0, GST_FORMAT_TIME, 0, 1 * GST_SECOND, 0));
+
+ /* Hit source1 */
+ seeks =
+ g_list_append (seeks, new_seek_info (0.5 * GST_SECOND, 0.5 * GST_SECOND,
+ GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (0 * GST_SECOND, 0 * GST_SECOND,
+ GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (GST_SECOND - 1, GST_SECOND - 1,
+ GST_SECOND, FALSE));
+ /* Hit source2 */
+ seeks =
+ g_list_append (seeks, new_seek_info (1.5 * GST_SECOND, 1.5 * GST_SECOND,
+ 2 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (GST_SECOND, GST_SECOND,
+ 2 * GST_SECOND, FALSE));
+ seeks =
+ g_list_append (seeks, new_seek_info (2 * GST_SECOND - 1,
+ 2 * GST_SECOND - 1, 2 * GST_SECOND, FALSE));
+ /* Should fail */
+ seeks =
+ g_list_append (seeks, new_seek_info (2 * GST_SECOND, GST_SECOND,
+ GST_SECOND, TRUE));
+
+ fill_pipeline_and_check (comp, segments, seeks);
+}
+
+GST_START_TEST (test_simplest)
+{
+ test_simplest_full ();
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_one_after_other)
+{
+ test_one_after_other_full ();
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_one_under_another)
+{
+ test_one_under_another_full ();
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_one_bin_after_other)
+{
+ test_one_bin_after_other_full ();
+}
+
+GST_END_TEST;
+
+
+Suite *
+gnonlin_suite (void)
+{
+ Suite *s = suite_create ("gnonlin-seek");
+ TCase *tc_chain = tcase_create ("general");
+
+ suite_add_tcase (s, tc_chain);
+
+ tcase_add_test (tc_chain, test_simplest);
+ tcase_add_test (tc_chain, test_one_after_other);
+ tcase_add_test (tc_chain, test_one_under_another);
+ tcase_add_test (tc_chain, test_one_bin_after_other);
+ return s;
+}
+
+GST_CHECK_MAIN (gnonlin)