clip: Don't split clips at illegal position
authorThibault Saunier <tsaunier@igalia.com>
Wed, 4 Mar 2020 20:16:18 +0000 (17:16 -0300)
committerThibault Saunier <tsaunier@igalia.com>
Fri, 6 Mar 2020 18:18:28 +0000 (18:18 +0000)
Make sure that when we split a clip, the resulting timeline would
not be in an illegal state.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/issues/94

ges/ges-clip.c
tests/check/python/test_timeline.py

index 1f8d95c29e494f8f30b99a8709ab6e38a09ad8e6..bdb5989a295e9e3787cb3fb74fc1903ba0f9cf84 100644 (file)
@@ -1428,6 +1428,30 @@ ges_clip_split (GESClip * clip, guint64 position)
     return NULL;
   }
 
+  old_duration = position - start;
+  if (!timeline_tree_can_move_element (timeline_get_tree
+          (GES_TIMELINE_ELEMENT_TIMELINE (clip)), GES_TIMELINE_ELEMENT (clip),
+          GES_TIMELINE_ELEMENT_LAYER_PRIORITY (clip),
+          start, old_duration, NULL)) {
+    GST_WARNING_OBJECT (clip,
+        "Can not split %" GES_FORMAT " at %" GST_TIME_FORMAT
+        " as timeline would be in an illegal" " state.", GES_ARGS (clip),
+        GST_TIME_ARGS (position));
+    return NULL;
+  }
+
+  new_duration = duration + start - position;
+  if (!timeline_tree_can_move_element (timeline_get_tree
+          (GES_TIMELINE_ELEMENT_TIMELINE (clip)), GES_TIMELINE_ELEMENT (clip),
+          GES_TIMELINE_ELEMENT_LAYER_PRIORITY (clip), position, new_duration,
+          NULL)) {
+    GST_WARNING_OBJECT (clip,
+        "Can not split %" GES_FORMAT " at %" GST_TIME_FORMAT
+        " as timeline would end up in an illegal" " state.", GES_ARGS (clip),
+        GST_TIME_ARGS (position));
+    return NULL;
+  }
+
   GST_DEBUG_OBJECT (clip, "Spliting at %" GST_TIME_FORMAT,
       GST_TIME_ARGS (position));
 
@@ -1440,8 +1464,6 @@ ges_clip_split (GESClip * clip, guint64 position)
   media_duration_factor =
       ges_timeline_element_get_media_duration_factor (GES_TIMELINE_ELEMENT
       (clip));
-  new_duration = duration + start - position;
-  old_duration = position - start;
   _set_start0 (GES_TIMELINE_ELEMENT (new_object), position);
   _set_inpoint0 (GES_TIMELINE_ELEMENT (new_object),
       inpoint + old_duration * media_duration_factor);
index 5903d1a7e9d0912a3cc3665b3e6ee29d74b41da1..2cfb7afb4e5746f3341c8655320b1ec249deb1b2 100644 (file)
@@ -561,6 +561,32 @@ class TestInvalidOverlaps(common.GESSimpleTimelineTest):
         self.assertIsNone(clip3.split(12))
         self.assertIsNone(clip3.split(15))
 
+    def test_split_with_transition(self):
+        self.track_types = [GES.TrackType.AUDIO]
+        super().setUp()
+        self.timeline.set_auto_transition(True)
+
+        clip0 = self.add_clip(start=0, in_point=0, duration=50)
+        clip1 = self.add_clip(start=20, in_point=0, duration=50)
+        self.assertTimelineTopology([
+            [
+                (GES.TestClip, 0, 50),
+                (GES.TransitionClip, 20, 30),
+                (GES.TestClip, 20, 50)
+            ]
+        ])
+
+        # Split should file as the first part of the split
+        # would be fully overlapping clip0
+        self.assertIsNone(clip1.split(40))
+        self.assertTimelineTopology([
+            [
+                (GES.TestClip, 0, 50),
+                (GES.TransitionClip, 20, 30),
+                (GES.TestClip, 20, 50)
+            ]
+        ])
+
     def test_changing_duration(self):
         clip1 = self.add_clip(start=9, in_point=0, duration=2)
         clip2 = self.add_clip(start=10, in_point=0, duration=2)