GES : remove transitions when needed
authorMathieu Duponchelle <seeed@laposte.net>
Wed, 24 Aug 2011 10:04:32 +0000 (12:04 +0200)
committerThibault Saunier <thibault.saunier@collabora.com>
Wed, 11 Jan 2012 14:56:17 +0000 (11:56 -0300)
Conflicts:

ges/ges-timeline.c

ges/ges-timeline-layer.c
ges/ges-timeline.c

index f764b04..291e2ef 100644 (file)
@@ -40,7 +40,7 @@ static void
 track_object_removed_cb (GESTimelineObject * object,
     GESTrackObject * track_object);
 static void track_object_added_cb (GESTimelineObject * object,
-    GESTrackObject * track_object);
+    GESTrackObject * track_object, GHashTable * signal_table);
 static void track_object_changed_cb (GESTrackObject * track_object,
     GParamSpec * arg G_GNUC_UNUSED);
 static void calculate_transitions (GESTrackObject * track_object);
@@ -63,6 +63,9 @@ struct _GESTimelineLayerPrivate
                                  * containing timeline */
 
   gboolean auto_transition;
+
+
+  GHashTable *signal_table;
 };
 
 enum
@@ -210,6 +213,9 @@ ges_timeline_layer_init (GESTimelineLayer * self)
   self->priv->auto_transition = FALSE;
   self->min_gnl_priority = 0;
   self->max_gnl_priority = LAYER_HEIGHT;
