static gboolean _remove_clip(GstValidateScenario *scenario, GstValidateAction * action) { GESTimeline *timeline = get_timeline(scenario); GESTimelineElement *clip; GESLayer *layer; const gchar *name; gboolean res = FALSE; name = gst_structure_get_string (action->structure, "name"); clip = ges_timeline_get_element (timeline, name); g_return_val_if_fail (GES_IS_CLIP (clip), FALSE); layer = ges_clip_get_layer(GES_CLIP(clip)); if (layer) { res = ges_layer_remove_clip(layer, GES_CLIP(clip)); gst_object_unref(layer); } else { GST_ERROR("No layer for clip %s", ges_timeline_element_get_name(clip)); } g_object_unref(timeline); return res; }
/**************************************************** * Our listening of children * ****************************************************/ static void _update_our_values (GESGroup * group) { GList *tmp; GESContainer *container = GES_CONTAINER (group); guint32 min_layer_prio = G_MAXINT32, max_layer_prio = 0; for (tmp = GES_CONTAINER_CHILDREN (group); tmp; tmp = tmp->next) { GESContainer *child = tmp->data; if (GES_IS_CLIP (child)) { GESLayer *layer = ges_clip_get_layer (GES_CLIP (child)); gint32 prio = ges_layer_get_priority (layer); min_layer_prio = MIN (prio, min_layer_prio); max_layer_prio = MAX (prio, max_layer_prio); } else if (GES_IS_GROUP (child)) { gint32 prio = _PRIORITY (child), height = GES_CONTAINER_HEIGHT (child); min_layer_prio = MIN (prio, min_layer_prio); max_layer_prio = MAX ((prio + height), max_layer_prio); } } if (min_layer_prio != _PRIORITY (group)) { group->priv->setting_value = TRUE; _set_priority0 (GES_TIMELINE_ELEMENT (group), min_layer_prio); group->priv->setting_value = FALSE; for (tmp = GES_CONTAINER_CHILDREN (group); tmp; tmp = tmp->next) { GESTimelineElement *child = tmp->data; guint32 child_prio = GES_IS_CLIP (child) ? ges_clip_get_layer_priority (GES_CLIP (child)) : _PRIORITY (child); _ges_container_set_priority_offset (container, child, min_layer_prio - child_prio); } } group->priv->max_layer_prio = max_layer_prio; _ges_container_set_height (GES_CONTAINER (group), max_layer_prio - min_layer_prio + 1); }
/** * ges_layer_remove_clip: * @layer: a #GESLayer * @clip: the #GESClip to remove * * Removes the given @clip from the @layer and unparents it. * Unparenting it means the reference owned by @layer on the @clip will be * removed. If you wish to use the @clip after this function, make sure you * call gst_object_ref() before removing it from the @layer. * * Returns: TRUE if the clip could be removed, FALSE if the layer does * not want to remove the clip. */ gboolean ges_layer_remove_clip (GESLayer * layer, GESClip * clip) { GESLayer *current_layer; g_return_val_if_fail (GES_IS_LAYER (layer), FALSE); g_return_val_if_fail (GES_IS_CLIP (clip), FALSE); GST_DEBUG ("layer:%p, clip:%p", layer, clip); current_layer = ges_clip_get_layer (clip); if (G_UNLIKELY (current_layer != layer)) { GST_WARNING ("Clip doesn't belong to this layer"); if (current_layer != NULL) gst_object_unref (current_layer); return FALSE; } gst_object_unref (current_layer); /* emit 'clip-removed' */ g_signal_emit (layer, ges_layer_signals[OBJECT_REMOVED], 0, clip); /* inform the clip it's no longer in a layer */ ges_clip_set_layer (clip, NULL); /* so neither in a timeline */ ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (clip), NULL); /* Remove it from our list of controlled objects */ layer->priv->clips_start = g_list_remove (layer->priv->clips_start, clip); /* Remove our reference to the clip */ gst_object_unref (clip); return TRUE; }
static gboolean extractable_set_asset (GESExtractable * self, GESAsset * asset) { gboolean res = TRUE; GESUriClip *uriclip = GES_URI_CLIP (self); GESUriClipAsset *uri_clip_asset; GESClip *clip = GES_CLIP (self); GESLayer *layer = ges_clip_get_layer (clip); GList *tmp; GESTimelineElement *audio_source = NULL, *video_source = NULL; g_return_val_if_fail (GES_IS_URI_CLIP_ASSET (asset), FALSE); uri_clip_asset = GES_URI_CLIP_ASSET (asset); if (GST_CLOCK_TIME_IS_VALID (GES_TIMELINE_ELEMENT_DURATION (clip)) == FALSE) _set_duration0 (GES_TIMELINE_ELEMENT (uriclip), ges_uri_clip_asset_get_duration (uri_clip_asset)); ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (uriclip), ges_uri_clip_asset_get_duration (uri_clip_asset)); ges_uri_clip_set_is_image (uriclip, ges_uri_clip_asset_is_image (uri_clip_asset)); if (ges_clip_get_supported_formats (clip) == GES_TRACK_TYPE_UNKNOWN) { ges_clip_set_supported_formats (clip, ges_clip_asset_get_supported_formats (GES_CLIP_ASSET (uri_clip_asset))); } GES_TIMELINE_ELEMENT (uriclip)->asset = asset; if (layer) { GList *children = ges_container_get_children (GES_CONTAINER (self), TRUE); for (tmp = children; tmp; tmp = tmp->next) { if (GES_IS_SOURCE (tmp->data)) { GESTrack *track = ges_track_element_get_track (tmp->data); if (track->type == GES_TRACK_TYPE_AUDIO) audio_source = gst_object_ref (tmp->data); else if (track->type == GES_TRACK_TYPE_VIDEO) video_source = gst_object_ref (tmp->data); ges_track_remove_element (track, tmp->data); ges_container_remove (GES_CONTAINER (self), tmp->data); } } g_list_free_full (children, g_object_unref); gst_object_ref (clip); ges_layer_remove_clip (layer, clip); res = ges_layer_add_clip (layer, clip); for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) { if (GES_IS_SOURCE (tmp->data)) { GESTrack *track = ges_track_element_get_track (tmp->data); if (track->type == GES_TRACK_TYPE_AUDIO && audio_source) ges_track_element_copy_properties (audio_source, tmp->data); else if (track->type == GES_TRACK_TYPE_VIDEO && video_source) ges_track_element_copy_properties (video_source, tmp->data); } } g_clear_object (&audio_source); g_clear_object (&video_source); gst_object_unref (clip); gst_object_unref (layer); } if (res) { g_free (uriclip->priv->uri); uriclip->priv->uri = g_strdup (ges_asset_get_id (asset)); } return res; }
/** * ges_layer_add_clip: * @layer: a #GESLayer * @clip: (transfer full): the #GESClip to add. * * Adds the given clip to the layer. Sets the clip's parent, and thus * takes ownership of the clip. * * An clip can only be added to one layer. * * Calling this method will construct and properly set all the media related * elements on @clip. If you need to know when those objects (actually #GESTrackElement) * are constructed, you should connect to the container::child-added signal which * is emited right after those elements are ready to be used. * * Returns: TRUE if the clip was properly added to the layer, or FALSE * if the @layer refuses to add the clip. */ gboolean ges_layer_add_clip (GESLayer * layer, GESClip * clip) { GESAsset *asset; GESLayerPrivate *priv; GESLayer *current_layer; 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); 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_unref (current_layer); return FALSE; } asset = ges_extractable_get_asset (GES_EXTRACTABLE (clip)); if (asset == NULL) { gchar *id; NewAssetUData *mudata = g_slice_new (NewAssetUData); mudata->clip = clip; mudata->layer = layer; GST_DEBUG_OBJECT (layer, "%" GST_PTR_FORMAT " as no reference to any " "assets creating a asset... trying sync", clip); id = ges_extractable_get_id (GES_EXTRACTABLE (clip)); asset = ges_asset_request (G_OBJECT_TYPE (clip), id, NULL); if (asset == NULL) { GESProject *project = layer->timeline ? GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE (layer->timeline))) : NULL; ges_asset_request_async (G_OBJECT_TYPE (clip), id, NULL, (GAsyncReadyCallback) new_asset_cb, mudata); if (project) ges_project_add_loading_asset (project, G_OBJECT_TYPE (clip), id); g_free (id); GST_LOG_OBJECT (layer, "Object added async"); return TRUE; } g_free (id); ges_extractable_set_asset (GES_EXTRACTABLE (clip), asset); g_slice_free (NewAssetUData, mudata); } gst_object_ref_sink (clip); /* Take a reference to the clip and store it stored by start/priority */ priv->clips_start = g_list_insert_sorted (priv->clips_start, clip, (GCompareFunc) element_start_compare); /* Inform the clip it's now in this layer */ ges_clip_set_layer (clip, layer); GST_DEBUG ("current clip priority : %d, Height: %d", _PRIORITY (clip), LAYER_HEIGHT); /* Set the priority. */ if (_PRIORITY (clip) > LAYER_HEIGHT) { GST_WARNING_OBJECT (layer, "%p is out of the layer space, setting its priority to " "%d, setting it to the maximum priority of the layer: %d", clip, _PRIORITY (clip), LAYER_HEIGHT - 1); _set_priority0 (GES_TIMELINE_ELEMENT (clip), LAYER_HEIGHT - 1); } /* If the clip has an acceptable priority, we just let it with its current * priority */ ges_layer_resync_priorities (layer); ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (clip), layer->timeline); /* emit 'clip-added' */ g_signal_emit (layer, ges_layer_signals[OBJECT_ADDED], 0, clip); return TRUE; }