timeline: Destroy transition if a neighbor is not being moved to a layer
authorThibault Saunier <thibault.saunier@osg.samsung.com>
Thu, 6 Oct 2016 17:14:57 +0000 (19:14 +0200)
committerThibault Saunier <thibault.saunier@osg.samsung.com>
Fri, 4 Nov 2016 18:56:31 +0000 (15:56 -0300)
And make sure that we move the transition to the right layer, not trying
to figure it out.

Differential Revision: https://phabricator.freedesktop.org/D1360

ges/ges-layer.c
ges/ges-timeline.c
tests/check/python/test_timeline.py

index f7e9844..606e3eb 100644 (file)
@@ -618,6 +618,7 @@ ges_layer_add_clip (GESLayer * layer, GESClip * clip)
   }
 
   ges_layer_resync_priorities (layer);
+
   ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (clip),
       layer->timeline);
 
index 3d788b1..a6e8a7a 100644 (file)
@@ -145,8 +145,9 @@ struct _MoveContext
   GESTrackElement *last_snaped2;
   GstClockTime *last_snap_ts;
 
-  /* Moving elements of the context between layers */
-  gboolean moving_to_layer;
+  /* Priority of the layer where we are moving current clip
+   * -1 if not moving any clip to a new layer. */
+  GESLayer *moving_to_layer;
 };
 
 struct _GESTimelinePrivate
@@ -700,7 +701,7 @@ ges_timeline_init (GESTimeline * self)
 /* Private methods */
 
 static inline GESContainer *
-get_toplevel_container (GESTrackElement * element)
+get_toplevel_container (gpointer element)
 {
   GESTimelineElement *ret =
       ges_timeline_element_get_toplevel_parent ((GESTimelineElement
@@ -830,24 +831,20 @@ _destroy_auto_transition_cb (GESAutoTransition * auto_transition,
     GESTimeline * timeline)
 {
   GESTimelinePrivate *priv = timeline->priv;
+  MoveContext *mv_ctx = &timeline->priv->movecontext;
   GESClip *transition = auto_transition->transition_clip;
   GESLayer *layer = ges_clip_get_layer (transition);
+  GESContainer *toplevel_prev =
+      get_toplevel_container (auto_transition->previous_clip), *toplevel_next =
+      get_toplevel_container (auto_transition->next_clip);
 
-  if (timeline->priv->movecontext.moving_to_layer) {
-    GESLayer *nlayer, *transition_layer =
-        ges_clip_get_layer (auto_transition->transition_clip),
-        *prev_clip_layer =
-        ges_clip_get_layer (auto_transition->previous_clip), *next_clip_layer =
-        ges_clip_get_layer (auto_transition->next_clip);
-
-    nlayer =
-        next_clip_layer == transition_layer ? prev_clip_layer : next_clip_layer;
+  if (mv_ctx->moving_to_layer &&
+      g_hash_table_lookup (mv_ctx->toplevel_containers, toplevel_prev) &&
+      g_hash_table_lookup (mv_ctx->toplevel_containers, toplevel_next)) {
+    GESLayer *nlayer = mv_ctx->moving_to_layer;
 
-    ges_clip_move_to_layer (auto_transition->transition_clip, nlayer);
+    ges_clip_move_to_layer (transition, nlayer);
 
-    g_object_unref (transition_layer);
-    g_object_unref (prev_clip_layer);
-    g_object_unref (next_clip_layer);
     return;
   }
 
@@ -1106,6 +1103,7 @@ init_movecontext (MoveContext * mv_ctx, gboolean first_init)
   mv_ctx->last_snaped1 = NULL;
   mv_ctx->last_snaped2 = NULL;
   mv_ctx->last_snap_ts = NULL;
+  mv_ctx->moving_to_layer = NULL;
 }
 
 static inline void
@@ -2129,7 +2127,6 @@ timeline_context_to_layer (GESTimeline * timeline, gint offset)
       g_hash_table_size (mv_ctx->toplevel_containers), offset);
 
   mv_ctx->ignore_needs_ctx = TRUE;
-  mv_ctx->moving_to_layer = TRUE;
   timeline->priv->needs_rollback = FALSE;
   g_hash_table_iter_init (&iter, mv_ctx->toplevel_containers);
   while (g_hash_table_iter_next (&iter, (gpointer *) & key,
@@ -2147,6 +2144,7 @@ timeline_context_to_layer (GESTimeline * timeline, gint offset)
         } while (ges_layer_get_priority (new_layer) < prio + offset);
       }
 
+      mv_ctx->moving_to_layer = new_layer;
       ret &= ges_clip_move_to_layer (GES_CLIP (key), new_layer);
     } else if (GES_IS_GROUP (value)) {
       guint32 last_prio = _PRIORITY (value) + offset +
@@ -2160,6 +2158,7 @@ timeline_context_to_layer (GESTimeline * timeline, gint offset)
         } while (ges_layer_get_priority (new_layer) < last_prio);
       }
 
+      mv_ctx->moving_to_layer = NULL;
       _set_priority0 (GES_TIMELINE_ELEMENT (value), _PRIORITY (value) + offset);
     }
   }
@@ -2174,7 +2173,7 @@ timeline_context_to_layer (GESTimeline * timeline, gint offset)
     timeline_context_to_layer (timeline, -offset);
     timeline->priv->rolling_back = FALSE;
   }
-  mv_ctx->moving_to_layer = FALSE;
+  mv_ctx->moving_to_layer = NULL;
 
   return ret;
 }
index 0c5f41e..86e52cc 100644 (file)
@@ -73,3 +73,15 @@ class TestEditing(common.GESSimpleTimelineTest):
         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)
+
+    def test_transition_moves_when_rippling_to_another_layer(self):
+        self.timeline.props.auto_transition = True
+        clip1 = self.add_clip(0, 0, 100)
+        clip2 = self.add_clip(50, 0, 100)
+        all_clips = self.layer.get_clips()
+        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)
+        self.assertEquals(self.layer.get_clips(), [])
+        self.assertEquals(set(layer2.get_clips()), set(all_clips))