summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnl/gnlcomposition.c65
-rw-r--r--tests/check/complex.c245
-rw-r--r--tests/check/gnloperation.c219
3 files changed, 507 insertions, 22 deletions
diff --git a/gnl/gnlcomposition.c b/gnl/gnlcomposition.c
index 4c34eaf..cf2b4c0 100644
--- a/gnl/gnlcomposition.c
+++ b/gnl/gnlcomposition.c
@@ -96,7 +96,8 @@ struct _GnlCompositionPrivate
/* current stack, list of GnlObject* */
GNode *current;
- GnlObject *defaultobject;
+ /* List of GnlObject whose start/duration will be the same as the composition */
+ GList *expandables;
/* TRUE if the stack is valid.
* This is meant to prevent the top-level pad to be unblocked before the stack
@@ -328,8 +329,6 @@ gnl_composition_init (GnlComposition * comp,
comp->private->waitingpads = 0;
- comp->private->defaultobject = NULL;
-
comp->private->objects_hash = g_hash_table_new_full
(g_direct_hash,
g_direct_equal, NULL, (GDestroyNotify) hash_value_destroy);
@@ -366,6 +365,11 @@ gnl_composition_dispose (GObject * object)
comp->private->current = NULL;
}
+ if (comp->private->expandables) {
+ g_list_free (comp->private->expandables);
+ comp->private->expandables = NULL;
+ }
+
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -917,7 +921,7 @@ handle_seek_event (GnlComposition * comp, GstEvent * event)
/* crop the segment start/stop values */
/* Only crop segment start value if we don't have a default object */
- if (comp->private->defaultobject == NULL)
+ if (comp->private->expandables == NULL)
comp->private->segment->start = MAX (comp->private->segment->start,
((GnlObject *) comp)->start);
comp->private->segment->stop = MIN (comp->private->segment->stop,
@@ -1262,9 +1266,14 @@ get_stack_list (GnlComposition * comp, GstClockTime timestamp,
}
}
- /* append the default source if we have one */
- if ((timestamp < ((GnlObject *) comp)->stop) && comp->private->defaultobject)
- stack = g_list_append (stack, comp->private->defaultobject);
+ /* Insert the expandables */
+ if (G_LIKELY (timestamp < ((GnlObject *) comp)->stop))
+ for (tmp = comp->private->expandables; tmp; tmp = g_list_next (tmp)) {
+ GST_DEBUG_OBJECT (comp, "Adding expandable %s sorted to the list",
+ GST_OBJECT_NAME (tmp->data));
+ stack = g_list_insert_sorted (stack, tmp->data,
+ (GCompareFunc) priority_comp);
+ }
/* convert that list to a stack */
tmp = stack;
@@ -1529,7 +1538,7 @@ update_start_stop_duration (GnlComposition * comp)
}
/* If we have a default object, the start position is 0 */
- if (comp->private->defaultobject) {
+ if (comp->private->expandables) {
GST_LOG_OBJECT (cobj,
"Setting start to 0 because we have a default object");
if (cobj->start != 0) {
@@ -1551,10 +1560,13 @@ update_start_stop_duration (GnlComposition * comp)
if (obj->stop != cobj->stop) {
GST_LOG_OBJECT (obj, "setting stop from %s to %" GST_TIME_FORMAT,
GST_OBJECT_NAME (obj), GST_TIME_ARGS (obj->stop));
- if (comp->private->defaultobject) {
- g_object_set (comp->private->defaultobject, "duration", obj->stop, NULL);
- g_object_set (comp->private->defaultobject, "media-duration", obj->stop,
- NULL);
+ if (comp->private->expandables) {
+ GList *tmp = comp->private->expandables;
+ while (tmp) {
+ g_object_set (tmp->data, "duration", obj->stop, NULL);
+ g_object_set (tmp->data, "media-duration", obj->stop, NULL);
+ tmp = g_list_next (tmp);
+ }
}
comp->private->segment->stop = obj->stop;
cobj->stop = obj->stop;
@@ -1730,7 +1742,8 @@ compare_relink_single_node (GnlComposition * comp, GNode * node,
guint nbchilds = g_node_n_children (node);
GnlOperation *oper = (GnlOperation *) newobj;
- GST_LOG_OBJECT (newobj, "is operation, analyzing the %d childs", nbchilds);
+ GST_LOG_OBJECT (newobj, "is a %s operation, analyzing the %d childs",
+ oper->dynamicsinks ? "dynamic" : "regular", nbchilds);
if (oper->dynamicsinks)
g_object_set (G_OBJECT (newobj), "sinks", nbchilds, NULL);
for (child = node->children; child; child = child->next)
@@ -2330,10 +2343,11 @@ gnl_composition_add_object (GstBin * bin, GstElement * element)
COMP_OBJECTS_LOCK (comp);
- if ((((GnlObject *) element)->priority == G_MAXUINT32)
- && comp->private->defaultobject) {
+ if (((((GnlObject *) element)->priority == G_MAXUINT32) ||
+ GNL_OBJECT_IS_EXPANDABLE (element)) &&
+ g_list_find (comp->private->expandables, element)) {
GST_WARNING_OBJECT (comp,
- "We already have a default source, remove it before adding new one");
+ "We already have an expandable, remove it before adding new one");
ret = FALSE;
goto chiringuito;
}
@@ -2352,7 +2366,8 @@ gnl_composition_add_object (GstBin * bin, GstElement * element)
/* wrap new element in a GnlCompositionEntry ... */
entry = g_new0 (GnlCompositionEntry, 1);
entry->object = (GnlObject *) element;
- if ((((GnlObject *) element)->priority != G_MAXUINT32)) {
+ if (G_LIKELY ((((GnlObject *) element)->priority != G_MAXUINT32) &&
+ !GNL_OBJECT_IS_EXPANDABLE (element))) {
/* Only react on non-default objects properties */
entry->starthandler = g_signal_connect (G_OBJECT (element),
"notify::start", G_CALLBACK (object_start_stop_priority_changed), comp);
@@ -2380,9 +2395,11 @@ gnl_composition_add_object (GstBin * bin, GstElement * element)
g_hash_table_insert (comp->private->objects_hash, element, entry);
/* Special case for default source. */
- if (((GnlObject *) element)->priority == G_MAXUINT32) {
+ if ((((GnlObject *) element)->priority == G_MAXUINT32) ||
+ GNL_OBJECT_IS_EXPANDABLE (element)) {
/* It doesn't get added to objects_start and objects_stop. */
- comp->private->defaultobject = ((GnlObject *) element);
+ comp->private->expandables = g_list_prepend (comp->private->expandables,
+ element);
goto chiringuito;
}
@@ -2470,8 +2487,11 @@ gnl_composition_remove_object (GstBin * bin, GstElement * element)
gst_element_set_locked_state (element, FALSE);
/* handle default source */
- if (((GnlObject *) element)->priority == G_MAXUINT32) {
- comp->private->defaultobject = NULL;
+ if ((((GnlObject *) element)->priority == G_MAXUINT32) ||
+ GNL_OBJECT_IS_EXPANDABLE (element)) {
+ /* Find it in the list */
+ comp->private->expandables =
+ g_list_remove (comp->private->expandables, element);
} else {
/* remove it from the objects list and resort the lists */
comp->private->objects_start = g_list_remove
@@ -2487,7 +2507,8 @@ gnl_composition_remove_object (GstBin * bin, GstElement * element)
goto chiringuito;
update_required = OBJECT_IN_ACTIVE_SEGMENT (comp, element) ||
- ((GnlObject *) element)->priority == G_MAXUINT32;
+ (((GnlObject *) element)->priority == G_MAXUINT32) ||
+ GNL_OBJECT_IS_EXPANDABLE (element);
if (update_required && comp->private->can_update) {
curpos = get_current_position (comp);
diff --git a/tests/check/complex.c b/tests/check/complex.c
index 06eca9e..ae9db2a 100644
--- a/tests/check/complex.c
+++ b/tests/check/complex.c
@@ -442,6 +442,250 @@ GST_START_TEST (test_one_default_another)
GST_END_TEST;
+GST_START_TEST (test_one_expandable_another)
+{
+ GstElement *pipeline;
+ GstElement *comp, *sink, *source1, *source2, *source3, *defaultsrc;
+ CollectStructure *collect;
+ GstBus *bus;
+ GstMessage *message;
+ gboolean carry_on = TRUE;
+ guint64 start, stop;
+ gint64 duration;
+ GstPad *sinkpad;
+
+ pipeline = gst_pipeline_new ("test_pipeline");
+ comp =
+ gst_element_factory_make_or_warn ("gnlcomposition", "test_composition");
+ fail_if (comp == NULL);
+
+ /*
+ defaultsrc source
+ Start : 0s
+ Duration : 5s
+ Priority : 1000
+ */
+
+ defaultsrc = videotest_gnl_src ("defaultsrc", 0, 5 * GST_SECOND, 2, 1000);
+ g_object_set (defaultsrc, "expandable", TRUE, NULL);
+ fail_if (defaultsrc == NULL);
+ check_start_stop_duration (defaultsrc, 0, 5 * GST_SECOND, 5 * GST_SECOND);
+
+ /*
+ Source 1
+ Start : 1s
+ Duration : 1s
+ Priority : 1
+ */
+ source1 = videotest_gnl_src ("source1", 1 * GST_SECOND, 1 * GST_SECOND, 1, 1);
+ fail_if (source1 == NULL);
+ check_start_stop_duration (source1, GST_SECOND, 2 * GST_SECOND,
+ 1 * GST_SECOND);
+
+ /*
+ Source 2
+ Start : 3s
+ Duration : 1s
+ Priority : 1
+ */
+ source2 = videotest_gnl_src ("source2", 3 * GST_SECOND, 1 * GST_SECOND, 2, 1);
+ fail_if (source2 == NULL);
+ check_start_stop_duration (source2, 3 * GST_SECOND, 4 * GST_SECOND,
+ 1 * GST_SECOND);
+
+ /*
+ Source 3
+ Start : 4s
+ Duration : 1s
+ Priority : 1
+ */
+ source3 = videotest_gnl_src ("source3", 4 * GST_SECOND, 1 * GST_SECOND, 2, 1);
+ fail_if (source3 == NULL);
+ check_start_stop_duration (source3, 4 * GST_SECOND, 5 * GST_SECOND,
+ 1 * GST_SECOND);
+
+
+ /* Add one source */
+
+ gst_bin_add (GST_BIN (comp), source1);
+ check_start_stop_duration (comp, GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND);
+
+ ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
+
+ /* defaultsrc source */
+
+ gst_bin_add (GST_BIN (comp), defaultsrc);
+ check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND);
+ check_start_stop_duration (defaultsrc, 0, 2 * GST_SECOND, 2 * GST_SECOND);
+
+ ASSERT_OBJECT_REFCOUNT (defaultsrc, "defaultsrc", 1);
+
+ /* Second source */
+
+ gst_bin_add (GST_BIN (comp), source2);
+ check_start_stop_duration (comp, 0, 4 * GST_SECOND, 4 * GST_SECOND);
+ check_start_stop_duration (defaultsrc, 0, 4 * GST_SECOND, 4 * GST_SECOND);
+
+ ASSERT_OBJECT_REFCOUNT (source2, "source2", 1);
+
+
+ /* Third source */
+
+ gst_bin_add (GST_BIN (comp), source3);
+ check_start_stop_duration (comp, 0, 5 * GST_SECOND, 5 * GST_SECOND);
+ check_start_stop_duration (defaultsrc, 0, 5 * GST_SECOND, 5 * GST_SECOND);
+
+ ASSERT_OBJECT_REFCOUNT (source3, "source3", 1);
+
+
+ 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 = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME, 0, 1 * GST_SECOND, 0));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 2 * GST_SECOND, 3 * GST_SECOND, 2 * GST_SECOND));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 3 * GST_SECOND, 4 * GST_SECOND, 3 * GST_SECOND));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 4 * GST_SECOND, 5 * GST_SECOND, 4 * GST_SECOND));
+
+ 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");
+ ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
+
+ GST_DEBUG ("Let's poll the bus");
+
+ while (carry_on) {
+ message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2);
+ 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);
+ default:
+ break;
+ }
+ gst_mini_object_unref (GST_MINI_OBJECT (message));
+ }
+ }
+
+ GST_DEBUG ("Setting pipeline to NULL");
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
+
+ fail_if (collect->expected_segments != NULL);
+
+ GST_DEBUG ("Resetted pipeline to READY");
+
+ /* Expected segments */
+ /* Expected segments */
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME, 0, 1 * GST_SECOND, 0));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 2 * GST_SECOND, 3 * GST_SECOND, 2 * GST_SECOND));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 3 * GST_SECOND, 4 * GST_SECOND, 3 * GST_SECOND));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 4 * GST_SECOND, 5 * GST_SECOND, 4 * GST_SECOND));
+ collect->gotsegment = FALSE;
+
+
+ GST_DEBUG ("Setting pipeline to PLAYING again");
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
+
+ carry_on = TRUE;
+
+ GST_DEBUG ("Let's poll the bus");
+
+ while (carry_on) {
+ message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2);
+ if (message) {
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_EOS:
+ /* we should check if we really finished here */
+ 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_ERROR ("Saw an ERROR");
+ fail_if (TRUE);
+ default:
+ break;
+ }
+ gst_mini_object_unref (GST_MINI_OBJECT (message));
+ } else {
+ GST_DEBUG ("bus_poll responded, but there wasn't any message...");
+ }
+ }
+
+ fail_if (collect->expected_segments != NULL);
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE);
+
+ gst_object_unref (GST_OBJECT (sinkpad));
+ 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_free (collect);
+}
+
+GST_END_TEST;
+
GST_START_TEST (test_renegotiation)
@@ -934,6 +1178,7 @@ gnonlin_suite (void)
tcase_add_test (tc_chain, test_one_space_another);
tcase_add_test (tc_chain, test_one_default_another);
+ tcase_add_test (tc_chain, test_one_expandable_another);
tcase_add_test (tc_chain, test_renegotiation);
tcase_add_test (tc_chain, test_one_bin_space_another);
tcase_add_test (tc_chain, test_one_above_another);
diff --git a/tests/check/gnloperation.c b/tests/check/gnloperation.c
index aa668f0..4e3b74f 100644
--- a/tests/check/gnloperation.c
+++ b/tests/check/gnloperation.c
@@ -655,6 +655,224 @@ GST_START_TEST (test_pyramid_operations2)
GST_END_TEST;
+GST_START_TEST (test_pyramid_operations_expandable)
+{
+ GstElement *pipeline;
+ guint64 start, stop;
+ gint64 duration;
+ GstElement *comp, *oper, *source1, *source2, *def, *sink;
+ CollectStructure *collect;
+ GstBus *bus;
+ GstMessage *message;
+ gboolean carry_on = TRUE;
+ GstPad *sinkpad;
+
+ pipeline = gst_pipeline_new ("test_pipeline");
+ comp =
+ gst_element_factory_make_or_warn ("gnlcomposition", "test_composition");
+
+ /*
+ source1
+ Start : 0s
+ Duration : 2s
+ Priority : 2
+ */
+
+ source1 = videotest_gnl_src ("source1", 0, 2 * GST_SECOND, 1, 2);
+ check_start_stop_duration (source1, 0, 2 * GST_SECOND, 2 * GST_SECOND);
+
+ /*
+ operation (expandable)
+ Start : XX
+ Duration : XX
+ Priority : 1
+ */
+
+ oper = new_operation ("oper", "identity", 1 * GST_SECOND, 4 * GST_SECOND, 1);
+ g_object_set (oper, "expandable", TRUE, NULL);
+ check_start_stop_duration (oper, 1 * GST_SECOND, 5 * GST_SECOND,
+ 4 * GST_SECOND);
+
+ /*
+ source2
+ Start : 4s
+ Duration : 2s
+ Priority : 2
+ */
+
+ source2 = videotest_gnl_src ("source2", 4 * GST_SECOND, 2 * GST_SECOND, 1, 2);
+ check_start_stop_duration (source2, 4 * GST_SECOND, 6 * GST_SECOND,
+ 2 * GST_SECOND);
+
+ /*
+ def (default source)
+ Priority = G_MAXUINT32
+ */
+ def =
+ videotest_gnl_src ("default", 0 * GST_SECOND, 0 * GST_SECOND, 1,
+ G_MAXUINT32);
+
+ ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
+ ASSERT_OBJECT_REFCOUNT (source2, "source2", 1);
+ ASSERT_OBJECT_REFCOUNT (oper, "oper", 1);
+ ASSERT_OBJECT_REFCOUNT (def, "default", 1);
+
+ /* Add source 1 */
+
+ gst_bin_add (GST_BIN (comp), source1);
+ check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND);
+
+ /* Add source 2 */
+
+ gst_bin_add (GST_BIN (comp), source2);
+ check_start_stop_duration (comp, 0, 6 * GST_SECOND, 6 * GST_SECOND);
+
+ /* Add operation */
+
+ gst_bin_add (GST_BIN (comp), oper);
+ check_start_stop_duration (comp, 0, 6 * GST_SECOND, 6 * GST_SECOND);
+
+ /* Add default */
+
+ gst_bin_add (GST_BIN (comp), def);
+ check_start_stop_duration (comp, 0, 6 * GST_SECOND, 6 * GST_SECOND);
+
+
+
+ sink = gst_element_factory_make_or_warn ("fakesink", "sink");
+ 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 = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME, 0, 2 * GST_SECOND, 0));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 2 * GST_SECOND, 4 * GST_SECOND, 2 * GST_SECOND));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 4 * GST_SECOND, 6 * GST_SECOND, 4 * GST_SECOND));
+
+ 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");
+ ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
+
+ GST_DEBUG ("Let's poll the bus");
+
+ while (carry_on) {
+ message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2);
+ 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);
+ default:
+ break;
+ }
+ gst_mini_object_unref (GST_MINI_OBJECT (message));
+ }
+ }
+
+ GST_DEBUG ("Setting pipeline to NULL");
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
+
+ fail_if (collect->expected_segments != NULL);
+
+ GST_DEBUG ("Resetted pipeline to READY");
+
+ /* Expected segments */
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME, 0, 2 * GST_SECOND, 0));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 2 * GST_SECOND, 4 * GST_SECOND, 2 * GST_SECOND));
+ collect->expected_segments = g_list_append (collect->expected_segments,
+ segment_new (1.0, GST_FORMAT_TIME,
+ 4 * GST_SECOND, 6 * GST_SECOND, 4 * GST_SECOND));
+
+ collect->gotsegment = FALSE;
+
+
+ GST_DEBUG ("Setting pipeline to PLAYING again");
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
+
+ carry_on = TRUE;
+
+ GST_DEBUG ("Let's poll the bus");
+
+ while (carry_on) {
+ message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2);
+ if (message) {
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_EOS:
+ /* we should check if we really finished here */
+ 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_ERROR ("Saw an ERROR");
+ fail_if (TRUE);
+ default:
+ break;
+ }
+ gst_mini_object_unref (GST_MINI_OBJECT (message));
+ } else {
+ GST_DEBUG ("bus_poll responded, but there wasn't any message...");
+ }
+ }
+
+ fail_if (collect->expected_segments != NULL);
+
+ fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
+ GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE);
+
+ gst_object_unref (GST_OBJECT (sinkpad));
+ 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_free (collect);
+}
+
+GST_END_TEST;
+
@@ -888,6 +1106,7 @@ gnonlin_suite (void)
tcase_add_test (tc_chain, test_simple_operation);
tcase_add_test (tc_chain, test_pyramid_operations);
tcase_add_test (tc_chain, test_pyramid_operations2);
+ tcase_add_test (tc_chain, test_pyramid_operations_expandable);
tcase_add_test (tc_chain, test_complex_operations);
return s;