trackelement: split bindings correctly.

This commit is contained in:
Mathieu Duponchelle 2013-08-13 18:05:55 +02:00 committed by Thibault Saunier
parent 01f9dbcadc
commit cd8955c56f
3 changed files with 80 additions and 2 deletions

View 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;
}

View 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__ */

View 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