mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
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:
parent
53d335b4ed
commit
34719efa17
3 changed files with 37 additions and 0 deletions
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue