ges: Handle absolute GstDirectControlBindings

This commit is contained in:
Thibault Saunier 2015-06-16 13:25:32 +02:00
parent 8e13b7d9b8
commit 7f4f1b0a07
2 changed files with 43 additions and 17 deletions

View file

@ -290,7 +290,7 @@ ges_track_element_init (GESTrackElement * self)
static gfloat static gfloat
interpolate_values_for_position (GstTimedValue * first_value, interpolate_values_for_position (GstTimedValue * first_value,
GstTimedValue * second_value, guint64 position) GstTimedValue * second_value, guint64 position, gboolean absolute)
{ {
gfloat diff; gfloat diff;
GstClockTime interval; GstClockTime interval;
@ -308,6 +308,7 @@ interpolate_values_for_position (GstTimedValue * first_value,
first_value->value - ((float) (first_value->timestamp - first_value->value - ((float) (first_value->timestamp -
position) / (float) interval) * diff; position) / (float) interval) * diff;
if (!absolute)
value_at_pos = CLAMP (value_at_pos, 0.0, 1.0); value_at_pos = CLAMP (value_at_pos, 0.0, 1.0);
return value_at_pos; return value_at_pos;
@ -327,6 +328,7 @@ _update_control_bindings (GESTimelineElement * element, GstClockTime inpoint,
for (n = 0; n < n_specs; ++n) { for (n = 0; n < n_specs; ++n) {
GList *values, *tmp; GList *values, *tmp;
gboolean absolute;
GstTimedValue *last, *first, *prev = NULL, *next = NULL; GstTimedValue *last, *first, *prev = NULL, *next = NULL;
gfloat value_at_pos; gfloat value_at_pos;
@ -337,6 +339,7 @@ _update_control_bindings (GESTimelineElement * element, GstClockTime inpoint,
g_object_get (binding, "control_source", &source, NULL); g_object_get (binding, "control_source", &source, NULL);
g_object_get (binding, "absolute", &absolute, NULL);
if (duration == 0) { if (duration == 0) {
gst_timed_value_control_source_unset_all (GST_TIMED_VALUE_CONTROL_SOURCE gst_timed_value_control_source_unset_all (GST_TIMED_VALUE_CONTROL_SOURCE
(source)); (source));
@ -359,7 +362,8 @@ _update_control_bindings (GESTimelineElement * element, GstClockTime inpoint,
break; break;
} }
value_at_pos = interpolate_values_for_position (first, next, inpoint); value_at_pos =
interpolate_values_for_position (first, next, inpoint, absolute);
gst_timed_value_control_source_unset (source, first->timestamp); gst_timed_value_control_source_unset (source, first->timestamp);
gst_timed_value_control_source_set (source, inpoint, value_at_pos); gst_timed_value_control_source_set (source, inpoint, value_at_pos);
@ -378,7 +382,8 @@ _update_control_bindings (GESTimelineElement * element, GstClockTime inpoint,
} }
value_at_pos = value_at_pos =
interpolate_values_for_position (prev, last, duration + inpoint); interpolate_values_for_position (prev, last, duration + inpoint,
absolute);
gst_timed_value_control_source_unset (source, last->timestamp); gst_timed_value_control_source_unset (source, last->timestamp);
gst_timed_value_control_source_set (source, duration + inpoint, gst_timed_value_control_source_set (source, duration + inpoint,
@ -1270,7 +1275,7 @@ ges_track_element_split_bindings (GESTrackElement * element,
for (n = 0; n < n_specs; ++n) { for (n = 0; n < n_specs; ++n) {
GList *values, *tmp; GList *values, *tmp;
GstTimedValue *last_value = NULL; GstTimedValue *last_value = NULL;
gboolean past_position = FALSE; gboolean past_position = FALSE, absolute;
GstInterpolationMode mode; GstInterpolationMode mode;
binding = ges_track_element_get_control_binding (element, specs[n]->name); binding = ges_track_element_get_control_binding (element, specs[n]->name);
@ -1283,6 +1288,8 @@ ges_track_element_split_bindings (GESTrackElement * element,
if (!GST_IS_TIMED_VALUE_CONTROL_SOURCE (source)) if (!GST_IS_TIMED_VALUE_CONTROL_SOURCE (source))
continue; continue;
g_object_get (binding, "absolute", &absolute, NULL);
new_source = new_source =
GST_TIMED_VALUE_CONTROL_SOURCE (gst_interpolation_control_source_new GST_TIMED_VALUE_CONTROL_SOURCE (gst_interpolation_control_source_new
()); ());
@ -1303,7 +1310,8 @@ ges_track_element_split_bindings (GESTrackElement * element,
* we are looking for is between two actual keyframes which is not enough * we are looking for is between two actual keyframes which is not enough
* in our case. bug #706621 */ * in our case. bug #706621 */
value_at_pos = value_at_pos =
interpolate_values_for_position (last_value, value, position); interpolate_values_for_position (last_value, value, position,
absolute);
past_position = TRUE; past_position = TRUE;
@ -1320,7 +1328,11 @@ ges_track_element_split_bindings (GESTrackElement * element,
last_value = value; last_value = value;
} }
/* We only manage direct bindings, see TODO in set_control_source */ /* We only manage direct (absolute) bindings, see TODO in set_control_source */
if (absolute)
ges_track_element_set_control_source (new_element,
GST_CONTROL_SOURCE (new_source), specs[n]->name, "direct-absolute");
else
ges_track_element_set_control_source (new_element, ges_track_element_set_control_source (new_element,
GST_CONTROL_SOURCE (new_source), specs[n]->name, "direct"); GST_CONTROL_SOURCE (new_source), specs[n]->name, "direct");
} }
@ -1416,6 +1428,7 @@ ges_track_element_set_control_source (GESTrackElement * object,
GstElement *element; GstElement *element;
GParamSpec *pspec; GParamSpec *pspec;
GstControlBinding *binding; GstControlBinding *binding;
gboolean direct, direct_absolute;
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), FALSE); g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), FALSE);
priv = GES_TRACK_ELEMENT (object)->priv; priv = GES_TRACK_ELEMENT (object)->priv;
@ -1445,7 +1458,10 @@ ges_track_element_set_control_source (GESTrackElement * object,
} }
/* TODO : update this according to new types of bindings */ /* TODO : update this according to new types of bindings */
if (!g_strcmp0 (binding_type, "direct")) { direct = !g_strcmp0 (binding_type, "direct");
direct_absolute = !g_strcmp0 (binding_type, "direct-absolute");
if (direct || direct_absolute) {
/* First remove existing binding */ /* First remove existing binding */
binding = binding =
(GstControlBinding *) g_hash_table_lookup (priv->bindings_hashtable, (GstControlBinding *) g_hash_table_lookup (priv->bindings_hashtable,
@ -1455,9 +1471,16 @@ ges_track_element_set_control_source (GESTrackElement * object,
property_name); property_name);
gst_object_remove_control_binding (GST_OBJECT (element), binding); gst_object_remove_control_binding (GST_OBJECT (element), binding);
} }
if (direct_absolute)
binding =
gst_direct_control_binding_new_absolute (GST_OBJECT (element),
property_name, source);
else
binding = binding =
gst_direct_control_binding_new (GST_OBJECT (element), property_name, gst_direct_control_binding_new (GST_OBJECT (element), property_name,
source); source);
gst_object_add_control_binding (GST_OBJECT (element), binding); gst_object_add_control_binding (GST_OBJECT (element), binding);
g_hash_table_insert (priv->bindings_hashtable, g_strdup (property_name), g_hash_table_insert (priv->bindings_hashtable, g_strdup (property_name),
binding); binding);

View file

@ -1004,11 +1004,13 @@ _save_keyframes (GString * str, GESTrackElement * trackelement, gint index)
while (g_hash_table_iter_next (&iter, &key, &value)) { while (g_hash_table_iter_next (&iter, &key, &value)) {
if (GST_IS_DIRECT_CONTROL_BINDING ((GstControlBinding *) value)) { if (GST_IS_DIRECT_CONTROL_BINDING ((GstControlBinding *) value)) {
GstControlSource *source; GstControlSource *source;
gboolean absolute = FALSE;
GstDirectControlBinding *binding; GstDirectControlBinding *binding;
binding = (GstDirectControlBinding *) value; binding = (GstDirectControlBinding *) value;
g_object_get (binding, "control-source", &source, NULL); g_object_get (binding, "control-source", &source,
"absolute", &absolute, NULL);
if (GST_IS_INTERPOLATION_CONTROL_SOURCE (source)) { if (GST_IS_INTERPOLATION_CONTROL_SOURCE (source)) {
GList *timed_values, *tmp; GList *timed_values, *tmp;
@ -1016,8 +1018,9 @@ _save_keyframes (GString * str, GESTrackElement * trackelement, gint index)
append_escaped (str, append_escaped (str,
g_markup_printf_escaped g_markup_printf_escaped
(" <binding type='direct' source_type='interpolation' property='%s'", (" <binding type='%s' source_type='interpolation' property='%s'",
(gchar *) key)); absolute ? "direct-absolute" : "direct", (gchar *) key));
g_object_get (source, "mode", &mode, NULL); g_object_get (source, "mode", &mode, NULL);
append_escaped (str, g_markup_printf_escaped (" mode='%d'", mode)); append_escaped (str, g_markup_printf_escaped (" mode='%d'", mode));
append_escaped (str, g_markup_printf_escaped (" track_id='%d'", index)); append_escaped (str, g_markup_printf_escaped (" track_id='%d'", index));
@ -1038,7 +1041,7 @@ _save_keyframes (GString * str, GESTrackElement * trackelement, gint index)
} else } else
GST_DEBUG ("control source not in [interpolation]"); GST_DEBUG ("control source not in [interpolation]");
} else } else
GST_DEBUG ("Binding type not in [direct]"); GST_DEBUG ("Binding type not in [direct, direct-absolute]");
} }
} }