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; }
static void effect_added_cb (GESClip * clip, GESBaseEffect * trop, gboolean * effect_added) { GST_DEBUG ("Effect added"); fail_unless (GES_IS_CLIP (clip)); fail_unless (GES_IS_EFFECT (trop)); *effect_added = TRUE; }
/**************************************************** * 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; }
/** * 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; }
static gboolean _edit_clip (GstValidateScenario * scenario, GstValidateAction * action) { gint64 cpos; gdouble rate; GList *layers = NULL; GESTimeline *timeline; GstQuery *query_segment; GESTimelineElement *clip; GstClockTime position; gint64 stop_value; gboolean res = FALSE; gint new_layer_priority = -1; GESEditMode edge = GES_EDGE_NONE; GESEditMode mode = GES_EDIT_MODE_NORMAL; const gchar *edit_mode_str = NULL, *edge_str = NULL; const gchar *clip_name; clip_name = gst_structure_get_string (action->structure, "clip-name"); timeline = get_timeline (scenario); g_return_val_if_fail (timeline, FALSE); clip = ges_timeline_get_element (timeline, clip_name); g_return_val_if_fail (GES_IS_CLIP (clip), FALSE); if (!gst_validate_action_get_clocktime (scenario, action, "position", &position)) { GST_WARNING ("Could not get position"); goto beach; } if ((edit_mode_str = gst_structure_get_string (action->structure, "edit-mode"))) g_return_val_if_fail (gst_validate_utils_enum_from_str (GES_TYPE_EDIT_MODE, edit_mode_str, &mode), FALSE); if ((edge_str = gst_structure_get_string (action->structure, "edge"))) g_return_val_if_fail (gst_validate_utils_enum_from_str (GES_TYPE_EDGE, edge_str, &edge), FALSE); gst_structure_get_int (action->structure, "new-layer-priority", &new_layer_priority); gst_validate_printf (action, "Editing %s to %" GST_TIME_FORMAT " in %s mode, edge: %s " "with new layer prio: %d \n\n", clip_name, GST_TIME_ARGS (position), edit_mode_str ? edit_mode_str : "normal", edge_str ? edge_str : "None", new_layer_priority); if (!ges_container_edit (GES_CONTAINER (clip), layers, new_layer_priority, mode, edge, position)) { gst_object_unref (clip); goto beach; } gst_object_unref (clip); query_segment = gst_query_new_segment (GST_FORMAT_TIME); if (!gst_element_query (scenario->pipeline, query_segment)) { GST_ERROR_OBJECT (scenario, "Could not query segment"); goto beach; } if (!gst_element_query_position (scenario->pipeline, GST_FORMAT_TIME, &cpos)) { GST_ERROR_OBJECT (scenario, "Could not query position"); goto beach; } if (!ges_timeline_commit (timeline)) { GST_DEBUG_OBJECT (scenario, "nothing changed, no need to seek"); res = TRUE; goto beach; } gst_query_parse_segment (query_segment, &rate, NULL, NULL, &stop_value); res = gst_validate_scenario_execute_seek (scenario, action, rate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, cpos, GST_SEEK_TYPE_SET, stop_value); beach: g_object_unref(timeline); return res; }