GESTimeline * positionTestTL (void) { GESTimeline *timeline; GESTrack *trackv; GError **error = NULL; GESAsset *asset; GESClip *clip; timeline = ges_timeline_new (); trackv = GES_TRACK (ges_video_track_new ()); ges_timeline_add_track (timeline, trackv); GESLayer *layer = ges_layer_new (); ges_timeline_add_layer (timeline, layer); asset = GES_ASSET (ges_uri_clip_asset_request_sync (ges_renderer_get_absolute_path ("image/wallpaper720p.jpg"), error)); clip = ges_layer_add_asset (layer, asset, 0, 0, 2 * GST_SECOND, GES_TRACK_TYPE_VIDEO); GESTrackElement *elem = ges_clip_find_track_element (clip, trackv, G_TYPE_NONE); ges_track_element_set_child_properties (elem, "posx", 100, "width", 100, NULL); ges_timeline_commit (timeline); return timeline; }
int main (int argc, char **argv) { GESTimeline *timeline; GESLayer *layer; GError **error = NULL; GESAsset *asset; const gchar *url = "file:///home/bmonkey/workspace/ges/ges-renderer/data/sd/sintel_trailer-480p.mp4"; const gchar *exportURL = "file:///home/bmonkey/workspace/ges/ges-renderer/transition.mp4"; gst_init (&argc, &argv); ges_init (); timeline = ges_timeline_new_audio_video (); layer = ges_layer_new (); g_object_set (layer, "auto-transition", TRUE, NULL); ges_timeline_add_layer (timeline, layer); asset = GES_ASSET (ges_uri_clip_asset_request_sync (url, error)); ges_layer_add_asset (layer, asset, 0 * GST_SECOND, 0 * GST_SECOND, 10 * GST_SECOND, GES_TRACK_TYPE_VIDEO); ges_layer_add_asset (layer, asset, 5 * GST_SECOND, 20 * GST_SECOND, 10 * GST_SECOND, GES_TRACK_TYPE_VIDEO); ges_timeline_commit (timeline); duration = ges_timeline_get_duration (timeline); pipeline = ges_pipeline_new (); ges_pipeline_set_timeline (pipeline, timeline); GESRendererProfile pal = { 720, 576, 25, PROFILE_AAC_H264_QUICKTIME }; GstCaps *settings = gst_caps_from_renderer_profile (&pal); GstEncodingProfile *profile = profile_get_encoding_profile (settings); ges_pipeline_set_render_settings (pipeline, exportURL, profile); ges_pipeline_set_mode (pipeline, GES_PIPELINE_MODE_RENDER); GMainLoop *mainloop; mainloop = g_main_loop_new (NULL, FALSE); GstBus *bus; bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); g_signal_connect (bus, "message", (GCallback) bus_message_cb, mainloop); g_timeout_add (100, (GSourceFunc) ges_renderer_print_progress, NULL); gst_bus_add_signal_watch (bus); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); g_main_loop_run (mainloop); g_main_loop_unref (mainloop); return 0; }
static void ges_project_set_uri (GESProject * project, const gchar * uri) { GESProjectPrivate *priv; g_return_if_fail (GES_IS_PROJECT (project)); priv = project->priv; if (priv->uri) { GST_WARNING_OBJECT (project, "Trying to rest URI, this is prohibited"); return; } if (uri == NULL || !gst_uri_is_valid (uri)) { GST_LOG_OBJECT (project, "Invalid URI: %s", uri); return; } priv->uri = g_strdup (uri); /* We use that URI as ID */ ges_asset_set_id (GES_ASSET (project), uri); return; }
static gboolean create_asset (AssetUri * asset_uri) { asset_uri->asset = GES_ASSET (ges_uri_clip_asset_request_sync (asset_uri->uri, NULL)); g_main_loop_quit (mainloop); return FALSE; }
static gboolean _load_project (GESProject * project, GESTimeline * timeline, GError ** error) { GError *lerr = NULL; GESProjectPrivate *priv; GESFormatter *formatter; priv = GES_PROJECT (project)->priv; if (priv->uri == NULL) { EmitLoadedInIdle *data = g_slice_new (EmitLoadedInIdle); GST_LOG_OBJECT (project, "%s, Loading an empty timeline %s" " as no URI set yet", GST_OBJECT_NAME (timeline), ges_asset_get_id (GES_ASSET (project))); data->timeline = gst_object_ref (timeline); data->project = gst_object_ref (project); /* Make sure the signal is emitted after the functions ends */ g_idle_add ((GSourceFunc) _emit_loaded_in_idle, data); return TRUE; } if (priv->formatter_asset == NULL) priv->formatter_asset = _find_formatter_asset_for_uri (priv->uri); if (priv->formatter_asset == NULL) goto failed; formatter = GES_FORMATTER (ges_asset_extract (priv->formatter_asset, &lerr)); if (lerr) { GST_WARNING_OBJECT (project, "Could not create the formatter: %s", (*error)->message); goto failed; } ges_project_add_formatter (GES_PROJECT (project), formatter); ges_formatter_load_from_uri (formatter, timeline, priv->uri, &lerr); if (lerr) { GST_WARNING_OBJECT (project, "Could not load the timeline," " returning: %s", lerr->message); goto failed; } return TRUE; failed: if (lerr) g_propagate_error (error, lerr); return FALSE; }
/* GESAsset vmethod implementation */ static GESExtractable * ges_project_extract (GESAsset * project, GError ** error) { GESTimeline *timeline = g_object_new (GES_TYPE_TIMELINE, NULL); ges_extractable_set_asset (GES_EXTRACTABLE (timeline), GES_ASSET (project)); if (_load_project (GES_PROJECT (project), timeline, error)) return GES_EXTRACTABLE (timeline); gst_object_unref (timeline); return NULL; }
/** * ges_uri_clip_new: * @uri: the URI the source should control * * Creates a new #GESUriClip for the provided @uri. * * Returns: (transfer floating) (nullable): The newly created #GESUriClip, or * %NULL if there was an error. */ GESUriClip * ges_uri_clip_new (const gchar * uri) { GESAsset *asset = GES_ASSET (ges_uri_clip_asset_request_sync (uri, NULL)); GESUriClip *res = NULL; if (asset) { res = GES_URI_CLIP (ges_asset_extract (asset, NULL)); gst_object_unref (asset); } else GST_ERROR ("Could not create asset for uri: %s", uri); return res; }
static gboolean initable_init (GInitable * initable, GCancellable * cancellable, GError ** error) { gboolean ret; GESAsset *asset = GES_ASSET (initable); ges_asset_cache_put (gst_object_ref (asset), NULL); ret = ges_asset_cache_set_loaded (asset->priv->extractable_type, asset->priv->id, NULL); g_clear_error (error); return ret; }
/** * ges_project_load: * @project: A #GESProject that has an @uri set already * @timeline: A blank timeline to load @project into * @error: (out) (allow-none): An error to be set in case something wrong happens or %NULL * * Loads @project into @timeline * * Returns: %TRUE if the project could be loaded %FALSE otherwize. */ gboolean ges_project_load (GESProject * project, GESTimeline * timeline, GError ** error) { g_return_val_if_fail (GES_IS_TIMELINE (timeline), FALSE); g_return_val_if_fail (GES_IS_PROJECT (project), FALSE); g_return_val_if_fail (ges_project_get_uri (project), FALSE); g_return_val_if_fail ( (ges_extractable_get_asset (GES_EXTRACTABLE (timeline)) == NULL), FALSE); if (!_load_project (project, timeline, error)) return FALSE; ges_extractable_set_asset (GES_EXTRACTABLE (timeline), GES_ASSET (project)); return TRUE; }
static void ges_asset_finalize (GObject * object) { GESAssetPrivate *priv = GES_ASSET (object)->priv; if (priv->id) g_free (priv->id); if (priv->proxied_asset_id) g_free (priv->proxied_asset_id); if (priv->error) g_error_free (priv->error); G_OBJECT_CLASS (ges_asset_parent_class)->finalize (object); }
/* GObject virtual methods implementation */ static void ges_asset_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { GESAsset *asset = GES_ASSET (object); switch (property_id) { case PROP_TYPE: g_value_set_gtype (value, asset->priv->extractable_type); break; case PROP_ID: g_value_set_string (value, asset->priv->id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } }
/** * ges_project_list_assets: * @project: A #GESProject * @filter: Type of assets to list, #GES_TYPE_EXTRACTABLE will list * all assets * * List all @asset contained in @project filtering per extractable_type * as defined by @filter. It copies the asset and thus will not be updated * in time. * * Returns: (transfer full) (element-type GESAsset): The list of * #GESAsset the object contains */ GList * ges_project_list_assets (GESProject * project, GType filter) { GList *ret = NULL; GHashTableIter iter; gpointer key, value; g_return_val_if_fail (GES_IS_PROJECT (project), NULL); g_hash_table_iter_init (&iter, project->priv->assets); while (g_hash_table_iter_next (&iter, &key, &value)) { if (g_type_is_a (ges_asset_get_extractable_type (GES_ASSET (value)), filter)) ret = g_list_append (ret, gst_object_ref (value)); } return ret; }
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 async_initable_init_async (GAsyncInitable * initable, gint io_priority, GCancellable * cancellable, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *simple; GError *error = NULL; GESAsset *asset = GES_ASSET (initable); simple = g_simple_async_result_new (G_OBJECT (asset), callback, user_data, ges_asset_request_async); ges_asset_cache_put (asset, simple); switch (GES_ASSET_GET_CLASS (asset)->start_loading (asset, &error)) { case GES_ASSET_LOADING_ERROR: { if (error == NULL) g_set_error (&error, GES_ERROR, GES_ERROR_ASSET_LOADING, "Could not start loading asset"); /* FIXME Define error code */ ges_asset_cache_set_loaded (asset->priv->extractable_type, asset->priv->id, error); g_error_free (error); return; } case GES_ASSET_LOADING_OK: { ges_asset_cache_set_loaded (asset->priv->extractable_type, asset->priv->id, error); return; } case GES_ASSET_LOADING_ASYNC: /* If Async.... let it go */ break; } }
/* A image sequence test */ int main (int argc, gchar ** argv) { GError *err = NULL; GOptionContext *ctx; GESPipeline *pipeline; GESTimeline *timeline; GESAsset *asset; GESLayer *layer; GMainLoop *mainloop; GESTrack *track; gint duration = 10; gchar *filepattern = NULL; GOptionEntry options[] = { {"duration", 'd', 0, G_OPTION_ARG_INT, &duration, "duration to use from the file (in seconds, default:10s)", "seconds"}, {"pattern-url", 'u', 0, G_OPTION_ARG_FILENAME, &filepattern, "Pattern of the files. i.e. multifile:///foo/%04d.jpg", "pattern-url"}, {NULL} }; ctx = g_option_context_new ("- Plays an image sequence"); g_option_context_add_main_entries (ctx, options, NULL); g_option_context_add_group (ctx, gst_init_get_option_group ()); if (!g_option_context_parse (ctx, &argc, &argv, &err)) { g_print ("Error initializing %s\n", err->message); exit (1); } if (filepattern == NULL) { g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL)); exit (0); } g_option_context_free (ctx); gst_init (&argc, &argv); ges_init (); timeline = ges_timeline_new (); track = GES_TRACK (ges_video_track_new ()); ges_timeline_add_track (timeline, track); layer = ges_layer_new (); if (!ges_timeline_add_layer (timeline, layer)) return -1; asset = GES_ASSET (ges_uri_clip_asset_request_sync (filepattern, &err)); ges_layer_add_asset (layer, asset, 0, 0, 5 * GST_SECOND, GES_TRACK_TYPE_VIDEO); pipeline = ges_pipeline_new (); if (!ges_pipeline_set_timeline (pipeline, timeline)) return -1; gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); mainloop = g_main_loop_new (NULL, FALSE); g_timeout_add_seconds (4, (GSourceFunc) g_main_loop_quit, mainloop); g_main_loop_run (mainloop); return 0; }
/** * ges_project_save: * @project: A #GESProject to save * @timeline: The #GESTimeline to save, it must have been extracted from @project * @uri: The uri where to save @project and @timeline * @formatter_asset: (allow-none): The formatter asset to use or %NULL. If %NULL, * will try to save in the same format as the one from which the timeline as been loaded * or default to the formatter with highest rank * @overwrite: %TRUE to overwrite file if it exists * @error: (out) (allow-none): An error to be set in case something wrong happens or %NULL * * Save the timeline of @project to @uri. You should make sure that @timeline * is one of the timelines that have been extracted from @project * (using ges_asset_extract (@project);) * * Returns: %TRUE if the project could be save, %FALSE otherwize */ gboolean ges_project_save (GESProject * project, GESTimeline * timeline, const gchar * uri, GESAsset * formatter_asset, gboolean overwrite, GError ** error) { GESAsset *tl_asset; gboolean ret = TRUE; GESFormatter *formatter = NULL; g_return_val_if_fail (GES_IS_PROJECT (project), FALSE); g_return_val_if_fail (formatter_asset == NULL || g_type_is_a (ges_asset_get_extractable_type (formatter_asset), GES_TYPE_FORMATTER), FALSE); g_return_val_if_fail ((error == NULL || *error == NULL), FALSE); tl_asset = ges_extractable_get_asset (GES_EXTRACTABLE (timeline)); if (tl_asset == NULL && project->priv->uri == NULL) { GESAsset *asset = ges_asset_cache_lookup (GES_TYPE_PROJECT, uri); if (asset) { GST_WARNING_OBJECT (project, "Trying to save project to %s but we already" "have %" GST_PTR_FORMAT " for that uri, can not save", uri, asset); goto out; } GST_DEBUG_OBJECT (project, "Timeline %" GST_PTR_FORMAT " has no asset" " we have no uri set, so setting ourself as asset", timeline); ges_extractable_set_asset (GES_EXTRACTABLE (timeline), GES_ASSET (project)); } else if (tl_asset != GES_ASSET (project)) { GST_WARNING_OBJECT (project, "Timeline %" GST_PTR_FORMAT " not created by this project can not save", timeline); ret = FALSE; goto out; } if (formatter_asset == NULL) formatter_asset = gst_object_ref (ges_formatter_get_default ()); formatter = GES_FORMATTER (ges_asset_extract (formatter_asset, error)); if (formatter == NULL) { GST_WARNING_OBJECT (project, "Could not create the formatter %p %s: %s", formatter_asset, ges_asset_get_id (formatter_asset), (error && *error) ? (*error)->message : "Unknown Error"); ret = FALSE; goto out; } ges_project_add_formatter (project, formatter); ret = ges_formatter_save_to_uri (formatter, timeline, uri, overwrite, error); if (ret && project->priv->uri == NULL) ges_project_set_uri (project, uri); out: if (formatter_asset) gst_object_unref (formatter_asset); ges_project_remove_formatter (project, formatter); return ret; }
static void ges_effect_asset_constructed (GObject * object) { _fill_track_type (GES_ASSET (object)); }