+  self->priv->signal_table =
+      g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref,
+      g_free);
 }
 
 /**
@@ -312,7 +318,7 @@ ges_timeline_layer_add_object (GESTimelineLayer * layer,
   if (layer->priv->auto_transition) {
     if (GES_IS_TIMELINE_SOURCE (object)) {
       g_signal_connect (G_OBJECT (object), "track-object-added",
-          G_CALLBACK (track_object_added_cb), NULL);
+          G_CALLBACK (track_object_added_cb), layer->priv->signal_table);
       g_signal_connect (G_OBJECT (object), "track-object-removed",
           G_CALLBACK (track_object_removed_cb), NULL);
     }
@@ -361,9 +367,60 @@ track_object_duration_cb (GESTrackObject * track_object,
 }
 
 static void
+track_object_deleted_cb (GESTrack * track, GESTrackObject * track_object)
+{
+  GList *track_objects, *tmp, *cur;
+  GESTimelineLayer *layer;
+
+  track_objects = ges_track_get_objects (track);
+  cur = g_list_find (track_objects, track_object);
+  for (tmp = cur->next; tmp; tmp = tmp->next) {
+    if (GES_IS_TRACK_SOURCE (tmp->data)) {
+      break;
+    }
+    if (GES_IS_TRACK_AUDIO_TRANSITION (tmp->data)
+        || GES_IS_TRACK_VIDEO_TRANSITION (tmp->data)) {
+      layer =
+          ges_timeline_object_get_layer (ges_track_object_get_timeline_object
+          (tmp->data));
+      if (ges_timeline_layer_get_auto_transition (layer)) {
+        ges_track_enable_update (track, FALSE);
+        ges_timeline_layer_remove_object (layer,
+            ges_track_object_get_timeline_object (tmp->data));
+        ges_track_enable_update (track, TRUE);
+      }
+      g_object_unref (layer);
+    }
+  }
+
+  for (tmp = cur->prev; tmp; tmp = tmp->prev) {
+    if (GES_IS_TRACK_SOURCE (tmp->data)) {
+      break;
+    }
+    if (GES_IS_TRACK_AUDIO_TRANSITION (tmp->data)
+        || GES_IS_TRACK_VIDEO_TRANSITION (tmp->data)) {
+      layer =
+          ges_timeline_object_get_layer (ges_track_object_get_timeline_object
+          (tmp->data));
+      if (ges_timeline_layer_get_auto_transition (layer)) {
+        ges_track_enable_update (track, FALSE);
+        ges_timeline_layer_remove_object (layer,
+            ges_track_object_get_timeline_object (tmp->data));
+        ges_track_enable_update (track, TRUE);
+      }
+      g_object_unref (layer);
+    }
+  }
+  g_object_unref (track_object);
+}
+
+static void
 track_object_added_cb (GESTimelineObject * object,
-    GESTrackObject * track_object)
+    GESTrackObject * track_object, GHashTable * signal_table)
 {
+  GESTrack *track;
+  gint ptr;
+
   if (GES_IS_TRACK_SOURCE (track_object)) {
     g_signal_connect (G_OBJECT (track_object), "notify::start",
         G_CALLBACK (track_object_changed_cb), NULL);
@@ -371,6 +428,12 @@ track_object_added_cb (GESTimelineObject * object,
         G_CALLBACK (track_object_duration_cb), NULL);
     calculate_transitions (track_object);
   }
+  track = ges_track_object_get_track (track_object);
+  if (!g_hash_table_lookup (signal_table, track)) {
+    ptr = g_signal_connect (track, "track-object-removed",
+        (GCallback) track_object_deleted_cb, NULL);
+    g_hash_table_insert (signal_table, track, &ptr);
+  }
   return;
 }
 
@@ -378,6 +441,7 @@ static void
 track_object_removed_cb (GESTimelineObject * object,
     GESTrackObject * track_object)
 {
+  return;
   if (GES_IS_TRACK_SOURCE (track_object)) {
     g_signal_handlers_disconnect_by_func (track_object, track_object_changed_cb,
         object);
@@ -648,6 +712,41 @@ clean:
   g_object_unref (layer);
 }
 
+static void
+look_for_transition (GESTrackObject * track_object, GESTimelineLayer * layer)
+{
+  GESTrack *track;
+  GList *track_objects, *tmp, *cur;
+
+  track = ges_track_object_get_track (track_object);
+
+  track_objects = ges_track_get_objects (track);
+
+  cur = g_list_find (track_objects, track_object);
+
+  for (tmp = cur->next; tmp; tmp = tmp->next) {
+    if (GES_IS_TRACK_SOURCE (tmp->data)) {
+      break;
+    }
+    if (GES_IS_TRACK_AUDIO_TRANSITION (tmp->data)
+        || GES_IS_TRACK_VIDEO_TRANSITION (tmp->data)) {
+      ges_timeline_layer_remove_object (layer,
+          ges_track_object_get_timeline_object (tmp->data));
+    }
+  }
+
+  for (tmp = cur->prev; tmp; tmp = tmp->prev) {
+    if (GES_IS_TRACK_SOURCE (tmp->data)) {
+      break;
+    }
+    if (GES_IS_TRACK_AUDIO_TRANSITION (tmp->data)
+        || GES_IS_TRACK_VIDEO_TRANSITION (tmp->data)) {
+      ges_timeline_layer_remove_object (layer,
+          ges_track_object_get_timeline_object (tmp->data));
+    }
+  }
+  g_list_free_full (track_objects, g_object_unref);
+}
 
 /**
  * ges_timeline_layer_remove_object:
@@ -667,6 +766,7 @@ ges_timeline_layer_remove_object (GESTimelineLayer * layer,
     GESTimelineObject * object)
 {
   GESTimelineLayer *tl_obj_layer;
+  GList *trackobjects, *tmp;
 
   g_return_val_if_fail (GES_IS_TIMELINE_LAYER (layer), FALSE);
   g_return_val_if_fail (GES_IS_TIMELINE_OBJECT (object), FALSE);
@@ -682,6 +782,16 @@ ges_timeline_layer_remove_object (GESTimelineLayer * layer,
   }
   g_object_unref (tl_obj_layer);
 
+  if (layer->priv->auto_transition) {
+    trackobjects = ges_timeline_object_get_track_objects (object);
+
+    for (tmp = trackobjects; tmp; tmp = tmp->next) {
+      look_for_transition (tmp->data, layer);
+    }
+
+    g_list_free_full (trackobjects, g_object_unref);
+  }
+
   /* emit 'object-removed' */
   g_signal_emit (layer, ges_timeline_layer_signals[OBJECT_REMOVED], 0, object);
 
index 4579f4a..35a79ec 100644 (file)
@@ -114,6 +114,11 @@ static void
 discoverer_discovered_cb (GstDiscoverer * discoverer,
     GstDiscovererInfo * info, GError * err, GESTimeline * timeline);
 
+void look_for_transition (GESTrackObject * track_object,
+    GESTimelineLayer * layer);
+void track_object_removed_cb (GESTrack * track, GESTrackObject * track_object,
+    GESTimeline * timeline);
+
 static void
 ges_timeline_get_property (GObject * object, guint property_id,
     GValue * value, GParamSpec * pspec)
@@ -696,7 +701,7 @@ static void
 layer_object_removed_cb (GESTimelineLayer * layer, GESTimelineObject * object,
     GESTimeline * timeline)
 {
-  GList *tmp, *trackobjects;
+  GList *trackobjects, *tmp;
 
   if (ges_timeline_object_is_moving_from_layer (object)) {
     GST_DEBUG ("TimelineObject %p is moving from a layer to another, not doing"
@@ -722,10 +727,10 @@ layer_object_removed_cb (GESTimelineLayer * layer, GESTimelineObject * object,
 
       ges_timeline_object_release_track_object (object, trobj);
     }
-
     /* removing the reference added by _get_track_objects() */
     g_object_unref (trobj);
   }
+
   g_list_free (trackobjects);
 
   /* if the object is a timeline file source that has not yet been discovered,