mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-09 00:45:56 +00:00
clip: secure adding clip to layer
Add more checks when adding a clip to a layer, or moving a clip to a new layer. Also, mark the "layer" property as explicit-notify.
This commit is contained in:
parent
46e6a074bb
commit
e57c345f72
2 changed files with 75 additions and 29 deletions
|
@ -106,6 +106,7 @@ struct _GESClipPrivate
|
|||
|
||||
GList *copied_track_elements;
|
||||
GESLayer *copied_layer;
|
||||
GESTimeline *copied_timeline;
|
||||
gboolean prevent_priority_offset_update;
|
||||
gboolean prevent_resort;
|
||||
|
||||
|
@ -1225,6 +1226,7 @@ _deep_copy (GESTimelineElement * element, GESTimelineElement * copy)
|
|||
}
|
||||
|
||||
ccopy->priv->copied_layer = g_object_ref (self->priv->layer);
|
||||
ccopy->priv->copied_timeline = self->priv->layer->timeline;
|
||||
}
|
||||
|
||||
static GESTimelineElement *
|
||||
|
@ -1233,6 +1235,7 @@ _paste (GESTimelineElement * element, GESTimelineElement * ref,
|
|||
{
|
||||
GList *tmp;
|
||||
GESClip *self = GES_CLIP (element);
|
||||
GESLayer *layer = self->priv->copied_layer;
|
||||
GESClip *nclip = GES_CLIP (ges_timeline_element_copy (element, FALSE));
|
||||
|
||||
ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (nclip), paste_position);
|
||||
|
@ -1241,8 +1244,18 @@ _paste (GESTimelineElement * element, GESTimelineElement * ref,
|
|||
for (tmp = self->priv->copied_track_elements; tmp; tmp = tmp->next)
|
||||
ges_clip_copy_track_element_into (nclip, tmp->data, GST_CLOCK_TIME_NONE);
|
||||
|
||||
if (self->priv->copied_layer) {
|
||||
if (!ges_layer_add_clip (self->priv->copied_layer, nclip)) {
|
||||
if (layer) {
|
||||
if (layer->timeline != self->priv->copied_timeline) {
|
||||
GST_WARNING_OBJECT (self, "Cannot be pasted into the layer %"
|
||||
GST_PTR_FORMAT " because its timeline has changed", layer);
|
||||
gst_object_ref_sink (nclip);
|
||||
gst_object_unref (nclip);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* adding the clip to the layer will add it to the tracks, but not
|
||||
* necessarily the same ones depending on select-tracks-for-object */
|
||||
if (!ges_layer_add_clip (layer, nclip)) {
|
||||
GST_INFO ("%" GES_FORMAT " could not be pasted to %" GST_TIME_FORMAT,
|
||||
GES_ARGS (element), GST_TIME_ARGS (paste_position));
|
||||
|
||||
|
@ -1366,7 +1379,7 @@ ges_clip_class_init (GESClipClass * klass)
|
|||
*/
|
||||
properties[PROP_LAYER] = g_param_spec_object ("layer", "Layer",
|
||||
"The GESLayer where this clip is being used.",
|
||||
GES_TYPE_LAYER, G_PARAM_READABLE);
|
||||
GES_TYPE_LAYER, G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
g_object_class_install_property (object_class, PROP_LAYER,
|
||||
properties[PROP_LAYER]);
|
||||
|
||||
|
@ -1585,13 +1598,42 @@ ges_clip_is_moving_from_layer (GESClip * clip)
|
|||
gboolean
|
||||
ges_clip_move_to_layer (GESClip * clip, GESLayer * layer)
|
||||
{
|
||||
gboolean ret;
|
||||
gboolean ret = FALSE;
|
||||
GESLayer *current_layer;
|
||||
GESTimeline *current_timeline = GES_TIMELINE_ELEMENT_TIMELINE (clip);
|
||||
|
||||
g_return_val_if_fail (GES_IS_CLIP (clip), FALSE);
|
||||
g_return_val_if_fail (GES_IS_LAYER (layer), FALSE);
|
||||
|
||||
current_layer = clip->priv->layer;
|
||||
|
||||
if (current_layer == layer) {
|
||||
GST_INFO_OBJECT (clip, "Already in the layer %" GST_PTR_FORMAT, layer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gst_object_ref (clip);
|
||||
|
||||
if (current_layer == NULL) {
|
||||
GST_DEBUG ("Not moving %p, only adding it to %p", clip, layer);
|
||||
|
||||
ret = ges_layer_add_clip (layer, clip);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ELEMENT_SET_FLAG (clip, GES_CLIP_IS_MOVING);
|
||||
|
||||
if (current_timeline != layer->timeline) {
|
||||
/* make sure we can perform the can_move_element_check in the timeline
|
||||
* of the layer */
|
||||
GST_WARNING_OBJECT (layer, "Cannot move clip %" GES_FORMAT " into "
|
||||
"the layer because its timeline %" GST_PTR_FORMAT " does not "
|
||||
"match the timeline of the layer %" GST_PTR_FORMAT,
|
||||
GES_ARGS (clip), current_timeline, layer->timeline);
|
||||
ret = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (layer->timeline
|
||||
&& !timeline_tree_can_move_element (timeline_get_tree (layer->timeline),
|
||||
GES_TIMELINE_ELEMENT (clip),
|
||||
|
@ -1600,36 +1642,30 @@ ges_clip_move_to_layer (GESClip * clip, GESLayer * layer)
|
|||
GES_TIMELINE_ELEMENT_DURATION (clip), NULL)) {
|
||||
GST_INFO_OBJECT (layer, "Clip %" GES_FORMAT " can't move to layer %d",
|
||||
GES_ARGS (clip), ges_layer_get_priority (layer));
|
||||
ELEMENT_UNSET_FLAG (clip, GES_CLIP_IS_MOVING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
current_layer = clip->priv->layer;
|
||||
|
||||
if (current_layer == NULL) {
|
||||
GST_DEBUG ("Not moving %p, only adding it to %p", clip, layer);
|
||||
|
||||
return ges_layer_add_clip (layer, clip);
|
||||
goto done;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (clip, "moving to layer %p, priority: %d", layer,
|
||||
ges_layer_get_priority (layer));
|
||||
|
||||
gst_object_ref (clip);
|
||||
ret = ges_layer_remove_clip (current_layer, clip);
|
||||
|
||||
if (!ret) {
|
||||
ELEMENT_UNSET_FLAG (clip, GES_CLIP_IS_MOVING);
|
||||
gst_object_unref (clip);
|
||||
return FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = ges_layer_add_clip (layer, clip);
|
||||
|
||||
if (ret) {
|
||||
g_object_notify_by_pspec (G_OBJECT (clip), properties[PROP_LAYER]);
|
||||
} else {
|
||||
/* try and move back into the original layer */
|
||||
ges_layer_add_clip (current_layer, clip);
|
||||
}
|
||||
|
||||
done:
|
||||
ELEMENT_UNSET_FLAG (clip, GES_CLIP_IS_MOVING);
|
||||
|
||||
gst_object_unref (clip);
|
||||
g_object_notify_by_pspec (G_OBJECT (clip), properties[PROP_LAYER]);
|
||||
|
||||
|
||||
return ret && (clip->priv->layer == layer);
|
||||
}
|
||||
|
|
|
@ -690,29 +690,41 @@ ges_layer_add_clip (GESLayer * layer, GESClip * clip)
|
|||
GESAsset *asset;
|
||||
GESLayerPrivate *priv;
|
||||
GESLayer *current_layer;
|
||||
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (clip);
|
||||
|
||||
g_return_val_if_fail (GES_IS_LAYER (layer), FALSE);
|
||||
g_return_val_if_fail (GES_IS_CLIP (clip), FALSE);
|
||||
|
||||
GST_DEBUG_OBJECT (layer, "adding clip:%p", clip);
|
||||
gst_object_ref_sink (clip);
|
||||
|
||||
priv = layer->priv;
|
||||
current_layer = ges_clip_get_layer (clip);
|
||||
if (G_UNLIKELY (current_layer)) {
|
||||
GST_WARNING ("Clip %p already belongs to another layer", clip);
|
||||
gst_object_ref_sink (clip);
|
||||
GST_WARNING_OBJECT (layer, "Clip %" GES_FORMAT " already belongs to "
|
||||
"another layer", GES_ARGS (clip));
|
||||
gst_object_unref (clip);
|
||||
gst_object_unref (current_layer);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (timeline && timeline != layer->timeline) {
|
||||
/* if a clip is not in any layer, its timeline should not be set */
|
||||
GST_ERROR_OBJECT (layer, "Clip %" GES_FORMAT " timeline %"
|
||||
GST_PTR_FORMAT " does not match that of the layer %"
|
||||
GST_PTR_FORMAT, GES_ARGS (clip), timeline, layer->timeline);
|
||||
gst_object_unref (clip);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
timeline = layer->timeline;
|
||||
|
||||
asset = ges_extractable_get_asset (GES_EXTRACTABLE (clip));
|
||||
if (asset == NULL) {
|
||||
gchar *id;
|
||||
NewAssetUData *mudata = g_slice_new (NewAssetUData);
|
||||
|
||||
mudata->clip = gst_object_ref_sink (clip);
|
||||
mudata->clip = clip;
|
||||
mudata->layer = layer;
|
||||
|
||||
GST_DEBUG_OBJECT (layer, "%" GST_PTR_FORMAT " as no reference to any "
|
||||
|
@ -741,8 +753,6 @@ ges_layer_add_clip (GESLayer * layer, GESClip * clip)
|
|||
|
||||
g_slice_free (NewAssetUData, mudata);
|
||||
gst_clear_object (&asset);
|
||||
} else {
|
||||
gst_object_ref_sink (clip);
|
||||
}
|
||||
|
||||
/* Take a reference to the clip and store it stored by start/priority */
|
||||
|
@ -775,9 +785,9 @@ ges_layer_add_clip (GESLayer * layer, GESClip * clip)
|
|||
* invoked by ges_timeline_add_clip */
|
||||
g_signal_emit (layer, ges_layer_signals[OBJECT_ADDED], 0, clip);
|
||||
|
||||
if (layer->timeline && !ges_timeline_add_clip (layer->timeline, clip)) {
|
||||
if (timeline && !ges_timeline_add_clip (timeline, clip)) {
|
||||
GST_WARNING_OBJECT (layer, "Could not add the clip %" GES_FORMAT
|
||||
" to the timeline %" GST_PTR_FORMAT, GES_ARGS (clip), layer->timeline);
|
||||
" to the timeline %" GST_PTR_FORMAT, GES_ARGS (clip), timeline);
|
||||
/* FIXME: change emit signal to FALSE once we are able to delay the
|
||||
* "clip-added" signal until after ges_timeline_add_clip */
|
||||
ges_layer_remove_clip_internal (layer, clip, TRUE);
|
||||
|
|
Loading…
Reference in a new issue