diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index 73dfffdc21..95b3ed7f7f 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -1079,6 +1079,10 @@ ges_asset_request_finish ges_asset_extract ges_asset_get_error ges_list_assets +ges_asset_set_proxy +ges_asset_list_proxies +ges_asset_get_proxy_target +ges_asset_get_proxy GESAssetPrivate GES_ASSET diff --git a/ges/ges-asset.c b/ges/ges-asset.c index 44b9895737..9feab55eea 100644 --- a/ges/ges-asset.c +++ b/ges/ges-asset.c @@ -96,6 +96,8 @@ enum PROP_0, PROP_TYPE, PROP_ID, + PROP_PROXY, + PROP_PROXY_TARGET, PROP_LAST }; @@ -115,11 +117,14 @@ struct _GESAssetPrivate GESAssetState state; GType extractable_type; - /* When a asset is proxied, instanciating it will + /* When an asset is proxied, instanciating it will * return the asset it points to */ char *proxied_asset_id; - /* The error that accured when a asset has been initialized with error */ + GList *proxies; + GESAsset *proxy_target; + + /* The error that accured when an asset has been initialized with error */ GError *error; }; @@ -314,6 +319,12 @@ ges_asset_get_property (GObject * object, guint property_id, case PROP_ID: g_value_set_string (value, asset->priv->id); break; + case PROP_PROXY: + g_value_set_object (value, ges_asset_get_proxy (asset)); + break; + case PROP_PROXY_TARGET: + g_value_set_object (value, ges_asset_get_proxy_target (asset)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -333,6 +344,12 @@ ges_asset_set_property (GObject * object, guint property_id, case PROP_ID: asset->priv->id = g_value_dup_string (value); break; + case PROP_PROXY: + ges_asset_set_proxy (asset, g_value_get_object (value)); + break; + case PROP_PROXY_TARGET: + ges_asset_set_proxy (g_value_get_object (value), asset); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -377,6 +394,14 @@ ges_asset_class_init (GESAssetClass * klass) "The unic identifier of the asset", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + _properties[PROP_PROXY] = + g_param_spec_object ("proxy", "Proxy", + "The asset default proxy.", GES_TYPE_ASSET, G_PARAM_READWRITE); + + _properties[PROP_PROXY_TARGET] = + g_param_spec_object ("proxy-target", "Proxy target", + "The target of a proxy asset.", GES_TYPE_ASSET, G_PARAM_READWRITE); + g_object_class_install_properties (object_class, PROP_LAST, _properties); klass->start_loading = ges_asset_start_loading_default; @@ -593,9 +618,10 @@ ges_asset_request_id_update (GESAsset * asset, gchar ** proposed_id, } gboolean -ges_asset_set_proxy (GESAsset * asset, const gchar * new_id) +ges_asset_try_proxy (GESAsset * asset, const gchar * new_id) { GESAssetClass *class; + if (g_strcmp0 (asset->priv->id, new_id) == 0) { GST_WARNING_OBJECT (asset, "Trying to proxy to itself (%s)," " NOT possible", new_id); @@ -609,9 +635,7 @@ ges_asset_set_proxy (GESAsset * asset, const gchar * new_id) return FALSE; } - if (asset->priv->proxied_asset_id) - g_free (asset->priv->proxied_asset_id); - + g_free (asset->priv->proxied_asset_id); asset->priv->state = ASSET_PROXIED; asset->priv->proxied_asset_id = g_strdup (new_id); @@ -619,10 +643,160 @@ ges_asset_set_proxy (GESAsset * asset, const gchar * new_id) if (class->inform_proxy) GES_ASSET_GET_CLASS (asset)->inform_proxy (asset, new_id); - GST_DEBUG_OBJECT (asset, "Now proxied to %s", new_id); + GST_DEBUG_OBJECT (asset, "Trying to proxy to %s", new_id); + return TRUE; } +static gboolean +_lookup_proxied_asset (const gchar * id, GESAssetCacheEntry * entry, + const gchar * asset_id) +{ + return !g_strcmp0 (asset_id, entry->asset->priv->proxied_asset_id); +} + +/** + * ges_asset_set_proxy: + * @asset: The #GESAsset to set proxy on + * @proxy: (allow-none): The #GESAsset that should be used as default proxy for @asset or + * %NULL if you want to use the currently set proxy. Note that an asset can proxy one and only + * one other asset. + * + * A proxying asset is an asset that can substitue the real @asset. For example if you + * have a full HD #GESUriClipAsset you might want to set a lower resolution (HD version + * of the same file) as proxy. Note that when an asset is proxied, calling + * #ges_asset_request will actually return the proxy asset. + * + * Returns: The list of proxies @asset has. Note that the default asset to be + * used is always the first in that list. + */ +gboolean +ges_asset_set_proxy (GESAsset * asset, GESAsset * proxy) +{ + g_return_val_if_fail (asset == NULL || GES_IS_ASSET (asset), FALSE); + g_return_val_if_fail (proxy == NULL || GES_IS_ASSET (proxy), FALSE); + g_return_val_if_fail (asset != proxy, FALSE); + + if (!proxy) { + if (asset->priv->error) { + GST_ERROR_OBJECT (asset, + "Proxy was loaded with error (%s), it should not be 'unproxied'", + asset->priv->error->message); + + return FALSE; + } + + if (asset->priv->proxies) { + GESAsset *old_proxy = GES_ASSET (asset->priv->proxies->data); + + GES_ASSET (asset->priv->proxies->data)->priv->proxy_target = NULL; + g_object_notify_by_pspec (G_OBJECT (old_proxy), + _properties[PROP_PROXY_TARGET]); + } + + GST_DEBUG_OBJECT (asset, "%s not proxied anymore", asset->priv->id); + asset->priv->state = ASSET_INITIALIZED; + g_object_notify_by_pspec (G_OBJECT (asset), _properties[PROP_PROXY]); + + return TRUE; + } + + if (asset == NULL) { + GHashTable *entries_table; + GESAssetCacheEntry *entry; + + entries_table = g_hash_table_lookup (type_entries_table, + _extractable_type_name (proxy->priv->extractable_type)); + entry = g_hash_table_find (entries_table, (GHRFunc) _lookup_proxied_asset, + (gpointer) ges_asset_get_id (proxy)); + + if (!entry) { + GST_DEBUG_OBJECT (asset, "Not proxying any asset"); + return FALSE; + } + + asset = entry->asset; + while (asset->priv->proxies) + asset = asset->priv->proxies->data; + } + + if (proxy->priv->proxy_target) { + GST_ERROR_OBJECT (asset, + "Trying to use %s as a proxy, but it is already proxying %s", + proxy->priv->id, proxy->priv->proxy_target->priv->id); + } + + if (g_list_find (proxy->priv->proxies, asset)) { + GST_ERROR_OBJECT (asset, "Trying to setup a circular proxying dependency!"); + + return FALSE; + } + + if (g_list_find (asset->priv->proxies, proxy)) { + GST_INFO_OBJECT (asset, + "%" GST_PTR_FORMAT " already marked as proxy, moving to first", proxy); + GES_ASSET (asset->priv->proxies->data)->priv->proxy_target = NULL; + asset->priv->proxies = g_list_remove (asset->priv->proxies, proxy); + } + + GST_INFO ("%s is now proxied by %s", asset->priv->id, proxy->priv->id); + asset->priv->proxies = g_list_prepend (asset->priv->proxies, proxy); + proxy->priv->proxy_target = asset; + g_object_notify_by_pspec (G_OBJECT (proxy), _properties[PROP_PROXY_TARGET]); + + asset->priv->state = ASSET_PROXIED; + g_object_notify_by_pspec (G_OBJECT (asset), _properties[PROP_PROXY]); + + return TRUE; +} + +/** + * ges_asset_list_proxies: + * @asset: The #GESAsset to get proxies from + * + * Returns: The list of proxies @asset has. Note that the default asset to be + * used is always the first in that list. + */ +GList * +ges_asset_list_proxies (GESAsset * asset) +{ + g_return_val_if_fail (GES_IS_ASSET (asset), NULL); + + return asset->priv->proxies; +} + +/** + * ges_asset_get_proxy: + * @asset: The #GESAsset to get currenlty used proxy + * + * Returns: (transfer none): The proxy in use for @asset + */ +GESAsset * +ges_asset_get_proxy (GESAsset * asset) +{ + g_return_val_if_fail (GES_IS_ASSET (asset), NULL); + + if (asset->priv->state == ASSET_PROXIED && asset->priv->proxies) { + return asset->priv->proxies->data; + } + + return NULL; +} + +/** + * ges_asset_get_proxy_target: + * @proxy: The #GESAsset from which to get the the asset it proxies. + * + * Returns: (transfer none): The #GESAsset that is proxied by @proxy + */ +GESAsset * +ges_asset_get_proxy_target (GESAsset * proxy) +{ + g_return_val_if_fail (GES_IS_ASSET (proxy), NULL); + + return proxy->priv->proxy_target; +} + /* Caution, this method should be used in rare cases (ie: for the project * as we can change its ID from a useless one to a proper URI). In most * cases you want to update the ID creating a proxy @@ -751,19 +925,21 @@ ges_asset_request (GType extractable_type, const gchar * id, GError ** error) asset = NULL; goto done; case ASSET_PROXIED: - asset = - ges_asset_cache_lookup (asset->priv->extractable_type, - asset->priv->proxied_asset_id); - if (asset == NULL) { - GST_ERROR ("Asset against a asset we do not" + if (asset->priv->proxies == NULL) { + GST_ERROR ("Proxied against an asset we do not" " have in cache, something massively screwed"); goto done; } + + asset = asset->priv->proxies->data; + while (ges_asset_get_proxy (asset)) + asset = ges_asset_get_proxy (asset); + break; case ASSET_INITIALIZED_WITH_ERROR: GST_WARNING_OBJECT (asset, "Initialized with error, not returning"); - if (asset->priv->error) + if (asset->priv->error && error) *error = g_error_copy (asset->priv->error); asset = NULL; goto done; @@ -866,7 +1042,7 @@ ges_asset_request_async (GType extractable_type, real_id = g_strdup (id); } - /* Check if we already have a asset for this ID */ + /* Check if we already have an asset for this ID */ asset = ges_asset_cache_lookup (extractable_type, real_id); if (asset) { GTask *task = g_task_new (asset, NULL, callback, user_data); @@ -892,12 +1068,12 @@ ges_asset_request_async (GType extractable_type, goto done; case ASSET_PROXIED: - asset = - ges_asset_cache_lookup (asset->priv->extractable_type, - asset->priv->proxied_asset_id); + asset = ges_asset_get_proxy (asset); + if (asset == NULL) { - GST_ERROR ("Asset proxied against a asset we do not" - " have in cache, something massively screwed"); + GST_ERROR ("Asset %s proxied against an asset (%s) we do not" + " have in cache, something massively screwed", + asset->priv->id, asset->priv->proxied_asset_id); goto done; } diff --git a/ges/ges-asset.h b/ges/ges-asset.h index 337df20c89..64a12c2e96 100644 --- a/ges/ges-asset.h +++ b/ges/ges-asset.h @@ -74,6 +74,10 @@ struct _GESAssetClass /* Let subclasses know that we proxied an asset */ void (*inform_proxy) (GESAsset *self, const gchar *proxy_id); + + void (*proxied) (GESAsset *self, + GESAsset *proxy); + /* Ask subclasses for a new ID for @self when the asset failed loading * This function returns %FALSE when the ID could be updated or %TRUE * otherwize */ @@ -100,5 +104,11 @@ GESExtractable * ges_asset_extract (GESAsset * self, GError **error); GList * ges_list_assets (GType filter); + +gboolean ges_asset_set_proxy (GESAsset *asset, GESAsset *proxy); +GList * ges_asset_list_proxies (GESAsset *asset); +GESAsset * ges_asset_get_proxy_target(GESAsset *proxy); +GESAsset * ges_asset_get_proxy (GESAsset *asset); + G_END_DECLS #endif /* _GES_ASSET */ diff --git a/ges/ges-base-xml-formatter.c b/ges/ges-base-xml-formatter.c index bf176d8e4c..106aab1c58 100644 --- a/ges/ges-base-xml-formatter.c +++ b/ges/ges-base-xml-formatter.c @@ -100,6 +100,7 @@ typedef struct PendingAsset GESFormatter *formatter; gchar *metadatas; GstStructure *properties; + gchar *proxy_id; } PendingAsset; struct _GESBaseXmlFormatterPrivate @@ -467,6 +468,7 @@ _add_all_groups (GESFormatter * self) static void _loading_done (GESFormatter * self) { + GList *assets, *tmp; GESBaseXmlFormatterPrivate *priv = GES_BASE_XML_FORMATTER (self)->priv; _add_all_groups (self); @@ -478,6 +480,13 @@ _loading_done (GESFormatter * self) ges_timeline_set_auto_transition (self->timeline, priv->timeline_auto_transition); + /* Go over all assets and make sure that all proxies we were 'trying' to set are finally + * properly set */ + assets = ges_project_list_assets (self->project, GES_TYPE_EXTRACTABLE); + for (tmp = assets; tmp; tmp = tmp->next) { + ges_asset_set_proxy (NULL, tmp->data); + } + g_hash_table_foreach (priv->layers, (GHFunc) _set_auto_transition, NULL); ges_project_set_loaded (self->project, self); } @@ -623,8 +632,8 @@ _free_pending_clip (GESBaseXmlFormatterPrivate * priv, PendingClip * pend) static void _free_pending_asset (GESBaseXmlFormatterPrivate * priv, PendingAsset * passet) { - if (passet->metadatas) - g_free (passet->metadatas); + g_free (passet->metadatas); + g_free (passet->proxy_id); if (passet->properties) gst_structure_free (passet->properties); @@ -722,6 +731,13 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, PendingAsset * passet) goto done; } + if (passet->proxy_id) { + /* We set the URI to be used as a proxy, + * this will finally be set as the proxy when we + * are done loading all assets */ + ges_asset_try_proxy (asset, passet->proxy_id); + } + /* now that we have the GESAsset, we create the GESClips */ pendings = g_hash_table_lookup (priv->assetid_pendingclips, id); GST_DEBUG_OBJECT (self, "Asset created with ID %s, now creating pending " @@ -825,7 +841,7 @@ _create_profile (GESBaseXmlFormatter * self, void ges_base_xml_formatter_add_asset (GESBaseXmlFormatter * self, const gchar * id, GType extractable_type, GstStructure * properties, - const gchar * metadatas, GError ** error) + const gchar * metadatas, const gchar * proxy_id, GError ** error) { PendingAsset *passet; GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self); @@ -835,6 +851,7 @@ ges_base_xml_formatter_add_asset (GESBaseXmlFormatter * self, passet = g_slice_new0 (PendingAsset); passet->metadatas = g_strdup (metadatas); + passet->proxy_id = g_strdup (proxy_id); passet->formatter = gst_object_ref (self); if (properties) passet->properties = gst_structure_copy (properties); diff --git a/ges/ges-internal.h b/ges/ges-internal.h index 1e19eb1616..cde566b83f 100644 --- a/ges/ges-internal.h +++ b/ges/ges-internal.h @@ -143,7 +143,7 @@ GESAsset* ges_asset_cache_lookup(GType extractable_type, const gchar * id); gboolean -ges_asset_set_proxy (GESAsset *asset, const gchar *new_id); +ges_asset_try_proxy (GESAsset *asset, const gchar *new_id); G_GNUC_INTERNAL gboolean ges_asset_request_id_update (GESAsset *asset, gchar **proposed_id, @@ -224,6 +224,7 @@ G_GNUC_INTERNAL void ges_base_xml_formatter_add_asset (GESBaseXmlFormatte GType extractable_type, GstStructure *properties, const gchar *metadatas, + const gchar *proxy_id, GError **error); G_GNUC_INTERNAL void ges_base_xml_formatter_add_layer (GESBaseXmlFormatter *self, GType extractable_type, diff --git a/ges/ges-project.c b/ges/ges-project.c index 72619af4a8..15025f6e33 100644 --- a/ges/ges-project.c +++ b/ges/ges-project.c @@ -595,7 +595,7 @@ ges_project_try_updating_id (GESProject * project, GESAsset * asset, if (new_id) { GST_DEBUG_OBJECT (project, "new id found: %s", new_id); - if (!ges_asset_set_proxy (asset, new_id)) { + if (!ges_asset_try_proxy (asset, new_id)) { g_free (new_id); new_id = NULL; } @@ -633,6 +633,7 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, GESProject * project) return; } + ges_asset_set_proxy (NULL, asset); ges_project_add_asset (project, asset); if (asset) gst_object_unref (asset); @@ -766,6 +767,10 @@ ges_project_create_asset_sync (GESProject * project, const gchar * id, if (asset) { retry = FALSE; + if ((!g_hash_table_lookup (project->priv->assets, + ges_asset_get_id (asset)))) + g_signal_emit (project, _signals[ASSET_LOADING_SIGNAL], 0, asset); + if (possible_id) { g_free (possible_id); ges_uri_assets_validate_uri (id); @@ -776,6 +781,9 @@ ges_project_create_asset_sync (GESProject * project, const gchar * id, GESAsset *tmpasset; tmpasset = ges_asset_cache_lookup (extractable_type, id); + g_signal_emit (project, _signals[ASSET_LOADING_SIGNAL], 0, tmpasset); + g_signal_emit (project, _signals[ERROR_LOADING_ASSET], 0, *error, id, + extractable_type); possible_id = ges_project_try_updating_id (project, tmpasset, *error); if (possible_id == NULL) @@ -788,6 +796,9 @@ ges_project_create_asset_sync (GESProject * project, const gchar * id, } } + if (!ges_asset_get_proxy_target (asset)) + ges_asset_set_proxy (NULL, asset); + ges_project_add_asset (project, asset); return asset; diff --git a/ges/ges-uri-clip.c b/ges/ges-uri-clip.c index 652d1c63bf..0069227e61 100644 --- a/ges/ges-uri-clip.c +++ b/ges/ges-uri-clip.c @@ -37,6 +37,7 @@ #include "ges-image-source.h" #include "ges-audio-test-source.h" #include "ges-multi-file-source.h" +#include "ges-layer.h" static void ges_extractable_interface_init (GESExtractableInterface * iface); @@ -260,13 +261,19 @@ extractable_get_id (GESExtractable * self) return g_strdup (GES_URI_CLIP (self)->priv->uri); } -static void +static gboolean extractable_set_asset (GESExtractable * self, GESAsset * asset) { + gboolean res = TRUE; GESUriClip *uriclip = GES_URI_CLIP (self); - GESUriClipAsset *filesource_asset = GES_URI_CLIP_ASSET (asset); + GESUriClipAsset *filesource_asset; GESClip *clip = GES_CLIP (self); + GESLayer *layer = ges_clip_get_layer (clip); + GList *tmp; + g_return_val_if_fail (GES_IS_URI_CLIP_ASSET (asset), FALSE); + + filesource_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 (filesource_asset)); @@ -277,13 +284,35 @@ extractable_set_asset (GESExtractable * self, GESAsset * asset) 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_clip_asset_get_supported_formats (GES_CLIP_ASSET + (filesource_asset))); } GES_TIMELINE_ELEMENT (uriclip)->asset = asset; + + if (layer) { + 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); + + ges_track_remove_element (track, tmp->data); + } + } + + gst_object_ref (clip); + ges_layer_remove_clip (layer, clip); + res = ges_layer_add_clip (layer, clip); + 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; } static void @@ -293,7 +322,9 @@ ges_extractable_interface_init (GESExtractableInterface * iface) iface->check_id = (GESExtractableCheckId) extractable_check_id; iface->get_parameters_from_id = extractable_get_parameters_from_id; iface->get_id = extractable_get_id; - iface->set_asset = extractable_set_asset; + iface->get_id = extractable_get_id; + iface->can_update_asset = TRUE; + iface->set_asset_full = extractable_set_asset; } static void diff --git a/ges/ges-xml-formatter.c b/ges/ges-xml-formatter.c index 07588f657a..b040d7787f 100644 --- a/ges/ges-xml-formatter.c +++ b/ges/ges-xml-formatter.c @@ -32,8 +32,8 @@ G_DEFINE_TYPE (GESXmlFormatter, ges_xml_formatter, GES_TYPE_BASE_XML_FORMATTER); #define API_VERSION 0 -#define MINOR_VERSION 2 -#define VERSION 0.2 +#define MINOR_VERSION 3 +#define VERSION 0.3 #define COLLECT_STR_OPT (G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL) @@ -272,14 +272,15 @@ _parse_asset (GMarkupParseContext * context, const gchar * element_name, { GType extractable_type; const gchar *id, *extractable_type_name, *metadatas = NULL, *properties = - NULL; + NULL, *proxy_id = NULL; if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error, G_MARKUP_COLLECT_STRING, "id", &id, G_MARKUP_COLLECT_STRING, "extractable-type-name", &extractable_type_name, COLLECT_STR_OPT, "properties", &properties, - COLLECT_STR_OPT, "metadatas", &metadatas, G_MARKUP_COLLECT_INVALID)) + COLLECT_STR_OPT, "metadatas", &metadatas, + COLLECT_STR_OPT, "proxy-id", &proxy_id, G_MARKUP_COLLECT_INVALID)) return; extractable_type = g_type_from_name (extractable_type_name); @@ -299,7 +300,7 @@ _parse_asset (GMarkupParseContext * context, const gchar * element_name, props = gst_structure_from_string (properties, NULL); ges_base_xml_formatter_add_asset (GES_BASE_XML_FORMATTER (self), id, - extractable_type, props, metadatas, error); + extractable_type, props, metadatas, proxy_id, error); if (props) gst_structure_free (props); } @@ -910,10 +911,10 @@ _serialize_properties (GObject * object, const gchar * fieldname, ...) } static inline void -_save_assets (GString * str, GESProject * project) +_save_assets (GESXmlFormatter * self, GString * str, GESProject * project) { char *properties, *metas; - GESAsset *asset; + GESAsset *asset, *proxy; GList *assets, *tmp; assets = ges_project_list_assets (project, GES_TYPE_EXTRACTABLE); @@ -923,10 +924,27 @@ _save_assets (GString * str, GESProject * project) metas = ges_meta_container_metas_to_string (GES_META_CONTAINER (asset)); append_escaped (str, g_markup_printf_escaped - (" \n", + (" next) + tmp->next = g_list_last (assets); + } + + self->priv->min_version = MAX (self->priv->min_version, 3); + } + g_string_append (str, "/>\n"); g_free (properties); g_free (metas); } @@ -1433,6 +1451,7 @@ _save (GESFormatter * formatter, GESTimeline * timeline, GError ** error) gchar *projstr = NULL, *version; gchar *properties = NULL, *metas = NULL; + GESXmlFormatter *self = GES_XML_FORMATTER (formatter); GESXmlFormatterPrivate *priv; @@ -1455,10 +1474,10 @@ _save (GESFormatter * formatter, GESTimeline * timeline, GError ** error) g_string_append (str, " \n"); g_string_append (str, " \n"); - _save_assets (str, project); + _save_assets (self, str, project); g_string_append (str, " \n"); - _save_timeline (GES_XML_FORMATTER (formatter), str, timeline); + _save_timeline (self, str, timeline); g_string_append (str, "\n"); projstr = g_strdup_printf ("\n", API_VERSION, diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 039291f1e3..222910575d 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -35,6 +35,7 @@ SUPPRESSIONS = $(top_srcdir)/common/gst.supp # $(srcdir)/gst-plugins-bad.supp clean-local: clean-local-check check_PROGRAMS = \ + ges/asset \ ges/backgroundsource\ ges/basic \ ges/layer \ diff --git a/tests/check/ges/asset.c b/tests/check/ges/asset.c index 00caca11bb..f760aaad6e 100644 --- a/tests/check/ges/asset.c +++ b/tests/check/ges/asset.c @@ -1,6 +1,7 @@ /* GStreamer Editing Services * * Copyright (C) 2012 Volodymyr Rudyi + * Copyright (C) 2015 Thibault Saunier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -18,8 +19,9 @@ * Boston, MA 02111-1307, USA. */ -#include "../../../ges/ges-internal.h" +#include "test-utils.h" #undef GST_CAT_DEFAULT +#include "../../../ges/ges-internal.h" #include #include @@ -53,7 +55,7 @@ GST_START_TEST (test_basic) GST_END_TEST; -GST_START_TEST (test_change_asset) +GST_START_TEST (test_transition_change_asset) { gchar *id; GESAsset *a; @@ -96,6 +98,43 @@ GST_START_TEST (test_change_asset) GST_END_TEST; +GST_START_TEST (test_uri_clip_change_asset) +{ + GESAsset *asset, *asset1; + GESExtractable *extractable; + GESLayer *layer = ges_layer_new (); + gchar *uri = ges_test_file_uri ("audio_video.ogg"); + gchar *uri1 = ges_test_file_uri ("audio_only.ogg"); + GESTimeline *timeline = ges_timeline_new_audio_video (); + + ges_timeline_add_layer (timeline, layer); + + gst_init (NULL, NULL); + ges_init (); + + asset = GES_ASSET (ges_uri_clip_asset_request_sync (uri, NULL)); + + fail_unless (GES_IS_ASSET (asset)); + fail_unless_equals_string (ges_asset_get_id (asset), uri); + + extractable = GES_EXTRACTABLE (ges_layer_add_asset (layer, + asset, 0, 0, GST_CLOCK_TIME_NONE, GES_TRACK_TYPE_UNKNOWN)); + fail_unless (ges_extractable_get_asset (extractable) == asset); + gst_object_unref (asset); + + /* Now try to set the a and see if the vtype is properly updated */ + asset1 = GES_ASSET (ges_uri_clip_asset_request_sync (uri1, NULL)); + fail_unless_equals_int (g_list_length (GES_CONTAINER_CHILDREN (extractable)), + 2); + fail_unless (ges_extractable_set_asset (extractable, asset1)); + fail_unless_equals_int (g_list_length (GES_CONTAINER_CHILDREN (extractable)), + 1); + + gst_object_unref (extractable); +} + +GST_END_TEST; + GST_START_TEST (test_list_asset) { GList *assets; @@ -128,7 +167,8 @@ GST_START_TEST (test_proxy_asset) nothing = ges_asset_cache_lookup (GES_TYPE_EFFECT, "nothing"); fail_unless (nothing != NULL); - fail_unless (ges_asset_set_proxy (nothing, "identity")); + fail_unless (ges_asset_try_proxy (nothing, "identity")); + fail_unless (ges_asset_set_proxy (NULL, identity)); nothing_at_all = ges_asset_request (GES_TYPE_EFFECT, "nothing_at_all", NULL); fail_if (nothing_at_all); @@ -137,7 +177,13 @@ GST_START_TEST (test_proxy_asset) fail_unless (nothing_at_all != NULL); /* Now we proxy nothing_at_all to nothing which is itself proxied to identity */ - fail_unless (ges_asset_set_proxy (nothing_at_all, "nothing")); + fail_unless (ges_asset_try_proxy (nothing_at_all, "nothing")); + fail_unless (ges_asset_set_proxy (NULL, nothing)); + fail_unless_equals_int (g_list_length (ges_asset_list_proxies + (nothing_at_all)), 1); + + fail_unless_equals_pointer (ges_asset_get_proxy_target (nothing), + nothing_at_all); /* If we request nothing_at_all we should get the good proxied identity */ nothing_at_all = ges_asset_request (GES_TYPE_EFFECT, "nothing_at_all", NULL); @@ -161,7 +207,8 @@ ges_suite (void) /* Must be first until we implement deinit */ tcase_add_test (tc_chain, test_list_asset); tcase_add_test (tc_chain, test_basic); - tcase_add_test (tc_chain, test_change_asset); + tcase_add_test (tc_chain, test_transition_change_asset); + tcase_add_test (tc_chain, test_uri_clip_change_asset); tcase_add_test (tc_chain, test_proxy_asset); return s;