From 1d397591af2c298c721d9823133ef5d10b09b2a6 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 11 Jan 2013 11:49:02 -0300 Subject: [PATCH] project: Handle assets that are being loaded API: ges_project_get_loading_assets --- docs/libs/ges-sections.txt | 1 + ges/ges-asset.c | 3 ++- ges/ges-base-xml-formatter.c | 4 ++- ges/ges-internal.h | 3 +++ ges/ges-pitivi-formatter.c | 3 +++ ges/ges-project.c | 51 ++++++++++++++++++++++++++++++++++-- ges/ges-project.h | 3 +++ ges/ges-timeline-layer.c | 7 +++-- tests/check/ges/project.c | 2 ++ 9 files changed, 71 insertions(+), 6 deletions(-) diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index 7d34af32c8..44349d5fe2 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -1065,6 +1065,7 @@ ges_project_get_uri ges_project_new ges_project_add_encoding_profile ges_project_list_encoding_profiles +ges_project_get_loading_assets GESProjectPrivate GES_PROJECT diff --git a/ges/ges-asset.c b/ges/ges-asset.c index 798265efb6..990c2f9def 100644 --- a/ges/ges-asset.c +++ b/ges/ges-asset.c @@ -952,7 +952,8 @@ ges_asset_extract (GESAsset * self, GError ** error) if (extractable == NULL) return NULL; - ges_extractable_set_asset (extractable, self); + if (ges_extractable_get_asset (extractable) == NULL) + ges_extractable_set_asset (extractable, self); return extractable; } diff --git a/ges/ges-base-xml-formatter.c b/ges/ges-base-xml-formatter.c index 958991ad2d..40268b1c39 100644 --- a/ges/ges-base-xml-formatter.c +++ b/ges/ges-base-xml-formatter.c @@ -586,7 +586,6 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, PendingAsset * passet) /* And now add to the project */ ges_project_add_asset (self->project, asset); - gst_object_unref (self); _free_pending_asset (priv, passet); @@ -668,8 +667,11 @@ ges_base_xml_formatter_add_asset (GESBaseXmlFormatter * self, passet->formatter = gst_object_ref (self); if (properties) passet->properties = gst_structure_copy (properties); + ges_asset_request_async (extractable_type, id, NULL, (GAsyncReadyCallback) new_asset_cb, passet); + ges_project_add_loading_asset (GES_FORMATTER (self)->project, + extractable_type, id); priv->pending_assets = g_list_prepend (priv->pending_assets, passet); } diff --git a/ges/ges-internal.h b/ges/ges-internal.h index c555111fd5..71deb19df8 100644 --- a/ges/ges-internal.h +++ b/ges/ges-internal.h @@ -135,6 +135,9 @@ G_GNUC_INTERNAL gboolean ges_project_set_loaded (GESProject * G_GNUC_INTERNAL gchar * ges_project_try_updating_id (GESProject *self, GESAsset *asset, GError *error); +G_GNUC_INTERNAL void ges_project_add_loading_asset (GESProject *project, + GType extractable_type, + const gchar *id); /************************************************ * * diff --git a/ges/ges-pitivi-formatter.c b/ges/ges-pitivi-formatter.c index 8bc2787ebd..780d47961f 100644 --- a/ges/ges-pitivi-formatter.c +++ b/ges/ges-pitivi-formatter.c @@ -553,6 +553,9 @@ list_sources (GESFormatter * self) g_hash_table_insert (priv->sources_table, g_strdup (id), table); g_hash_table_insert (priv->source_uris, g_strdup (filename), g_strdup (filename)); + if (self->project) + ges_project_create_asset (self->project, filename, + GES_TYPE_TIMELINE_FILE_SOURCE); } xmlXPathFreeObject (xpathObj); diff --git a/ges/ges-project.c b/ges/ges-project.c index e44be21eea..2948737830 100644 --- a/ges/ges-project.c +++ b/ges/ges-project.c @@ -54,6 +54,8 @@ G_DEFINE_TYPE (GESProject, ges_project, GES_TYPE_ASSET); struct _GESProjectPrivate { GHashTable *assets; + /* Set of asset ID being loaded */ + GHashTable *loading_assets; GESAsset *formatter_asset; GList *formatters; @@ -248,6 +250,8 @@ _dispose (GObject * object) if (priv->assets) g_hash_table_unref (priv->assets); + if (priv->loading_assets) + g_hash_table_unref (priv->loading_assets); if (priv->formatter_asset) gst_object_unref (priv->formatter_asset); @@ -419,6 +423,8 @@ ges_project_init (GESProject * project) priv->encoding_profiles = NULL; priv->assets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, gst_object_unref); + priv->loading_assets = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, gst_object_unref); } gchar * @@ -464,6 +470,7 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, GESProject * project) if (error) { possible_id = ges_project_try_updating_id (project, source, error); if (possible_id == NULL) { + g_hash_table_remove (project->priv->loading_assets, id); g_signal_emit (project, _signals[ERROR_LOADING_ASSET], 0, error, id, ges_asset_get_extractable_type (source)); @@ -502,6 +509,17 @@ ges_project_set_loaded (GESProject * project, GESFormatter * formatter) return TRUE; } +void +ges_project_add_loading_asset (GESProject * project, GType extractable_type, + const gchar * id) +{ + GESAsset *asset; + + if ((asset = ges_asset_cache_lookup (extractable_type, id))) + g_hash_table_insert (project->priv->loading_assets, g_strdup (id), + gst_object_ref (asset)); +} + /************************************** * * * API Implementation * @@ -529,12 +547,14 @@ ges_project_create_asset (GESProject * project, const gchar * id, g_return_val_if_fail (g_type_is_a (extractable_type, GES_TYPE_EXTRACTABLE), FALSE); - if (g_hash_table_lookup (project->priv->assets, id)) + if (g_hash_table_lookup (project->priv->assets, id) || + g_hash_table_lookup (project->priv->loading_assets, id)) return FALSE; /* TODO Add a GCancellable somewhere in our API */ ges_asset_request_async (extractable_type, id, NULL, (GAsyncReadyCallback) new_asset_cb, project); + ges_project_add_loading_asset (project, extractable_type, id); return TRUE; } @@ -561,6 +581,7 @@ ges_project_add_asset (GESProject * project, GESAsset * asset) g_hash_table_insert (project->priv->assets, g_strdup (ges_asset_get_id (asset)), gst_object_ref (asset)); + g_hash_table_remove (project->priv->loading_assets, ges_asset_get_id (asset)); GST_DEBUG_OBJECT (project, "Asset added: %s", ges_asset_get_id (asset)); g_signal_emit (project, _signals[ASSET_ADDED_SIGNAL], 0, asset); @@ -584,7 +605,6 @@ ges_project_remove_asset (GESProject * project, GESAsset * asset) g_return_val_if_fail (GES_IS_PROJECT (project), FALSE); ret = g_hash_table_remove (project->priv->assets, ges_asset_get_id (asset)); - g_signal_emit (project, _signals[ASSET_REMOVED_SIGNAL], 0, asset); return ret; @@ -866,3 +886,30 @@ ges_project_list_encoding_profiles (GESProject * project) return project->priv->encoding_profiles; } + +/** + * ges_project_get_loading_assets: + * @project: A #GESProject + * + * Get the assets that are being loaded + * + * Returns: (transfer full) (element-type GES.Asset): A set of loading asset + * that will be added to @project. Note that those Asset are *not* loaded yet, + * and thus can not be used + */ +GList * +ges_project_get_loading_assets (GESProject * project) +{ + GHashTableIter iter; + gpointer key, value; + + GList *ret = NULL; + + g_return_val_if_fail (GES_IS_PROJECT (project), NULL); + + g_hash_table_iter_init (&iter, project->priv->loading_assets); + while (g_hash_table_iter_next (&iter, &key, &value)) + ret = g_list_prepend (ret, gst_object_ref (value)); + + return ret; +} diff --git a/ges/ges-project.h b/ges/ges-project.h index a47919b8de..86ef44c629 100644 --- a/ges/ges-project.h +++ b/ges/ges-project.h @@ -96,9 +96,12 @@ gboolean ges_project_create_asset (GESProject * project, const gchar *id, GType extractable_type); +GList * ges_project_get_loading_assets (GESProject * project); + gboolean ges_project_add_encoding_profile (GESProject *project, GstEncodingProfile *profile); const GList *ges_project_list_encoding_profiles (GESProject *project); + G_END_DECLS #endif /* _GES_PROJECT */ diff --git a/ges/ges-timeline-layer.c b/ges/ges-timeline-layer.c index 1b9c3287f4..e6a131a018 100644 --- a/ges/ges-timeline-layer.c +++ b/ges/ges-timeline-layer.c @@ -259,7 +259,10 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, NewAssetUData * udata) return; } } - GST_ERROR ("Asset could not be created for uri"); + + GST_ERROR ("Asset could not be created for uri %s, error: %s", + ges_asset_get_id (asset), error->message); + } else { GESProject *project = udata->layer->timeline ? GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE @@ -585,7 +588,7 @@ ges_timeline_layer_add_asset (GESTimelineLayer * layer, GST_DEBUG_OBJECT (layer, "Adding asset %s with: start: %" GST_TIME_FORMAT " inpoint: %" GST_TIME_FORMAT " duration: %" GST_TIME_FORMAT " rate %d" " track types: %d (%s)", ges_asset_get_id (asset), GST_TIME_ARGS (start), - GST_TIME_ARGS (inpoint), GST_TIME_ARGS (duration), track_types, + GST_TIME_ARGS (inpoint), GST_TIME_ARGS (duration), rate, track_types, ges_track_type_name (track_types)); tlobj = GES_TIMELINE_OBJECT (ges_asset_extract (asset, NULL)); diff --git a/tests/check/ges/project.c b/tests/check/ges/project.c index d09f8220c8..bc8059c0a6 100644 --- a/tests/check/ges/project.c +++ b/tests/check/ges/project.c @@ -294,6 +294,8 @@ GST_START_TEST (test_project_load_xges) GST_LOG ("Loading project"); timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL)); fail_unless (GES_IS_TIMELINE (timeline)); + assert_equals_int (g_list_length (ges_project_get_loading_assets (project)), + 1); g_main_loop_run (mainloop); GST_LOG ("Test first loading");