diff --git a/ges/ges-clip.c b/ges/ges-clip.c index 602cd38225..801cb83648 100644 --- a/ges/ges-clip.c +++ b/ges/ges-clip.c @@ -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; } diff --git a/ges/ges-internal.h b/ges/ges-internal.h index 9ce44f0e4e..c12e00e7ca 100644 --- a/ges/ges-internal.h +++ b/ges/ges-internal.h @@ -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__ */ diff --git a/ges/ges-track-element.c b/ges/ges-track-element.c index 8e8147565c..c78f1dd9f0 100644 --- a/ges/ges-track-element.c +++ b/ges/ges-track-element.c @@ -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