diff --git a/ges/ges-clip.c b/ges/ges-clip.c index 34ac6fabf3..70c7ee3660 100644 --- a/ges/ges-clip.c +++ b/ges/ges-clip.c @@ -1385,6 +1385,13 @@ ges_clip_split (GESClip * clip, guint64 position) _set_duration0 (GES_TIMELINE_ELEMENT (clip), old_duration); + if (GES_TIMELINE_ELEMENT_TIMELINE (clip)) { + for (tmp = GES_CONTAINER_CHILDREN (new_object); tmp; tmp = tmp->next) { + timeline_create_transitions (GES_TIMELINE_ELEMENT_TIMELINE (tmp->data), + tmp->data); + } + } + return new_object; } diff --git a/ges/ges-internal.h b/ges/ges-internal.h index 9eaf01ff49..502b11ba90 100644 --- a/ges/ges-internal.h +++ b/ges/ges-internal.h @@ -125,6 +125,9 @@ G_GNUC_INTERNAL void timeline_fill_gaps (GESTimeline *timeline); +G_GNUC_INTERNAL void +timeline_create_transitions (GESTimeline * timeline, GESTrackElement * track_element); + G_GNUC_INTERNAL void track_resort_and_fill_gaps (GESTrack *track); diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c index 9febf1f2d1..aba57882c1 100644 --- a/ges/ges-timeline.c +++ b/ges/ges-timeline.c @@ -1065,8 +1065,9 @@ _create_transitions_on_layer (GESTimeline * timeline, GESLayer * layer, } /* @track_element must be a GESSource */ -static void -create_transitions (GESTimeline * timeline, GESTrackElement * track_element) +void +timeline_create_transitions (GESTimeline * timeline, + GESTrackElement * track_element) { GESTrack *track; GList *layer_node; @@ -1220,7 +1221,7 @@ start_tracking_track_element (GESTimeline * timeline, timeline->priv->movecontext.needs_move_ctx = TRUE; timeline_update_duration (timeline); - create_transitions (timeline, trackelement); + timeline_create_transitions (timeline, trackelement); } } @@ -2598,7 +2599,7 @@ trackelement_start_changed_cb (GESTrackElement * child, timeline->priv->snapping_distance == 0) timeline->priv->movecontext.needs_move_ctx = TRUE; - create_transitions (timeline, child); + timeline_create_transitions (timeline, child); } } @@ -2668,7 +2669,7 @@ trackelement_duration_changed_cb (GESTrackElement * child, timeline->priv->movecontext.needs_move_ctx = TRUE; } - create_transitions (timeline, child); + timeline_create_transitions (timeline, child); } } diff --git a/tests/check/python/common.py b/tests/check/python/common.py index 23d81e99d8..81e78557d2 100644 --- a/tests/check/python/common.py +++ b/tests/check/python/common.py @@ -55,6 +55,7 @@ def create_main_loop(): mainloop.run = run return mainloop + def create_project(with_group=False, saved=False): """Creates a project with two clips in a group.""" project = GES.Project() @@ -78,6 +79,7 @@ def create_project(with_group=False, saved=False): return timeline + class GESTest(unittest.TestCase): def _log(self, func, format, *args): string = format @@ -105,9 +107,22 @@ class GESTest(unittest.TestCase): class GESSimpleTimelineTest(GESTest): + def __init__(self, *args): + self.track_types = [GES.TrackType.AUDIO, GES.TrackType.VIDEO] + super(GESSimpleTimelineTest, self).__init__(*args) + def setUp(self): - self.timeline = GES.Timeline.new_audio_video() - self.assertEqual(len(self.timeline.get_tracks()), 2) + self.timeline = GES.Timeline.new() + for track_type in self.track_types: + self.assertIn( + track_type, [GES.TrackType.AUDIO, GES.TrackType.VIDEO]) + if track_type == GES.TrackType.AUDIO: + self.timeline.add_track(GES.AudioTrack.new()) + else: + self.timeline.add_track(GES.VideoTrack.new()) + + self.assertEqual(len(self.timeline.get_tracks()), + len(self.track_types)) self.layer = self.timeline.append_layer() def add_clip(self, start, in_point, duration): diff --git a/tests/check/python/test_timeline.py b/tests/check/python/test_timeline.py index f7d3556ec3..1769b5fcf0 100644 --- a/tests/check/python/test_timeline.py +++ b/tests/check/python/test_timeline.py @@ -45,6 +45,7 @@ class TestTimeline(unittest.TestCase): project = GES.Project.new(uri=timeline.get_asset().props.uri) loaded_called = False + def loaded(unused_project, unused_timeline): nonlocal loaded_called loaded_called = True @@ -62,6 +63,59 @@ class TestTimeline(unittest.TestCase): self.assertTrue(loaded_called) handle.assert_not_called() + +class TestSplitting(GESSimpleTimelineTest): + def setUp(self): + self.track_types = [GES.TrackType.AUDIO] + super(TestSplitting, self).setUp() + + def assertTimelineTopology(self, topology): + res = [] + for layer in self.timeline.get_layers(): + layer_timings = [] + for clip in layer.get_clips(): + layer_timings.append( + (type(clip), clip.props.start, clip.props.duration)) + + res.append(layer_timings) + + self.assertEqual(topology, res) + return res + + def test_spliting_with_auto_transition_on_the_left(self): + self.timeline.props.auto_transition = True + clip1 = self.add_clip(0, 0, 100) + clip2 = self.add_clip(50, 0, 100) + self.assertTimelineTopology([ + [ # Unique layer + (GES.TestClip, 0, 100), + (GES.TransitionClip, 50, 50), + (GES.TestClip, 50, 100) + ] + ]) + + clip1.split(25) + self.assertTimelineTopology([ + [ # Unique layer + (GES.TestClip, 0, 25), + (GES.TestClip, 25, 75), + (GES.TransitionClip, 50, 50), + (GES.TestClip, 50, 100), + ] + ]) + + clip2.split(125) + self.assertTimelineTopology([ + [ # Unique layer + (GES.TestClip, 0, 25), + (GES.TestClip, 25, 75), + (GES.TransitionClip, 50, 50), + (GES.TestClip, 50, 75), + (GES.TestClip, 125, 25), + ] + ]) + + class TestEditing(GESSimpleTimelineTest): def test_transition_disappears_when_moving_to_another_layer(self): @@ -71,7 +125,8 @@ class TestEditing(GESSimpleTimelineTest): self.assertEquals(len(self.layer.get_clips()), 4) layer2 = self.timeline.append_layer() - clip2.edit([], layer2.get_priority(), GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, clip2.props.start) + clip2.edit([], layer2.get_priority(), GES.EditMode.EDIT_NORMAL, + GES.Edge.EDGE_NONE, clip2.props.start) self.assertEquals(len(self.layer.get_clips()), 1) self.assertEquals(len(layer2.get_clips()), 1) @@ -83,7 +138,8 @@ class TestEditing(GESSimpleTimelineTest): self.assertEquals(len(all_clips), 4) layer2 = self.timeline.append_layer() - clip1.edit([], layer2.get_priority(), GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, clip1.props.start) + clip1.edit([], layer2.get_priority(), GES.EditMode.EDIT_RIPPLE, + GES.Edge.EDGE_NONE, clip1.props.start) self.assertEquals(self.layer.get_clips(), []) self.assertEquals(set(layer2.get_clips()), set(all_clips)) @@ -94,7 +150,8 @@ class TestEditing(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): @@ -103,14 +160,17 @@ class TestEditing(GESSimpleTimelineTest): 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) + 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) + 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) + 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) @@ -156,7 +216,9 @@ class TestTransitions(GESSimpleTimelineTest): clip2.connect("notify::start", property_changed_cb) # Move clip2 to create a transition with clip1. - clip2.edit([], self.layer.get_priority(), GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, 50) + clip2.edit([], self.layer.get_priority(), + GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, 50) # The clip-added signal is emitted twice, once for the video # transition and once for the audio transition. - self.assertEqual(signals, ["notify::start", "clip-added", "clip-added"]) + self.assertEqual( + signals, ["notify::start", "clip-added", "clip-added"])