static void extractable_set_asset (GESExtractable * self, GESAsset * asset) { GESUriClip *uriclip = GES_URI_CLIP (self); GESUriClipAsset *filesource_asset = GES_URI_CLIP_ASSET (asset); GESClip *clip = GES_CLIP (self); if (GST_CLOCK_TIME_IS_VALID (GES_TIMELINE_ELEMENT_DURATION (clip)) == FALSE) _set_duration0 (GES_TIMELINE_ELEMENT (uriclip), ges_uri_clip_asset_get_duration (filesource_asset)); ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (uriclip), ges_uri_clip_asset_get_duration (filesource_asset)); ges_uri_clip_set_is_image (uriclip, ges_uri_clip_asset_is_image (filesource_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 (filesource_asset))); } GES_TIMELINE_ELEMENT (uriclip)->asset = asset; }
GESTimeline * effectTL (void) { GESTimeline *timeline; GESLayer *layer; GESClip *clip1, *clip2; GESEffect *effect1, *effect2; timeline = ges_timeline_new_audio_video (); layer = ges_layer_new (); ges_timeline_add_layer (timeline, layer); clip1 = ges_clip_unknown_from_rel_path ("sd/trailer_400p.ogg", layer, 0, 0, 5); clip2 = ges_clip_unknown_from_rel_path ("sd/sintel_trailer-480p.ogv", layer, 5, 5, 5); effect1 = ges_effect_new ("agingtv"); ges_container_add (GES_CONTAINER (clip1), GES_TIMELINE_ELEMENT (effect1)); effect2 = ges_effect_new ("rippletv"); // some cool Frei0r plugins // "frei0r-filter-pixeliz0r", "frei0r-filter-flippo", "frei0r-filter-twolay0r" ges_container_add (GES_CONTAINER (clip2), GES_TIMELINE_ELEMENT (effect2)); ges_timeline_commit (timeline); return timeline; }
static void _add_track_element (GESFormatter * self, GESClip * clip, GESTrackElement * trackelement, const gchar * track_id, GstStructure * children_properties, GstStructure * properties) { GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self); GESTrack *track = g_hash_table_lookup (priv->tracks, track_id); if (track == NULL) { GST_WARNING_OBJECT (self, "No track with id %s, can not add trackelement", track_id); gst_object_unref (trackelement); return; } GST_DEBUG_OBJECT (self, "Adding track_element: %" GST_PTR_FORMAT " To : %" GST_PTR_FORMAT, trackelement, clip); ges_container_add (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (trackelement)); gst_structure_foreach (children_properties, (GstStructureForeachFunc) _set_child_property, trackelement); if (properties) gst_structure_foreach (properties, (GstStructureForeachFunc) set_property_foreach, trackelement); }
static void _set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { GESTimelineElement *self = GES_TIMELINE_ELEMENT (object); switch (property_id) { case PROP_PARENT: ges_timeline_element_set_parent (self, g_value_get_object (value)); break; case PROP_TIMELINE: ges_timeline_element_set_timeline (self, g_value_get_object (value)); break; case PROP_START: ges_timeline_element_set_start (self, g_value_get_uint64 (value)); break; case PROP_INPOINT: ges_timeline_element_set_inpoint (self, g_value_get_uint64 (value)); break; case PROP_DURATION: ges_timeline_element_set_duration (self, g_value_get_uint64 (value)); break; case PROP_PRIORITY: ges_timeline_element_set_priority (self, g_value_get_uint (value)); break; case PROP_MAX_DURATION: ges_timeline_element_set_max_duration (self, g_value_get_uint64 (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec); } }
static void _ges_container_remove_child_properties (GESContainer * container, GESTimelineElement * child) { guint n_props, i; GParamSpec **child_props = ges_timeline_element_list_children_properties (child, &n_props); for (i = 0; i < n_props; i++) { GObject *prop_child; if (ges_timeline_element_lookup_child (child, child_props[i]->name, &prop_child, NULL)) { ges_timeline_element_remove_child_property (GES_TIMELINE_ELEMENT (container), child_props[i]); } g_param_spec_unref (child_props[i]); } g_free (child_props); }
static void _get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { GESTimelineElement *self = GES_TIMELINE_ELEMENT (object); switch (property_id) { case PROP_PARENT: g_value_take_object (value, self->parent); break; case PROP_TIMELINE: g_value_take_object (value, self->timeline); break; case PROP_START: g_value_set_uint64 (value, self->start); break; case PROP_INPOINT: g_value_set_uint64 (value, self->inpoint); break; case PROP_DURATION: g_value_set_uint64 (value, self->duration); break; case PROP_MAX_DURATION: g_value_set_uint64 (value, self->maxduration); break; case PROP_PRIORITY: g_value_set_uint (value, self->priority); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec); } }
static gboolean _lookup_child (GESTrackElement * object, const gchar * prop_name, GstElement ** element, GParamSpec ** pspec) { return GES_TIMELINE_ELEMENT_GET_CLASS (object)->lookup_child (GES_TIMELINE_ELEMENT (object), prop_name, (GObject **) element, pspec); }
static void ges_uri_clip_init (GESUriClip * self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GES_TYPE_URI_CLIP, GESUriClipPrivate); /* Setting the duration to -1 by default. */ GES_TIMELINE_ELEMENT (self)->duration = GST_CLOCK_TIME_NONE; }
static void ges_timeline_element_finalize (GObject * self) { GESTimelineElement *tle = GES_TIMELINE_ELEMENT (self); g_free (tle->name); G_OBJECT_CLASS (ges_timeline_element_parent_class)->finalize (self); }
static void ges_title_clip_init (GESTitleClip * self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GES_TYPE_TITLE_CLIP, GESTitleClipPrivate); GES_TIMELINE_ELEMENT (self)->duration = 0; /* Not 100% required since a new gobject's content will always be memzero'd */ }
static void ges_test_clip_init (GESTestClip * self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GES_TYPE_TEST_CLIP, GESTestClipPrivate); self->priv->freq = 0; self->priv->volume = 0; GES_TIMELINE_ELEMENT (self)->duration = 0; }
static GList * ges_uri_clip_create_track_elements (GESClip * clip, GESTrackType type) { GList *res = NULL; const GList *tmp, *stream_assets; g_return_val_if_fail (GES_TIMELINE_ELEMENT (clip)->asset, NULL); stream_assets = ges_uri_clip_asset_get_stream_assets (GES_URI_CLIP_ASSET (GES_TIMELINE_ELEMENT (clip)->asset)); for (tmp = stream_assets; tmp; tmp = tmp->next) { GESTrackElementAsset *asset = GES_TRACK_ELEMENT_ASSET (tmp->data); if (ges_track_element_asset_get_track_type (asset) == type) res = g_list_prepend (res, ges_asset_extract (GES_ASSET (asset), NULL)); } return res; }
static void deep_check (GESTimelineElement * element, GstClockTime start, GstClockTime inpoint, GstClockTime duration) { GList *track_elements, *tmp; GstClockTime rstart, rinpoint, rduration; rstart = ges_timeline_element_get_start (GES_TIMELINE_ELEMENT (element)); rinpoint = ges_timeline_element_get_inpoint (GES_TIMELINE_ELEMENT (element)); rduration = ges_timeline_element_get_duration (GES_TIMELINE_ELEMENT (element)); assert_equals_uint64 (rstart, start); assert_equals_uint64 (rinpoint, inpoint); assert_equals_uint64 (rduration, duration); track_elements = GES_CONTAINER_CHILDREN (element); for (tmp = track_elements; tmp; tmp = tmp->next) { rstart = ges_timeline_element_get_start (GES_TIMELINE_ELEMENT (tmp->data)); rinpoint = ges_timeline_element_get_inpoint (GES_TIMELINE_ELEMENT (tmp->data)); rduration = ges_timeline_element_get_duration (GES_TIMELINE_ELEMENT (tmp->data)); assert_equals_uint64 (rstart, start); assert_equals_uint64 (rinpoint, inpoint); assert_equals_uint64 (rduration, duration); } }
/** * ges_layer_add_asset: * @layer: a #GESLayer * @asset: The asset to add to * @start: The start value to set on the new #GESClip * @inpoint: The inpoint value to set on the new #GESClip * @duration: The duration value to set on the new #GESClip * @track_types: The #GESTrackType to set on the the new #GESClip * * Creates Clip from asset, adds it to layer and * returns a reference to it. * * Returns: (transfer none): Created #GESClip */ GESClip * ges_layer_add_asset (GESLayer * layer, GESAsset * asset, GstClockTime start, GstClockTime inpoint, GstClockTime duration, GESTrackType track_types) { GESClip *clip; g_return_val_if_fail (GES_IS_LAYER (layer), NULL); g_return_val_if_fail (GES_IS_ASSET (asset), NULL); g_return_val_if_fail (g_type_is_a (ges_asset_get_extractable_type (asset), GES_TYPE_CLIP), NULL); GST_DEBUG_OBJECT (layer, "Adding asset %s with: start: %" GST_TIME_FORMAT " inpoint: %" GST_TIME_FORMAT " duration: %" GST_TIME_FORMAT " track types: %d (%s)", ges_asset_get_id (asset), GST_TIME_ARGS (start), GST_TIME_ARGS (inpoint), GST_TIME_ARGS (duration), track_types, ges_track_type_name (track_types)); clip = GES_CLIP (ges_asset_extract (asset, NULL)); _set_start0 (GES_TIMELINE_ELEMENT (clip), start); _set_inpoint0 (GES_TIMELINE_ELEMENT (clip), inpoint); if (track_types != GES_TRACK_TYPE_UNKNOWN) ges_clip_set_supported_formats (clip, track_types); if (GST_CLOCK_TIME_IS_VALID (duration)) { _set_duration0 (GES_TIMELINE_ELEMENT (clip), duration); } if (!ges_layer_add_clip (layer, clip)) { gst_object_unref (clip); return NULL; } return clip; }
static GESTimelineElement * _paste (GESTimelineElement * element, GESTimelineElement * ref, GstClockTime paste_position) { GList *tmp; ChildMapping *map; GESContainer *ncontainer = GES_CONTAINER (ges_timeline_element_copy (element, FALSE)); GESContainer *self = GES_CONTAINER (element); for (tmp = self->priv->copied_children; tmp; tmp = tmp->next) { GESTimelineElement *nchild; map = tmp->data; nchild = ges_timeline_element_paste (map->child, paste_position - map->start_offset); ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (ncontainer), GES_TIMELINE_ELEMENT_TIMELINE (ref)); ges_container_add (ncontainer, nchild); } return GES_TIMELINE_ELEMENT (ncontainer); }
static void ges_text_overlay_clip_init (GESTextOverlayClip * self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GES_TYPE_OVERLAY_TEXT_CLIP, GESTextOverlayClipPrivate); GES_TIMELINE_ELEMENT (self)->duration = 0; /* Not 100% needed since gobject contents are memzero'd when created */ self->priv->text = NULL; self->priv->font_desc = NULL; self->priv->halign = DEFAULT_PROP_HALIGNMENT; self->priv->valign = DEFAULT_PROP_VALIGNMENT; self->priv->color = G_MAXUINT32; self->priv->xpos = 0.5; self->priv->ypos = 0.5; }
static void ges_title_clip_init (GESTitleClip * self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GES_TYPE_TITLE_CLIP, GESTitleClipPrivate); GES_TIMELINE_ELEMENT (self)->duration = 0; /* Not 100% required since a new gobject's content will always be memzero'd */ self->priv->text = NULL; self->priv->font_desc = NULL; self->priv->halign = DEFAULT_HALIGNMENT; self->priv->valign = DEFAULT_VALIGNMENT; self->priv->color = G_MAXUINT32; self->priv->background = G_MAXUINT32; self->priv->xpos = 0.5; self->priv->ypos = 0.5; }
/** * ges_layer_resync_priorities: * @layer: a #GESLayer * * Resyncs the priorities of the objects controlled by @layer. * This method */ static gboolean ges_layer_resync_priorities (GESLayer * layer) { GList *tmp; GESTimelineElement *element; GST_DEBUG ("Resync priorities of %p", layer); /* TODO : Inhibit composition updates while doing this. * Ideally we want to do it from an even higher level, but here will * do in the meantime. */ for (tmp = layer->priv->clips_start; tmp; tmp = tmp->next) { element = GES_TIMELINE_ELEMENT (tmp->data); _set_priority0 (element, _PRIORITY (element)); } return 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); }
static void _add_all_groups (GESFormatter * self) { GList *tmp; GESTimelineElement *child; GESBaseXmlFormatterPrivate *priv = GES_BASE_XML_FORMATTER (self)->priv; for (tmp = priv->groups; tmp; tmp = tmp->next) { GList *lchild; PendingGroup *pgroup = tmp->data; for (lchild = ((PendingGroup *) tmp->data)->pending_children; lchild; lchild = lchild->next) { child = g_hash_table_lookup (priv->containers, lchild->data); GST_DEBUG_OBJECT (tmp->data, "Adding %s child %" GST_PTR_FORMAT " %s", (const gchar *) lchild->data, child, GES_TIMELINE_ELEMENT_NAME (child)); ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (pgroup->group), self->timeline); ges_container_add (GES_CONTAINER (pgroup->group), child); } } }
/** * 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 _add_clip(GstValidateScenario *scenario, GstValidateAction * action) { GESTimeline *timeline = get_timeline(scenario); GESAsset *asset; GESLayer *layer; GESClip *clip; GError *error = NULL; gint layer_priority; const gchar *name; const gchar *asset_id; const gchar *type_string; GType type; gboolean res = FALSE; GstClockTime duration = 1 * GST_SECOND; gst_structure_get_int(action->structure, "layer-priority", &layer_priority); name = gst_structure_get_string(action->structure, "name"); asset_id = gst_structure_get_string(action->structure, "asset-id"); type_string = gst_structure_get_string(action->structure, "type"); if (!(type = g_type_from_name(type_string))) { GST_ERROR("This type doesn't exist : %s", type_string); goto beach; } asset = ges_asset_request(type, asset_id, &error); if (!asset || error) { GST_ERROR("There was an error requesting the asset with id %s and type %s (%s)", asset_id, type_string, error->message); goto beach; } layer = _get_layer_by_priority(timeline, layer_priority); if (!layer) { GST_ERROR("No layer with priority %d", layer_priority); goto beach; } if (type == GES_TYPE_URI_CLIP) { duration = GST_CLOCK_TIME_NONE; } clip = ges_layer_add_asset(layer, asset, GST_CLOCK_TIME_NONE, 0, duration, GES_TRACK_TYPE_UNKNOWN); if (clip) { res = TRUE; if (!ges_timeline_element_set_name(GES_TIMELINE_ELEMENT(clip), name)) { res = FALSE; GST_ERROR("couldn't set name %s on clip with id %s", name, asset_id); } } else { GST_ERROR("Couldn't add clip with id %s to layer with priority %d", asset_id, layer_priority); } gst_object_unref (layer); ges_timeline_commit(timeline); beach: g_object_unref(timeline); 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; }
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; }
} /********************************************** * * * Property notifications from Children * * * **********************************************/ static void _child_start_changed_cb (GESTimelineElement * child, GParamSpec * arg G_GNUC_UNUSED, GESContainer * container) { ChildMapping *map; GstClockTime start; GESContainerPrivate *priv = container->priv; GESTimelineElement *element = GES_TIMELINE_ELEMENT (container); map = g_hash_table_lookup (priv->mappings, child); g_assert (map); switch (container->children_control_mode) { case GES_CHILDREN_IGNORE_NOTIFIES: return; case GES_CHILDREN_UPDATE_ALL_VALUES: _ges_container_sort_children (container); start = container->children ? _START (container->children->data) : _START (container); if (start != _START (container)) { _DURATION (container) = _END (container) - start; _START (container) = start;
static void extractable_set_asset (GESExtractable * extractable, GESAsset * asset) { GES_TIMELINE_ELEMENT (extractable)->asset = asset; }
void getClips (JsonReader * reader, GESLayer * layer, GESTrackType type, gboolean absolute_paths) { int i; json_reader_read_member (reader, "clips"); g_print ("= clips =\n"); for (i = 0; i < json_reader_count_elements (reader); i++) { json_reader_read_element (reader, i); const char *src = getString (reader, "src"); int start = getInt (reader, "start"); int in = getInt (reader, "in"); int dur = getInt (reader, "dur"); g_print ("Clip: %s (start: %d, in: %d, dur: %d)\n", src, start, in, dur); GESClip *clip; if (is_in_members (reader, "multi") && getBool (reader, "multi")) { g_print ("multi on.\n"); clip = ges_multi_clip_from_path (src, layer, start, in, dur, absolute_paths); } else { const char *path; if (absolute_paths == TRUE) { path = src; } else { path = ges_renderer_get_absolute_path (src); } clip = ges_clip_from_path (path, layer, start, in, dur, type); } GESTimeline *tl = ges_layer_get_timeline (layer); GList *tracks = ges_timeline_get_tracks (tl); GESTrack *trackv = g_list_first (tracks)->data; GESTrack *tracka = g_list_last (tracks)->data; if (is_in_members (reader, "volume")) { double volume = getDouble (reader, "volume"); GESTrackElement *audioElement = ges_clip_find_track_element (clip, tracka, G_TYPE_NONE); if (audioElement != NULL) { ges_track_element_set_child_properties (audioElement, "volume", volume, NULL); } } GESTrackElement *videoElement = ges_clip_find_track_element (clip, trackv, G_TYPE_NONE); if (videoElement != NULL) { if (is_in_members (reader, "x")) { int x = getInt (reader, "x"); ges_track_element_set_child_properties (videoElement, "posx", x, NULL); } if (is_in_members (reader, "y")) { int y = getInt (reader, "y"); ges_track_element_set_child_properties (videoElement, "posy", y, NULL); } if (is_in_members (reader, "alpha")) { gdouble alpha = getDouble (reader, "alpha"); ges_track_element_set_child_properties (videoElement, "alpha", alpha, NULL); } if (is_in_members (reader, "size")) { gdouble size = getDouble (reader, "size"); GESUriClipAsset *asset = GES_URI_CLIP_ASSET (ges_extractable_get_asset (GES_EXTRACTABLE (clip))); guint width = ges_asset_get_width (asset); guint height = ges_asset_get_height (asset); if (width != 0 && height != 0) { double dw = width * size; double dh = height * size; g_print ("%dx%d => * %f => %dx%d\n", width, height, size, (int) dw, (int) dh); ges_track_element_set_child_properties (videoElement, "width", (int) dw, "height", (int) dh, NULL); } } if (is_in_members (reader, "effect")) { const char *effect_str = getString (reader, "effect"); if (strcmp (effect_str, "") != 0) { g_print ("Using effect %s", effect_str); GESEffect *effect = ges_effect_new (effect_str); ges_container_add (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (effect)); } } } json_reader_end_element (reader); } json_reader_end_member (reader); }
static void make_source (GESFormatter * self, GList * reflist, GHashTable * source_table) { GHashTable *props_table, *effect_table; gchar **prio_array; GESLayer *layer; GESPitiviFormatterPrivate *priv = GES_PITIVI_FORMATTER (self)->priv; gchar *fac_ref = NULL, *media_type = NULL, *filename = NULL, *prio_str; GList *tmp = NULL, *keys, *tmp_key; GESUriClip *src = NULL; gint prio; gboolean a_avail = FALSE, v_avail = FALSE, video; GHashTable *trackelement_table = priv->track_elements_table; for (tmp = reflist; tmp; tmp = tmp->next) { /* Get the layer */ props_table = g_hash_table_lookup (trackelement_table, (gchar *) tmp->data); prio_str = (gchar *) g_hash_table_lookup (props_table, "priority"); prio_array = g_strsplit (prio_str, ")", 0); prio = (gint) g_ascii_strtod (prio_array[1], NULL); g_strfreev (prio_array); /* If we do not have any layer with this priority, create it */ if (!(layer = g_hash_table_lookup (priv->layers_table, &prio))) { layer = ges_layer_new (); g_object_set (layer, "auto-transition", TRUE, "priority", prio, NULL); ges_timeline_add_layer (self->timeline, layer); g_hash_table_insert (priv->layers_table, g_memdup (&prio, sizeof (guint64)), layer); } fac_ref = (gchar *) g_hash_table_lookup (props_table, "fac_ref"); media_type = (gchar *) g_hash_table_lookup (props_table, "media_type"); if (!g_strcmp0 (media_type, "pitivi.stream.VideoStream")) video = TRUE; else video = FALSE; /* FIXME I am sure we could reimplement this whole part * in a simpler way */ if (g_strcmp0 (fac_ref, (gchar *) "effect")) { /* FIXME this is a hack to get a ref to the formatter when receiving * child-added */ g_hash_table_insert (props_table, (gchar *) "current-formatter", self); if (a_avail && (!video)) { a_avail = FALSE; } else if (v_avail && (video)) { v_avail = FALSE; } else { /* If we only have audio or only video in the previous source, * set it has such */ if (a_avail) { ges_clip_set_supported_formats (GES_CLIP (src), GES_TRACK_TYPE_VIDEO); } else if (v_avail) { ges_clip_set_supported_formats (GES_CLIP (src), GES_TRACK_TYPE_AUDIO); } filename = (gchar *) g_hash_table_lookup (source_table, "filename"); src = ges_uri_clip_new (filename); if (!video) { v_avail = TRUE; a_avail = FALSE; } else { a_avail = TRUE; v_avail = FALSE; } set_properties (G_OBJECT (src), props_table); ges_layer_add_clip (layer, GES_CLIP (src)); g_signal_connect (src, "child-added", G_CALLBACK (track_element_added_cb), props_table); priv->sources_to_load = g_list_prepend (priv->sources_to_load, src); } } else { GESEffect *effect; gchar *active = (gchar *) g_hash_table_lookup (props_table, "active"); effect = ges_effect_new ((gchar *) g_hash_table_lookup (props_table, (gchar *) "effect_name")); ges_track_element_set_track_type (GES_TRACK_ELEMENT (effect), (video ? GES_TRACK_TYPE_VIDEO : GES_TRACK_TYPE_AUDIO)); effect_table = g_hash_table_lookup (props_table, (gchar *) "effect_props"); ges_container_add (GES_CONTAINER (src), GES_TIMELINE_ELEMENT (effect)); if (!g_strcmp0 (active, (gchar *) "(bool)False")) ges_track_element_set_active (GES_TRACK_ELEMENT (effect), FALSE); /* Set effect properties */ keys = g_hash_table_get_keys (effect_table); for (tmp_key = keys; tmp_key; tmp_key = tmp_key->next) { GstStructure *structure; const GValue *value; GParamSpec *spec; GstCaps *caps; gchar *prop_val; prop_val = (gchar *) g_hash_table_lookup (effect_table, (gchar *) tmp_key->data); if (g_strstr_len (prop_val, -1, "(GEnum)")) { gchar **val = g_strsplit (prop_val, ")", 2); ges_track_element_set_child_properties (GES_TRACK_ELEMENT (effect), (gchar *) tmp_key->data, atoi (val[1]), NULL); g_strfreev (val); } else if (ges_track_element_lookup_child (GES_TRACK_ELEMENT (effect), (gchar *) tmp->data, NULL, &spec)) { gchar *caps_str = g_strdup_printf ("structure1, property1=%s;", prop_val); caps = gst_caps_from_string (caps_str); g_free (caps_str); structure = gst_caps_get_structure (caps, 0); value = gst_structure_get_value (structure, "property1"); ges_track_element_set_child_property_by_pspec (GES_TRACK_ELEMENT (effect), spec, (GValue *) value); gst_caps_unref (caps); } } } } if (a_avail) { ges_clip_set_supported_formats (GES_CLIP (src), GES_TRACK_TYPE_VIDEO); } else if (v_avail) { ges_clip_set_supported_formats (GES_CLIP (src), GES_TRACK_TYPE_AUDIO); } }