timeline: Keep transitions when moving the moving context between layers

Differential Revision: https://phabricator.freedesktop.org/D1225
This commit is contained in:
Thibault Saunier 2016-07-28 21:50:58 -04:00
parent f8f3444daf
commit 8162811bce

View file

@ -144,6 +144,9 @@ struct _MoveContext
GESTrackElement *last_snaped1; GESTrackElement *last_snaped1;
GESTrackElement *last_snaped2; GESTrackElement *last_snaped2;
GstClockTime *last_snap_ts; GstClockTime *last_snap_ts;
/* Moving elements of the context between layers */
gboolean moving_to_layer;
}; };
struct _GESTimelinePrivate struct _GESTimelinePrivate
@ -830,6 +833,24 @@ _destroy_auto_transition_cb (GESAutoTransition * auto_transition,
GESClip *transition = auto_transition->transition_clip; GESClip *transition = auto_transition->transition_clip;
GESLayer *layer = ges_clip_get_layer (transition); GESLayer *layer = ges_clip_get_layer (transition);
if (timeline->priv->movecontext.moving_to_layer) {
GESLayer *nlayer, *transition_layer =
ges_clip_get_layer (auto_transition->transition_clip),
*prev_clip_layer =
ges_clip_get_layer (auto_transition->previous_clip), *next_clip_layer =
ges_clip_get_layer (auto_transition->next_clip);
nlayer =
next_clip_layer == transition_layer ? prev_clip_layer : next_clip_layer;
ges_clip_move_to_layer (auto_transition->transition_clip, nlayer);
g_object_unref (transition_layer);
g_object_unref (prev_clip_layer);
g_object_unref (next_clip_layer);
return;
}
ges_layer_remove_clip (layer, transition); ges_layer_remove_clip (layer, transition);
g_signal_handlers_disconnect_by_func (auto_transition, g_signal_handlers_disconnect_by_func (auto_transition,
_destroy_auto_transition_cb, timeline); _destroy_auto_transition_cb, timeline);
@ -2087,69 +2108,70 @@ gboolean
timeline_context_to_layer (GESTimeline * timeline, gint offset) timeline_context_to_layer (GESTimeline * timeline, gint offset)
{ {
gboolean ret = TRUE; gboolean ret = TRUE;
GHashTableIter iter;
GESContainer *key, *value;
GESLayer *new_layer;
guint prio;
MoveContext *mv_ctx = &timeline->priv->movecontext; MoveContext *mv_ctx = &timeline->priv->movecontext;
/* Layer's priority is always positive */ /* Layer's priority is always positive */
if (offset != 0 && (offset > 0 || mv_ctx->min_move_layer >= -offset)) { if (offset == 0)
GHashTableIter iter; return ret;
GESContainer *key, *value;
GESLayer *new_layer;
guint prio;
mv_ctx->ignore_needs_ctx = TRUE; if (offset < 0 && mv_ctx->min_move_layer < -offset)
return ret;
GST_DEBUG ("Moving %d object, offset %d", GST_DEBUG ("Moving %d object, offset %d",
g_hash_table_size (mv_ctx->toplevel_containers), offset); g_hash_table_size (mv_ctx->toplevel_containers), offset);
timeline->priv->needs_rollback = FALSE; mv_ctx->ignore_needs_ctx = TRUE;
g_hash_table_iter_init (&iter, mv_ctx->toplevel_containers); mv_ctx->moving_to_layer = TRUE;
while (g_hash_table_iter_next (&iter, (gpointer *) & key, timeline->priv->needs_rollback = FALSE;
(gpointer *) & value)) { g_hash_table_iter_init (&iter, mv_ctx->toplevel_containers);
while (g_hash_table_iter_next (&iter, (gpointer *) & key,
(gpointer *) & value)) {
if (GES_IS_CLIP (value)) { if (GES_IS_CLIP (value)) {
prio = ges_clip_get_layer_priority (GES_CLIP (value)); prio = ges_clip_get_layer_priority (GES_CLIP (value));
/* We know that the layer exists as we created it */ /* We know that the layer exists as we created it */
new_layer = new_layer = GES_LAYER (g_list_nth_data (timeline->layers, prio + offset));
GES_LAYER (g_list_nth_data (timeline->layers, prio + offset));
if (new_layer == NULL) { if (new_layer == NULL) {
do { do {
new_layer = ges_timeline_append_layer (timeline); new_layer = ges_timeline_append_layer (timeline);
} while (ges_layer_get_priority (new_layer) < prio + offset); } while (ges_layer_get_priority (new_layer) < prio + offset);
}
ret &= ges_clip_move_to_layer (GES_CLIP (key), new_layer);
} else if (GES_IS_GROUP (value)) {
guint32 last_prio = _PRIORITY (value) + offset +
GES_CONTAINER_HEIGHT (value) - 1;
new_layer = GES_LAYER (g_list_nth_data (timeline->layers, last_prio));
if (new_layer == NULL) {
do {
new_layer = ges_timeline_append_layer (timeline);
} while (ges_layer_get_priority (new_layer) < last_prio);
}
_set_priority0 (GES_TIMELINE_ELEMENT (value),
_PRIORITY (value) + offset);
} }
}
/* Readjust min_move_layer */ ret &= ges_clip_move_to_layer (GES_CLIP (key), new_layer);
mv_ctx->min_move_layer = mv_ctx->min_move_layer + offset; } else if (GES_IS_GROUP (value)) {
guint32 last_prio = _PRIORITY (value) + offset +
GES_CONTAINER_HEIGHT (value) - 1;
mv_ctx->ignore_needs_ctx = FALSE; new_layer = GES_LAYER (g_list_nth_data (timeline->layers, last_prio));
if (timeline->priv->needs_rollback && !timeline->priv->rolling_back) { if (new_layer == NULL) {
ret = FALSE; do {
timeline->priv->rolling_back = TRUE; new_layer = ges_timeline_append_layer (timeline);
timeline_context_to_layer (timeline, -offset); } while (ges_layer_get_priority (new_layer) < last_prio);
timeline->priv->rolling_back = FALSE; }
_set_priority0 (GES_TIMELINE_ELEMENT (value), _PRIORITY (value) + offset);
} }
} }
/* Readjust min_move_layer */
mv_ctx->min_move_layer = mv_ctx->min_move_layer + offset;
mv_ctx->ignore_needs_ctx = FALSE;
if (timeline->priv->needs_rollback && !timeline->priv->rolling_back) {
ret = FALSE;
timeline->priv->rolling_back = TRUE;
timeline_context_to_layer (timeline, -offset);
timeline->priv->rolling_back = FALSE;
}
mv_ctx->moving_to_layer = FALSE;
return ret; return ret;
} }