timeline-element: simplify check for being edited

It should be sufficient to set the edit flag only on the toplevel, which
allows all of its children to know they are being edited and should not
move in response.

Also, removed some unnecessary setting/checking of this.

Also, supplied the ges_timeline_element_peak_toplevel, which unlike
ges_timeline_element_get_toplevel_parent, does not add a reference to
the toplevel. Some corresponding leaks in auto-transition have been
fixed by using this instead.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
This commit is contained in:
Henry Wilkes 2020-04-20 13:13:48 +01:00
parent cda1cfa0df
commit bac0df294e
7 changed files with 85 additions and 113 deletions

View file

@ -44,24 +44,22 @@ neighbour_changed_cb (GESClip * clip, GParamSpec * arg G_GNUC_UNUSED,
{ {
gint64 new_duration; gint64 new_duration;
GESTimelineElement *parent = GESTimelineElement *parent =
ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT (clip)); ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT (clip));
if (ELEMENT_FLAG_IS_SET (parent, GES_TIMELINE_ELEMENT_SET_SIMPLE)) { if (GES_TIMELINE_ELEMENT_BEING_EDITED (parent))
return; return;
}
if (parent) { if (parent) {
GESTimelineElement *prev_topparent = GESTimelineElement *prev_topparent =
ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT
(self->next_source)); (self->next_source));
GESTimelineElement *next_topparent = GESTimelineElement *next_topparent =
ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT
(self->previous_source)); (self->previous_source));
if (ELEMENT_FLAG_IS_SET (prev_topparent, GES_TIMELINE_ELEMENT_SET_SIMPLE) || if (GES_TIMELINE_ELEMENT_BEING_EDITED (prev_topparent) ||
ELEMENT_FLAG_IS_SET (next_topparent, GES_TIMELINE_ELEMENT_SET_SIMPLE)) { GES_TIMELINE_ELEMENT_BEING_EDITED (next_topparent))
return; return;
}
if (parent == prev_topparent && parent == next_topparent) { if (parent == prev_topparent && parent == next_topparent) {
GST_DEBUG_OBJECT (self, GST_DEBUG_OBJECT (self,
@ -91,11 +89,11 @@ neighbour_changed_cb (GESClip * clip, GParamSpec * arg G_GNUC_UNUSED,
} }
self->positioning = TRUE; self->positioning = TRUE;
ELEMENT_SET_FLAG (self->transition_clip, GES_TIMELINE_ELEMENT_SET_SIMPLE); GES_TIMELINE_ELEMENT_SET_BEING_EDITED (self->transition_clip);
_set_start0 (GES_TIMELINE_ELEMENT (self->transition_clip), _set_start0 (GES_TIMELINE_ELEMENT (self->transition_clip),
_START (self->next_source)); _START (self->next_source));
_set_duration0 (GES_TIMELINE_ELEMENT (self->transition_clip), new_duration); _set_duration0 (GES_TIMELINE_ELEMENT (self->transition_clip), new_duration);
ELEMENT_UNSET_FLAG (self->transition_clip, GES_TIMELINE_ELEMENT_SET_SIMPLE); GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED (self->transition_clip);
self->positioning = FALSE; self->positioning = FALSE;
} }

View file

@ -297,7 +297,7 @@ _update_duration_limit (GESClip * self)
GST_TIME_FORMAT, GST_TIME_ARGS (duration_limit)); GST_TIME_FORMAT, GST_TIME_ARGS (duration_limit));
if (_CLOCK_TIME_IS_LESS (duration_limit, element->duration) if (_CLOCK_TIME_IS_LESS (duration_limit, element->duration)
&& !ELEMENT_FLAG_IS_SET (self, GES_TIMELINE_ELEMENT_SET_SIMPLE)) { && !GES_TIMELINE_ELEMENT_BEING_EDITED (self)) {
gboolean res; gboolean res;
GST_INFO_OBJECT (self, "Automatically reducing duration to %" GST_INFO_OBJECT (self, "Automatically reducing duration to %"
@ -667,11 +667,8 @@ _set_duration (GESTimelineElement * element, GstClockTime duration)
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) { for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
GESTimelineElement *child = (GESTimelineElement *) tmp->data; GESTimelineElement *child = (GESTimelineElement *) tmp->data;
if (child != container->initiated_move) { if (child != container->initiated_move)
ELEMENT_SET_FLAG (child, GES_TIMELINE_ELEMENT_SET_SIMPLE);
_set_duration0 (GES_TIMELINE_ELEMENT (child), duration); _set_duration0 (GES_TIMELINE_ELEMENT (child), duration);
ELEMENT_UNSET_FLAG (child, GES_TIMELINE_ELEMENT_SET_SIMPLE);
}
} }
container->children_control_mode = GES_CHILDREN_UPDATE; container->children_control_mode = GES_CHILDREN_UPDATE;
g_list_free_full (children, gst_object_unref); g_list_free_full (children, gst_object_unref);
@ -1880,8 +1877,7 @@ ges_clip_move_to_layer (GESClip * clip, GESLayer * layer)
return FALSE; return FALSE;
} }
if (layer->timeline if (layer->timeline && !GES_TIMELINE_ELEMENT_BEING_EDITED (clip)) {
&& !ELEMENT_FLAG_IS_SET (clip, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
/* move to new layer, also checks moving of toplevel */ /* move to new layer, also checks moving of toplevel */
return timeline_tree_move (timeline_get_tree (layer->timeline), return timeline_tree_move (timeline_get_tree (layer->timeline),
element, (gint64) ges_layer_get_priority (current_layer) - element, (gint64) ges_layer_get_priority (current_layer) -
@ -2308,10 +2304,9 @@ ges_clip_split (GESClip * clip, guint64 position)
gst_object_ref (track)); gst_object_ref (track));
} }
ELEMENT_SET_FLAG (clip, GES_TIMELINE_ELEMENT_SET_SIMPLE); GES_TIMELINE_ELEMENT_SET_BEING_EDITED (clip);
_set_duration0 (GES_TIMELINE_ELEMENT (clip), old_duration); _set_duration0 (GES_TIMELINE_ELEMENT (clip), old_duration);
ELEMENT_UNSET_FLAG (clip, GES_TIMELINE_ELEMENT_SET_SIMPLE); GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED (clip);
g_object_notify (G_OBJECT (clip), "duration");
/* add to the track after the duration change so we don't overlap! */ /* add to the track after the duration change so we don't overlap! */
for (tmp = GES_CONTAINER_CHILDREN (new_object); tmp; tmp = tmp->next) { for (tmp = GES_CONTAINER_CHILDREN (new_object); tmp; tmp = tmp->next) {

View file

@ -554,8 +554,7 @@ _update_start_duration (GESContainer * container, GESTimelineElement * child)
{ {
GList *tmp; GList *tmp;
GstClockTime duration, end = 0, start = G_MAXUINT64; GstClockTime duration, end = 0, start = G_MAXUINT64;
gboolean was_setting_simple = gboolean was_being_edited = GES_TIMELINE_ELEMENT_BEING_EDITED (container);
ELEMENT_FLAG_IS_SET (container, GES_TIMELINE_ELEMENT_SET_SIMPLE);
if (!container->children) { if (!container->children) {
/* If we are now empty, keep the same duration and start. This works /* If we are now empty, keep the same duration and start. This works
@ -565,7 +564,7 @@ _update_start_duration (GESContainer * container, GESTimelineElement * child)
return; return;
} }
ELEMENT_SET_FLAG (container, GES_TIMELINE_ELEMENT_SET_SIMPLE); GES_TIMELINE_ELEMENT_SET_BEING_EDITED (container);
for (tmp = container->children; tmp; tmp = tmp->next) { for (tmp = container->children; tmp; tmp = tmp->next) {
start = MIN (start, _START (tmp->data)); start = MIN (start, _START (tmp->data));
@ -592,8 +591,8 @@ _update_start_duration (GESContainer * container, GESTimelineElement * child)
if (prev_dur != duration) if (prev_dur != duration)
g_object_notify (G_OBJECT (container), "duration"); g_object_notify (G_OBJECT (container), "duration");
} }
if (!was_setting_simple) if (!was_being_edited)
ELEMENT_UNSET_FLAG (container, GES_TIMELINE_ELEMENT_SET_SIMPLE); GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED (container);
g_hash_table_foreach (container->priv->mappings, g_hash_table_foreach (container->priv->mappings,
(GHFunc) _resync_position_offsets, container); (GHFunc) _resync_position_offsets, container);
@ -607,24 +606,24 @@ _child_start_changed_cb (GESTimelineElement * child,
GESContainerPrivate *priv = container->priv; GESContainerPrivate *priv = container->priv;
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container); GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
GESChildrenControlMode pmode = container->children_control_mode; GESChildrenControlMode mode = container->children_control_mode;
if (mode == GES_CHILDREN_IGNORE_NOTIFIES)
return;
if (GES_TIMELINE_ELEMENT_BEING_EDITED (child))
mode = GES_CHILDREN_UPDATE_ALL_VALUES;
map = g_hash_table_lookup (priv->mappings, child); map = g_hash_table_lookup (priv->mappings, child);
g_assert (map); g_assert (map);
if (ELEMENT_FLAG_IS_SET (child, GES_TIMELINE_ELEMENT_SET_SIMPLE)) switch (mode) {
container->children_control_mode = GES_CHILDREN_UPDATE_ALL_VALUES;
switch (container->children_control_mode) {
case GES_CHILDREN_IGNORE_NOTIFIES:
break;
case GES_CHILDREN_UPDATE_ALL_VALUES: case GES_CHILDREN_UPDATE_ALL_VALUES:
_update_start_duration (container, child); _update_start_duration (container, child);
break; break;
case GES_CHILDREN_UPDATE_OFFSETS: case GES_CHILDREN_UPDATE_OFFSETS:
map->start_offset = _START (container) - _START (child); map->start_offset = _START (container) - _START (child);
break; break;
case GES_CHILDREN_UPDATE: case GES_CHILDREN_UPDATE:
/* We update all the children calling our set_start method */ /* We update all the children calling our set_start method */
container->initiated_move = child; container->initiated_move = child;
@ -634,8 +633,6 @@ _child_start_changed_cb (GESTimelineElement * child,
default: default:
break; break;
} }
container->children_control_mode = pmode;
} }
static void static void
@ -646,20 +643,18 @@ _child_duration_changed_cb (GESTimelineElement * child,
GESContainerPrivate *priv = container->priv; GESContainerPrivate *priv = container->priv;
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container); GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
GESChildrenControlMode pmode = container->children_control_mode; GESChildrenControlMode mode = container->children_control_mode;
if (pmode == GES_CHILDREN_IGNORE_NOTIFIES) if (mode == GES_CHILDREN_IGNORE_NOTIFIES)
return; return;
if (ELEMENT_FLAG_IS_SET (child, GES_TIMELINE_ELEMENT_SET_SIMPLE)) if (GES_TIMELINE_ELEMENT_BEING_EDITED (child))
container->children_control_mode = GES_CHILDREN_UPDATE_ALL_VALUES; mode = GES_CHILDREN_UPDATE_ALL_VALUES;
map = g_hash_table_lookup (priv->mappings, child); map = g_hash_table_lookup (priv->mappings, child);
g_assert (map); g_assert (map);
switch (container->children_control_mode) { switch (mode) {
case GES_CHILDREN_IGNORE_NOTIFIES:
break;
case GES_CHILDREN_UPDATE_ALL_VALUES: case GES_CHILDREN_UPDATE_ALL_VALUES:
_update_start_duration (container, child); _update_start_duration (container, child);
break; break;
@ -678,8 +673,6 @@ _child_duration_changed_cb (GESTimelineElement * child,
default: default:
break; break;
} }
container->children_control_mode = pmode;
} }
/**************************************************** /****************************************************

View file

@ -203,7 +203,7 @@ _child_clip_changed_layer_cb (GESTimelineElement * clip,
/* sigids takes ownership of new_layer, we take ownership of old_layer */ /* sigids takes ownership of new_layer, we take ownership of old_layer */
sigids->layer = new_layer; sigids->layer = new_layer;
if (ELEMENT_FLAG_IS_SET (clip, GES_TIMELINE_ELEMENT_SET_SIMPLE)) { if (GES_TIMELINE_ELEMENT_BEING_EDITED (clip)) {
GST_DEBUG_OBJECT (container, "Not moving with change in priority of " GST_DEBUG_OBJECT (container, "Not moving with change in priority of "
"clip child %" GES_FORMAT, GES_ARGS (clip)); "clip child %" GES_FORMAT, GES_ARGS (clip));
_update_our_values (GES_GROUP (clip->parent)); _update_our_values (GES_GROUP (clip->parent));
@ -262,7 +262,8 @@ _child_group_priority_changed (GESTimelineElement * child,
return; return;
} }
/* if a child group is simply updating its values we will do the same */ /* if a child group is simply updating its values we will do the same */
if (child_group->priv->updating_priority) { if (child_group->priv->updating_priority ||
GES_TIMELINE_ELEMENT_BEING_EDITED (child)) {
GST_DEBUG_OBJECT (container, "Not moving with change in priority of " GST_DEBUG_OBJECT (container, "Not moving with change in priority of "
"group child %" GES_FORMAT " because it is not moving itself", "group child %" GES_FORMAT " because it is not moving itself",
GES_ARGS (child_group)); GES_ARGS (child_group));
@ -318,8 +319,6 @@ _set_priority (GESTimelineElement * element, guint32 priority)
if (GES_GROUP (element)->priv->updating_priority == TRUE) if (GES_GROUP (element)->priv->updating_priority == TRUE)
return TRUE; return TRUE;
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
layers = GES_TIMELINE_ELEMENT_TIMELINE (element) ? layers = GES_TIMELINE_ELEMENT_TIMELINE (element) ?
GES_TIMELINE_ELEMENT_TIMELINE (element)->layers : NULL; GES_TIMELINE_ELEMENT_TIMELINE (element)->layers : NULL;
if (layers == NULL) { if (layers == NULL) {
@ -332,11 +331,15 @@ _set_priority (GESTimelineElement * element, guint32 priority)
/* FIXME: why are we not shifting ->max_layer_prio? */ /* FIXME: why are we not shifting ->max_layer_prio? */
if (GES_TIMELINE_ELEMENT_BEING_EDITED (element))
return TRUE;
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) { for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
GESTimelineElement *child = tmp->data; GESTimelineElement *child = tmp->data;
if (child != container->initiated_move if (child != container->initiated_move) {
|| ELEMENT_FLAG_IS_SET (container, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
if (GES_IS_CLIP (child)) { if (GES_IS_CLIP (child)) {
guint32 layer_prio = GES_TIMELINE_ELEMENT_LAYER_PRIORITY (child) + diff; guint32 layer_prio = GES_TIMELINE_ELEMENT_LAYER_PRIORITY (child) + diff;
GESLayer *layer = GESLayer *layer =
@ -370,33 +373,20 @@ _set_start (GESTimelineElement * element, GstClockTime start)
{ {
GList *tmp, *children; GList *tmp, *children;
gint64 diff = start - _START (element); gint64 diff = start - _START (element);
GESTimeline *timeline;
GESContainer *container = GES_CONTAINER (element); GESContainer *container = GES_CONTAINER (element);
GESTimelineElement *toplevel =
ges_timeline_element_get_toplevel_parent (element);
gst_object_unref (toplevel);
if (GES_GROUP (element)->priv->setting_value == TRUE) if (GES_GROUP (element)->priv->setting_value == TRUE)
/* Let GESContainer update itself */ /* Let GESContainer update itself */
return GES_TIMELINE_ELEMENT_CLASS (parent_class)->set_start (element, return GES_TIMELINE_ELEMENT_CLASS (parent_class)->set_start (element,
start); start);
if (ELEMENT_FLAG_IS_SET (element, GES_TIMELINE_ELEMENT_SET_SIMPLE) || /* get copy of children, since GESContainer may resort the group */
ELEMENT_FLAG_IS_SET (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE)) { children = ges_container_get_children (container, FALSE);
/* get copy of children, since GESContainer may resort the group */ container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
children = ges_container_get_children (container, FALSE); for (tmp = children; tmp; tmp = tmp->next)
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES; _set_start0 (tmp->data, _START (tmp->data) + diff);
for (tmp = children; tmp; tmp = tmp->next) container->children_control_mode = GES_CHILDREN_UPDATE;
_set_start0 (tmp->data, _START (tmp->data) + diff); g_list_free_full (children, gst_object_unref);
container->children_control_mode = GES_CHILDREN_UPDATE;
g_list_free_full (children, gst_object_unref);
return TRUE;
}
timeline = GES_TIMELINE_ELEMENT_TIMELINE (element);
if (timeline)
return ges_timeline_move_object_simple (timeline, element, NULL,
GES_EDGE_NONE, start);
return TRUE; return TRUE;
} }

View file

@ -86,6 +86,21 @@ GstDebugCategory * _ges_debug (void);
#define GES_TRACK_ELEMENT_IS_CORE(child) \ #define GES_TRACK_ELEMENT_IS_CORE(child) \
(ges_track_element_get_creator_asset (GES_TRACK_ELEMENT (child)) != NULL) (ges_track_element_get_creator_asset (GES_TRACK_ELEMENT (child)) != NULL)
#define GES_TIMELINE_ELEMENT_SET_BEING_EDITED(element) \
ELEMENT_SET_FLAG ( \
ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT (element)), \
GES_TIMELINE_ELEMENT_SET_SIMPLE)
#define GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED(element) \
ELEMENT_UNSET_FLAG ( \
ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT (element)), \
GES_TIMELINE_ELEMENT_SET_SIMPLE)
#define GES_TIMELINE_ELEMENT_BEING_EDITED(element) \
ELEMENT_FLAG_IS_SET ( \
ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT (element)), \
GES_TIMELINE_ELEMENT_SET_SIMPLE)
#define SUPRESS_UNUSED_WARNING(a) (void)a #define SUPRESS_UNUSED_WARNING(a) (void)a
@ -443,6 +458,7 @@ typedef enum
GES_TIMELINE_ELEMENT_SET_SIMPLE = (1 << 1), GES_TIMELINE_ELEMENT_SET_SIMPLE = (1 << 1),
} GESTimelineElementFlags; } GESTimelineElementFlags;
G_GNUC_INTERNAL GESTimelineElement * ges_timeline_element_peak_toplevel (GESTimelineElement * self);
G_GNUC_INTERNAL gdouble ges_timeline_element_get_media_duration_factor(GESTimelineElement *self); G_GNUC_INTERNAL gdouble ges_timeline_element_get_media_duration_factor(GESTimelineElement *self);
G_GNUC_INTERNAL GESTimelineElement * ges_timeline_element_get_copied_from (GESTimelineElement *self); G_GNUC_INTERNAL GESTimelineElement * ges_timeline_element_get_copied_from (GESTimelineElement *self);
G_GNUC_INTERNAL GESTimelineElementFlags ges_timeline_element_flags (GESTimelineElement *self); G_GNUC_INTERNAL GESTimelineElementFlags ges_timeline_element_flags (GESTimelineElement *self);

View file

@ -673,6 +673,18 @@ _set_name (GESTimelineElement * self, const gchar * wanted_name)
/********************************************* /*********************************************
* Internal and private helpers * * Internal and private helpers *
*********************************************/ *********************************************/
GESTimelineElement *
ges_timeline_element_peak_toplevel (GESTimelineElement * self)
{
GESTimelineElement *toplevel = self;
while (toplevel->parent)
toplevel = toplevel->parent;
return toplevel;
}
gdouble gdouble
ges_timeline_element_get_media_duration_factor (GESTimelineElement * self) ges_timeline_element_get_media_duration_factor (GESTimelineElement * self)
{ {
@ -1072,18 +1084,11 @@ ges_timeline_element_set_start (GESTimelineElement * self, GstClockTime start)
" new start: %" GST_TIME_FORMAT, " new start: %" GST_TIME_FORMAT,
GST_TIME_ARGS (GES_TIMELINE_ELEMENT_START (self)), GST_TIME_ARGS (start)); GST_TIME_ARGS (GES_TIMELINE_ELEMENT_START (self)), GST_TIME_ARGS (start));
toplevel_container = ges_timeline_element_get_toplevel_parent (self); if (self->timeline && !GES_TIMELINE_ELEMENT_BEING_EDITED (self))
if (self->timeline
&& !ELEMENT_FLAG_IS_SET (self, GES_TIMELINE_ELEMENT_SET_SIMPLE)
&& !ELEMENT_FLAG_IS_SET (toplevel_container,
GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
gst_object_unref (toplevel_container);
return ges_timeline_element_edit (self, NULL, -1, GES_EDIT_MODE_NORMAL, return ges_timeline_element_edit (self, NULL, -1, GES_EDIT_MODE_NORMAL,
GES_EDGE_NONE, start); GES_EDGE_NONE, start);
}
toplevel_container = ges_timeline_element_peak_toplevel (self);
parent = self->parent; parent = self->parent;
/* FIXME This should not belong to GESTimelineElement */ /* FIXME This should not belong to GESTimelineElement */
@ -1097,11 +1102,9 @@ ges_timeline_element_set_start (GESTimelineElement * self, GstClockTime start)
"Can not move the object as it would imply its " "Can not move the object as it would imply its "
"container to have a negative start value"); "container to have a negative start value");
gst_object_unref (toplevel_container);
return FALSE; return FALSE;
} }
gst_object_unref (toplevel_container);
klass = GES_TIMELINE_ELEMENT_GET_CLASS (self); klass = GES_TIMELINE_ELEMENT_GET_CLASS (self);
if (klass->set_start) { if (klass->set_start) {
gint res = klass->set_start (self, start); gint res = klass->set_start (self, start);
@ -1256,22 +1259,15 @@ ges_timeline_element_set_duration (GESTimelineElement * self,
GstClockTime duration) GstClockTime duration)
{ {
GESTimelineElementClass *klass; GESTimelineElementClass *klass;
GESTimelineElement *toplevel;
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE); g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);
if (duration == self->duration) if (duration == self->duration)
return TRUE; return TRUE;
toplevel = ges_timeline_element_get_toplevel_parent (self); if (self->timeline && !GES_TIMELINE_ELEMENT_BEING_EDITED (self))
if (self->timeline &&
!ELEMENT_FLAG_IS_SET (self, GES_TIMELINE_ELEMENT_SET_SIMPLE) &&
!ELEMENT_FLAG_IS_SET (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
gst_object_unref (toplevel);
return ges_timeline_element_edit (self, NULL, -1, GES_EDIT_MODE_TRIM, return ges_timeline_element_edit (self, NULL, -1, GES_EDIT_MODE_TRIM,
GES_EDGE_END, self->start + duration); GES_EDGE_END, self->start + duration);
}
gst_object_unref (toplevel);
GST_DEBUG_OBJECT (self, "current duration: %" GST_TIME_FORMAT GST_DEBUG_OBJECT (self, "current duration: %" GST_TIME_FORMAT
" new duration: %" GST_TIME_FORMAT, " new duration: %" GST_TIME_FORMAT,
@ -1707,12 +1703,11 @@ G_GNUC_END_IGNORE_DEPRECATIONS; /* End ignoring GParameter deprecation */
GESTimelineElement * GESTimelineElement *
ges_timeline_element_get_toplevel_parent (GESTimelineElement * self) ges_timeline_element_get_toplevel_parent (GESTimelineElement * self)
{ {
GESTimelineElement *toplevel = self; GESTimelineElement *toplevel;
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), NULL); g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), NULL);
while (GES_TIMELINE_ELEMENT_PARENT (toplevel)) toplevel = ges_timeline_element_peak_toplevel (self);
toplevel = GES_TIMELINE_ELEMENT_PARENT (toplevel);
return gst_object_ref (toplevel); return gst_object_ref (toplevel);
} }

View file

@ -198,18 +198,6 @@ timeline_tree_debug (GNode * root)
(GNodeTraverseFunc) print_node, NULL); (GNodeTraverseFunc) print_node, NULL);
} }
static inline GESTimelineElement *
get_toplevel_container (gpointer element)
{
GESTimelineElement *ret =
ges_timeline_element_get_toplevel_parent ((GESTimelineElement
*) (element));
/* We own a ref to the elements ourself */
gst_object_unref (ret);
return ret;
}
static GNode * static GNode *
find_node (GNode * root, gpointer element) find_node (GNode * root, gpointer element)
{ {
@ -246,7 +234,7 @@ timeline_tree_track_element (GNode * root, GESTimelineElement * element)
g_signal_connect (element, "notify::parent", g_signal_connect (element, "notify::parent",
G_CALLBACK (timeline_element_parent_cb), root); G_CALLBACK (timeline_element_parent_cb), root);
toplevel = get_toplevel_container (element); toplevel = ges_timeline_element_peak_toplevel (element);
if (toplevel == element) { if (toplevel == element) {
GST_DEBUG ("Tracking toplevel element %" GES_FORMAT, GES_ARGS (element)); GST_DEBUG ("Tracking toplevel element %" GES_FORMAT, GES_ARGS (element));
@ -1462,7 +1450,6 @@ static gboolean
perform_element_edit (GESTimelineElement * element, EditData * edit) perform_element_edit (GESTimelineElement * element, EditData * edit)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
GESTimelineElement *toplevel = get_toplevel_container (element);
guint32 layer_prio = ges_timeline_element_get_layer_priority (element); guint32 layer_prio = ges_timeline_element_get_layer_priority (element);
switch (edit->mode) { switch (edit->mode) {
@ -1496,8 +1483,7 @@ perform_element_edit (GESTimelineElement * element, EditData * edit)
return FALSE; return FALSE;
} }
ELEMENT_SET_FLAG (element, GES_TIMELINE_ELEMENT_SET_SIMPLE); GES_TIMELINE_ELEMENT_SET_BEING_EDITED (element);
ELEMENT_SET_FLAG (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE);
if (GST_CLOCK_TIME_IS_VALID (edit->start)) { if (GST_CLOCK_TIME_IS_VALID (edit->start)) {
if (!ges_timeline_element_set_start (element, edit->start)) { if (!ges_timeline_element_set_start (element, edit->start)) {
GST_ERROR_OBJECT (element, "Failed to set the start"); GST_ERROR_OBJECT (element, "Failed to set the start");
@ -1541,8 +1527,7 @@ perform_element_edit (GESTimelineElement * element, EditData * edit)
ret = TRUE; ret = TRUE;
done: done:
ELEMENT_UNSET_FLAG (element, GES_TIMELINE_ELEMENT_SET_SIMPLE); GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED (element);
ELEMENT_UNSET_FLAG (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE);
return ret; return ret;
} }
@ -1594,7 +1579,7 @@ timeline_tree_ripple (GNode * root, GESTimelineElement * element,
_REPLACE_TRACK_ELEMENT_WITH_PARENT (element); _REPLACE_TRACK_ELEMENT_WITH_PARENT (element);
ripple_toplevel = get_toplevel_container (element); ripple_toplevel = ges_timeline_element_peak_toplevel (element);
/* if EDGE_END: /* if EDGE_END:
* TRIM_END the element, and MOVE all toplevels whose start is after * TRIM_END the element, and MOVE all toplevels whose start is after
@ -1797,7 +1782,7 @@ timeline_tree_move (GNode * root, GESTimelineElement * element,
GST_INFO_OBJECT (element, "Moving with toplevel with offset %" GST_INFO_OBJECT (element, "Moving with toplevel with offset %"
G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset, G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset,
layer_priority_offset); layer_priority_offset);
element = get_toplevel_container (element); element = ges_timeline_element_peak_toplevel (element);
mode = EDIT_MOVE; mode = EDIT_MOVE;
break; break;
default: default: