From 03e488ac743e0fc5e5ed178aff130c68fe62b493 Mon Sep 17 00:00:00 2001 From: Brandon Lewis Date: Thu, 5 Aug 2010 15:21:57 +0200 Subject: [PATCH] add vaid property and unit tests --- ges/ges-simple-timeline-layer.c | 37 ++++++++++++++++++++++++++++++++- ges/ges-simple-timeline-layer.h | 1 + tests/check/ges/simplelayer.c | 37 ++++++++++++++++++++++++++++----- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/ges/ges-simple-timeline-layer.c b/ges/ges-simple-timeline-layer.c index f89cfa7fcb..19a8a29818 100644 --- a/ges/ges-simple-timeline-layer.c +++ b/ges/ges-simple-timeline-layer.c @@ -61,13 +61,26 @@ enum LAST_SIGNAL, }; +enum +{ + PROP_0, + PROP_VALID, + LAST_PROP, +}; + static guint gstl_signals[LAST_SIGNAL] = { 0 }; static void ges_simple_timeline_layer_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { + GESSimpleTimelineLayer *self; + self = GES_SIMPLE_TIMELINE_LAYER (object); + switch (property_id) { + case PROP_VALID: + g_value_set_boolean (value, self->valid); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -110,6 +123,17 @@ ges_simple_timeline_layer_class_init (GESSimpleTimelineLayerClass * klass) layer_class->object_removed = ges_simple_timeline_layer_object_removed; layer_class->object_added = ges_simple_timeline_layer_object_added; + /** + * GESSimpleTimelineLayer:valid: + * + * FALSE when the arrangement of objects in the layer would cause errors or + * unexpected output during playback. Do not set the containing pipeline + * state to PLAYING when this property is FALSE. + */ + g_object_class_install_property (object_class, PROP_VALID, + g_param_spec_boolean ("valid", "Valid", + "Layer is in a valid configuration", FALSE, G_PARAM_READABLE)); + /** * GESSimpleTimelineLayer::object-moved * @layer: the #GESSimpleTimelineLayer @@ -145,6 +169,7 @@ gstl_recalculate (GESSimpleTimelineLayer * self) gint height; GESTimelineObject *prev_object = NULL; GESTimelineObject *prev_transition = NULL; + gboolean valid = TRUE; priority = GES_TIMELINE_LAYER (self)->min_gnl_priority + 2; @@ -199,14 +224,17 @@ gstl_recalculate (GESSimpleTimelineLayer * self) if (GES_IS_TIMELINE_TRANSITION (prev_object)) { GST_ERROR ("two transitions in sequence!"); + valid = FALSE; } if (prev_object && (GES_TIMELINE_OBJECT_DURATION (prev_object) < dur)) { GST_ERROR ("transition duration exceeds that of previous neighbor!"); + valid = FALSE; } if (l_next && (GES_TIMELINE_OBJECT_DURATION (l_next->data) < dur)) { GST_ERROR ("transition duration exceeds that of next neighbor!"); + valid = FALSE; } if (prev_transition) { @@ -216,8 +244,10 @@ gstl_recalculate (GESSimpleTimelineLayer * self) start = pos; - if (end > start) + if (end > start) { GST_ERROR ("%d, %d: overlapping transitions!", start, end); + valid = FALSE; + } } prev_transition = obj; } @@ -230,6 +260,11 @@ gstl_recalculate (GESSimpleTimelineLayer * self) GST_TIME_ARGS (pos)); GES_TIMELINE_LAYER (self)->max_gnl_priority = priority; + + if (valid != self->valid) { + self->valid = valid; + g_object_notify (G_OBJECT (self), "valid"); + } } /** diff --git a/ges/ges-simple-timeline-layer.h b/ges/ges-simple-timeline-layer.h index cbde229320..d8271f1bdf 100644 --- a/ges/ges-simple-timeline-layer.h +++ b/ges/ges-simple-timeline-layer.h @@ -57,6 +57,7 @@ struct _GESSimpleTimelineLayer { GList *objects; gboolean adding_object; + gboolean valid; }; /** diff --git a/tests/check/ges/simplelayer.c b/tests/check/ges/simplelayer.c index 76e1faf547..59afaf1c1a 100644 --- a/tests/check/ges/simplelayer.c +++ b/tests/check/ges/simplelayer.c @@ -162,7 +162,8 @@ GST_START_TEST (test_gsl_move_simple) (layer), GES_TIMELINE_OBJECT (source2), -1)); fail_unless_equals_uint64 (GES_TIMELINE_OBJECT_START (source1), 0); fail_unless_equals_uint64 (GES_TIMELINE_OBJECT_START (source2), GST_SECOND); - fail_unless_equals_int (info.new, -1); + /* position will be decremented, this is expected */ + fail_unless_equals_int (info.new, -2); fail_unless_equals_int (info.old, 0); /* remove source1, source2 should be moved to the beginning */ @@ -194,6 +195,12 @@ GST_START_TEST (test_gsl_move_simple) GST_END_TEST; +static void +valid_notify_cb (GObject * obj, GParamSpec * unused G_GNUC_UNUSED, gint * count) +{ + (*count)++; +} + GST_START_TEST (test_gsl_with_transitions) { GESTimeline *timeline; @@ -202,12 +209,18 @@ GST_START_TEST (test_gsl_with_transitions) GESCustomTimelineSource *source1, *source2, *source3, *source4; GESTimelineTransition *tr1, *tr2, *tr3, *tr4, *tr5; GESSimpleTimelineLayer *gstl; + gboolean valid; + gint count = 0; ges_init (); /* Timeline and 1 Layer */ timeline = ges_timeline_new (); layer = (GESTimelineLayer *) ges_simple_timeline_layer_new (); + + g_signal_connect (G_OBJECT (layer), "notify::valid", + G_CALLBACK (valid_notify_cb), &count); + fail_unless (ges_timeline_add_layer (timeline, layer)); ges_timeline_layer_set_priority (layer, 0); @@ -420,22 +433,36 @@ GST_START_TEST (test_gsl_with_transitions) fail_unless (ges_simple_timeline_layer_add_object (gstl, GES_TIMELINE_OBJECT (tr5), 0)); - /* check that removals which result in two or more adjacent transitions at - * least print a warning. */ + /* at this point the layer should still be valid */ + g_object_get (G_OBJECT (layer), "valid", &valid, NULL); + fail_unless (valid); + fail_unless_equals_int (count, 1); - /* FIXME: this needs to be checked manually in the console output */ + /* removals which result in two or more adjacent transitions will also + * print a warning on the console. This is expected */ GST_DEBUG ("Removing sources"); fail_unless (ges_timeline_layer_remove_object (layer, GES_TIMELINE_OBJECT (source1))); - fail_unless (ges_timeline_layer_remove_object (layer, + + /* transition should now be invalid */ + + g_object_get (G_OBJECT (layer), "valid", &valid, NULL); + fail_unless (!valid); + fail_unless_equals_int (count, 2) + + fail_unless (ges_timeline_layer_remove_object (layer, GES_TIMELINE_OBJECT (source2))); fail_unless (ges_timeline_layer_remove_object (layer, GES_TIMELINE_OBJECT (source3))); fail_unless (ges_timeline_layer_remove_object (layer, GES_TIMELINE_OBJECT (source4))); + g_object_get (G_OBJECT (layer), "valid", &valid, NULL); + fail_unless (!valid); + fail_unless_equals_int (count, 2); + GST_DEBUG ("Removing transitions"); fail_unless (ges_timeline_layer_remove_object (layer,