From 1b5c3cb8651b88afb618406f292a831785ea7f7a Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Sat, 8 Oct 2016 10:43:07 +0200 Subject: [PATCH] timeline: Avoid creating extra transition when rippling clips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases when rippling clip we could get the algo lost because a transition existed between two clips (for example at the end of c1 and at the begining of c2) but while rippling it would have required a transition at the end of c2 and beginning of c1, and we were properly not destroying the old one (as the two clips were in the moving context) but we were still creating the other transition in the end... Reviewed-by: Alex Băluț Differential Revision: https://phabricator.freedesktop.org/D1362 --- ges/ges-timeline.c | 31 ++++++++++++++++++----------- tests/check/python/test_timeline.py | 18 ++++++++++++++++- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c index 30dae4147d..8fa4fbc994 100644 --- a/ges/ges-timeline.c +++ b/ges/ges-timeline.c @@ -973,9 +973,9 @@ _create_auto_transition_from_transitions (GESTimeline * timeline, } /* Create all transition that do not exist on @layer. - * @get_auto_transition is called to check if a particular transition exists - * if @ track is specified, we will create the transitions only for that particular - * track */ + * @get_auto_transition is called to check if a particular transition exists. + * If @track is specified, we will create the transitions only for that particular + * track. */ static void _create_transitions_on_layer (GESTimeline * timeline, GESLayer * layer, GESTrack * track, GESTrackElement * initiating_obj, @@ -984,7 +984,8 @@ _create_transitions_on_layer (GESTimeline * timeline, GESLayer * layer, guint32 layer_prio; GSequenceIter *iter; GESAutoTransition *transition; - + GESContainer *toplevel_next; + MoveContext *mv_ctx = &timeline->priv->movecontext; GESTrack *ctrack = track; GList *entered = NULL; /* List of TrackElement for wich we walk through the * "start" but not the "end" in the starts_ends list */ @@ -1001,8 +1002,8 @@ _create_transitions_on_layer (GESTimeline * timeline, GESLayer * layer, guint *start_or_end = g_sequence_get (iter); GESTrackElement *next = g_hash_table_lookup (timeline->priv->by_object, start_or_end); - GESTimelineElement *toplevel = - ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT (next)); + GESContainer *toplevel = + get_toplevel_container (GES_TIMELINE_ELEMENT (next)); /* Only object that are in that layer and track */ if (_ges_track_element_get_layer_priority (next) != layer_prio || @@ -1024,18 +1025,24 @@ _create_transitions_on_layer (GESTimeline * timeline, GESLayer * layer, continue; } + toplevel_next = get_toplevel_container (next); for (tmp = entered; tmp; tmp = tmp->next) { gint64 transition_duration; - GESTrackElement *prev = tmp->data; + GESContainer *toplevel_prev = get_toplevel_container (prev); - if (ctrack != ges_track_element_get_track (prev) || - ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT (prev)) - == toplevel) + /* If we are not in the same track, we do not create a transition */ + if (ctrack != ges_track_element_get_track (prev)) continue; - if (priv->movecontext.moving_trackelements && - GES_TIMELINE_ELEMENT_START (next) > priv->movecontext.start) + /* If elements are in the same toplevel element, we do not create a transition */ + if (get_toplevel_container (GES_TIMELINE_ELEMENT (prev)) == toplevel) + continue; + + /* If the element is inside a container we are moving, we do not + * create a transition */ + if (g_hash_table_lookup (mv_ctx->toplevel_containers, toplevel_prev) && + g_hash_table_lookup (mv_ctx->toplevel_containers, toplevel_next)) continue; transition_duration = (_START (prev) + _DURATION (prev)) - _START (next); diff --git a/tests/check/python/test_timeline.py b/tests/check/python/test_timeline.py index f80ad37463..54d9a5cd88 100644 --- a/tests/check/python/test_timeline.py +++ b/tests/check/python/test_timeline.py @@ -93,5 +93,21 @@ class TestEditing(common.GESSimpleTimelineTest): all_clips = self.layer.get_clips() self.assertEquals(len(all_clips), 4) - clip1.edit([], self.layer.get_priority(), GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, clip2.props.start +1) + clip1.edit([], self.layer.get_priority(), GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, clip2.props.start + 1) self.assertEquals(set(self.layer.get_clips()), set(all_clips)) + + def test_transition_rippling_over_does_not_create_another_transition(self): + self.timeline.props.auto_transition = True + + clip1 = self.add_clip(0, 0, 17 * Gst.SECOND) + clip2 = clip1.split(7.0 * Gst.SECOND) + # Make a transition between the two clips + clip1.edit([], self.layer.get_priority(), GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, 4.5 * Gst.SECOND) + + # Rippl clip1 and check that transitions ar always the sames + all_clips = self.layer.get_clips() + self.assertEquals(len(all_clips), 4) + clip1.edit([], self.layer.get_priority(), GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, 41.5 * Gst.SECOND) + self.assertEquals(len(self.layer.get_clips()), 4) + clip1.edit([], self.layer.get_priority(), GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, 35 * Gst.SECOND) + self.assertEquals(len(self.layer.get_clips()), 4)