timeline-tree: make sure the layer priority refers to an existing layer

If a layer priority sits between the priorities of two layers in the
timeline, i.e. it references a gap in the timeline's layers, then
ges_timeline_append_layer will never fill this gap and create the
desired layer, so the edit in timeline-tree would loop forever. So a
check was added to avoid this.

This would be a usage error, but a user can reasonably end up with a gap
in their layers if they remove a layer from the timeline.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/177>
This commit is contained in:
Henry Wilkes 2020-05-15 14:58:08 +01:00
parent 53d335b4ed
commit 34719efa17
3 changed files with 37 additions and 0 deletions

View file

@ -121,6 +121,9 @@ ges_timeline_edit (GESTimeline * timeline, GESTimelineElement * element,
gint64 new_layer_priority, GESEditMode mode, GESEdge edge,
guint64 position, GError ** error);
G_GNUC_INTERNAL gboolean
ges_timeline_layer_priority_in_gap (GESTimeline * timeline, guint layer_priority);
G_GNUC_INTERNAL void
ges_timeline_set_track_selection_error (GESTimeline * timeline,
gboolean was_error,

View file

@ -962,6 +962,13 @@ set_layer_priority (GESTimelineElement * element, EditData * data,
data->layer_priority = (guint32) (layer_prio - (gint64) layer_offset);
if (ges_timeline_layer_priority_in_gap (element->timeline,
data->layer_priority)) {
GST_ERROR_OBJECT (element, "Edit layer %" G_GUINT32_FORMAT " would "
"be within a gap in the timeline layers", data->layer_priority);
return FALSE;
}
GST_INFO_OBJECT (element, "%s will move to layer %" G_GUINT32_FORMAT,
element->name, data->layer_priority);
@ -1814,6 +1821,13 @@ perform_element_edit (GESTimelineElement * element, EditData * edit)
edit->layer_priority);
if (layer == NULL) {
/* make sure we won't loop forever */
if (ges_timeline_layer_priority_in_gap (timeline, edit->layer_priority)) {
GST_ERROR_OBJECT (element, "Requested layer %" G_GUINT32_FORMAT
" is within a gap in the timeline layers", edit->layer_priority);
goto done;
}
do {
layer = ges_timeline_append_layer (timeline);
} while (ges_layer_get_priority (layer) < edit->layer_priority);

View file

@ -3074,6 +3074,26 @@ ges_timeline_get_layer (GESTimeline * timeline, guint priority)
return layer;
}
gboolean
ges_timeline_layer_priority_in_gap (GESTimeline * timeline, guint priority)
{
GList *tmp;
CHECK_THREAD (timeline);
for (tmp = timeline->layers; tmp; tmp = tmp->next) {
GESLayer *layer = GES_LAYER (tmp->data);
guint tmp_priority = ges_layer_get_priority (layer);
if (tmp_priority == priority)
return FALSE;
else if (tmp_priority > priority)
return TRUE;
}
return FALSE;
}
/**
* ges_timeline_paste_element:
* @timeline: The #GESTimeline onto which @element should be pasted