trackelement: split bindings correctly.
authorMathieu Duponchelle <mathieu.duponchelle@epitech.eu>
Tue, 13 Aug 2013 16:05:55 +0000 (18:05 +0200)
committerThibault Saunier <thibault.saunier@collabora.com>
Thu, 22 Aug 2013 22:36:40 +0000 (18:36 -0400)
ges/ges-clip.c
ges/ges-internal.h
ges/ges-track-element.c

index 602cd38..801cb83 100644 (file)
@@ -1206,7 +1206,6 @@ ges_clip_split (GESClip * clip, guint64 position)
 {
   GList *tmp;
   GESClip *new_object;
-
   GstClockTime start, inpoint, duration;
 
   g_return_val_if_fail (GES_IS_CLIP (clip), NULL);
@@ -1243,7 +1242,6 @@ ges_clip_split (GESClip * clip, guint64 position)
   ges_layer_add_clip (clip->priv->layer, new_object);
   ges_clip_set_moving_from_layer (new_object, FALSE);
 
-  _set_duration0 (GES_TIMELINE_ELEMENT (clip), position - _START (clip));
   for (tmp = GES_CONTAINER_CHILDREN (clip); tmp; tmp = tmp->next) {
     GESTrackElement *new_trackelement, *trackelement =
         GES_TRACK_ELEMENT (tmp->data);
@@ -1267,8 +1265,12 @@ ges_clip_split (GESClip * clip, guint64 position)
         GES_TIMELINE_ELEMENT (new_trackelement));
     ges_track_element_copy_properties (GES_TIMELINE_ELEMENT (trackelement),
         GES_TIMELINE_ELEMENT (new_trackelement));
+
+    ges_track_element_split_bindings (trackelement, new_trackelement, position);
   }
 
+  _set_duration0 (GES_TIMELINE_ELEMENT (clip), position - _START (clip));
+
   return new_object;
 }
 
index 9ce44f0..c12e00e 100644 (file)
@@ -285,4 +285,7 @@ G_GNUC_INTERNAL guint32   _ges_track_element_get_layer_priority (GESTrackElement
 G_GNUC_INTERNAL void ges_track_element_copy_properties          (GESTimelineElement * element,
                                                                  GESTimelineElement * elementcopy);
 
+G_GNUC_INTERNAL void ges_track_element_split_bindings (GESTrackElement *element,
+                                                      GESTrackElement *new_element,
+                                                      guint64 position);
 #endif /* __GES_INTERNAL_H__ */
index 8e81475..c78f1dd 100644 (file)
@@ -1392,6 +1392,79 @@ ges_track_element_copy_properties (GESTimelineElement * element,
   g_free (specs);
 }
 
+void
+ges_track_element_split_bindings (GESTrackElement * element,
+    GESTrackElement * new_element, guint64 position)
+{
+  GParamSpec **specs;
+  guint n, n_specs;
+  GstControlBinding *binding;
+  GstTimedValueControlSource *source, *new_source;
+
+  specs =
+      ges_track_element_list_children_properties (GES_TRACK_ELEMENT (element),
+      &n_specs);
+  for (n = 0; n < n_specs; ++n) {
+    GList *values, *tmp;
+    GstTimedValue *last_value = NULL;
+    gboolean past_position = FALSE;
+    GstInterpolationMode mode;
+
+    binding = ges_track_element_get_control_binding (element, specs[n]->name);
+    if (!binding)
+      continue;
+
+    g_object_get (binding, "control_source", &source, NULL);
+
+    /* FIXME : this should work as well with other types of control sources */
+    if (!GST_IS_TIMED_VALUE_CONTROL_SOURCE (source))
+      continue;
+
+    new_source =
+        GST_TIMED_VALUE_CONTROL_SOURCE (gst_interpolation_control_source_new
+        ());
+
+    g_object_get (source, "mode", &mode, NULL);
+    g_object_set (new_source, "mode", mode, NULL);
+
+    values =
+        gst_timed_value_control_source_get_all (GST_TIMED_VALUE_CONTROL_SOURCE
+        (source));
+    for (tmp = values; tmp; tmp = tmp->next) {
+      GstTimedValue *value = tmp->data;
+      if (value->timestamp > position) {
+        gfloat value_at_pos;
+
+        /* FIXME We should be able to use gst_control_source_get_value so
+         * all modes are handled. Right now that method only works if the value
+         * we are looking for is between two actual keyframes which is not enough
+         * in our case. bug #706621 */
+        value_at_pos =
+            interpolate_values_for_position (last_value, value, position);
+
+        past_position = TRUE;
+
+        gst_timed_value_control_source_set (new_source, position, value_at_pos);
+        gst_timed_value_control_source_set (new_source, value->timestamp,
+            value->value);
+        gst_timed_value_control_source_unset (source, value->timestamp);
+        gst_timed_value_control_source_set (source, position, value_at_pos);
+      } else if (past_position) {
+        gst_timed_value_control_source_unset (source, value->timestamp);
+        gst_timed_value_control_source_set (new_source, value->timestamp,
+            value->value);
+      }
+      last_value = value;
+    }
+
+    /* We only manage direct bindings, see TODO in set_control_source */
+    ges_track_element_set_control_source (new_element,
+        GST_CONTROL_SOURCE (new_source), specs[n]->name, "direct");
+  }
+
+  g_free (specs);
+}
+
 /**
  * ges_track_element_edit:
  * @object: the #GESTrackElement to edit