From 855270566c52fdd0a9cbbeba13d6f12f6704564b Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Tue, 19 Mar 2013 19:49:09 -0300 Subject: [PATCH] uri-asset: Implement a ges_uri_clip_asset_request_sync method This way we let the possibility to the user to actually do it, but we avoid him to do it without knowing it is absolutely not recommanded to. API: + ges_uri_clip_asset_request_sync --- docs/libs/ges-sections.txt | 1 + ges/ges-asset.c | 7 +++--- ges/ges-uri-asset.c | 53 +++++++++++++++++++++++++++++++++++++++++++++- ges/ges-uri-asset.h | 2 ++ tests/check/ges/uriclip.c | 43 +++++++++++++++++++++++++------------ 5 files changed, 88 insertions(+), 18 deletions(-) diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index 6bb60d4..057ca35 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -1048,6 +1048,7 @@ ges_uri_clip_asset_get_duration ges_uri_clip_asset_is_image ges_uri_clip_asset_get_info ges_uri_clip_asset_new +ges_uri_clip_asset_request_sync ges_uri_clip_asset_set_timeout ges_uri_clip_asset_get_stream_assets diff --git a/ges/ges-asset.c b/ges/ges-asset.c index c66aec6..359661d 100644 --- a/ges/ges-asset.c +++ b/ges/ges-asset.c @@ -696,10 +696,9 @@ ges_asset_get_extractable_type (GESAsset * self) * Create a #GESAsset in the most simple cases, you should look at the @extractable_type * documentation to see if that constructor can be called for this particular type * - * Note that it won't be possible to instantiate the first %GESAsset with - * @id depending on the @extractable_type. For example instantiate a - * #GESAsset that extract #GESUriClip needs to be done async - * the first time for a specific ID. + * As it is recommanded not to instanciate assets for GESUriClip synchronously, + * it will not work with this method, but you can instead use the specific + * #ges_uri_clip_asset_request_sync method if you really want to. * * Returns: (transfer full) (allow-none): A reference to the wanted #GESAsset or %NULL */ diff --git a/ges/ges-uri-asset.c b/ges/ges-uri-asset.c index 45fe446..17db72d 100644 --- a/ges/ges-uri-asset.c +++ b/ges/ges-uri-asset.c @@ -198,12 +198,12 @@ ges_uri_clip_asset_class_init (GESUriClipAssetClass * klass) properties[PROP_DURATION]); klass->discoverer = gst_discoverer_new (GST_SECOND, NULL); + klass->sync_discoverer = gst_discoverer_new (GST_SECOND, NULL); g_signal_connect (klass->discoverer, "discovered", G_CALLBACK (discoverer_discovered_cb), NULL); /* We just start the discoverer and let it live */ gst_discoverer_start (klass->discoverer); - if (parent_newparent_table == NULL) { parent_newparent_table = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, gst_object_unref, gst_object_unref); @@ -426,6 +426,56 @@ ges_uri_clip_asset_new (const gchar * uri, GCancellable * cancellable, } /** + * ges_uri_clip_asset_new_sync: + * @uri: The URI of the file for which to create a #GESUriClipAsset + * @error: (allow-none): An error to be set in case something wrong happens or %NULL + * + * Creates a #GESUriClipAsset for @uri syncronously. You should avoid + * to use it in application, and rather create #GESUriClipAsset asynchronously + * + * Returns: A reference to the requested asset or %NULL if an error happend + */ +GESUriClipAsset * +ges_uri_clip_asset_request_sync (const gchar * uri, GError ** error) +{ + GError *lerror = NULL; + GstDiscovererInfo *info; + GstDiscoverer *discoverer; + GESUriClipAsset *asset; + + asset = GES_URI_CLIP_ASSET (ges_asset_request (GES_TYPE_URI_CLIP, uri, + &lerror)); + + if (asset) + return asset; + + if (lerror && lerror->domain == GES_ASSET_ERROR && + lerror->code == GES_ASSET_WRONG_ID) { + g_propagate_error (error, lerror); + + return NULL; + } + + asset = g_object_new (GES_TYPE_URI_CLIP_ASSET, "id", uri, + "extractable-type", GES_TYPE_URI_CLIP, NULL); + discoverer = GES_URI_CLIP_ASSET_GET_CLASS (asset)->sync_discoverer; + info = gst_discoverer_discover_uri (discoverer, uri, &lerror); + if (info == NULL || lerror != NULL) { + gst_object_unref (asset); + if (lerror) + g_propagate_error (error, lerror); + + return NULL; + } + + ges_asset_cache_put (gst_object_ref (asset), NULL); + ges_uri_clip_asset_set_info (asset, info); + ges_asset_cache_set_loaded (GES_TYPE_URI_CLIP, uri, lerror); + + return asset; +} + +/** * ges_uri_clip_asset_set_timeout: * @class: The #GESUriClipAssetClass on which to set the discoverer timeout * @timeout: The timeout to set @@ -439,6 +489,7 @@ ges_uri_clip_asset_set_timeout (GESUriClipAssetClass * class, g_return_if_fail (GES_IS_URI_CLIP_ASSET_CLASS (class)); g_object_set (class->discoverer, "timeout", timeout, NULL); + g_object_set (class->sync_discoverer, "timeout", timeout, NULL); } /** diff --git a/ges/ges-uri-asset.h b/ges/ges-uri-asset.h index 40a7f82..10da0b5 100644 --- a/ges/ges-uri-asset.h +++ b/ges/ges-uri-asset.h @@ -62,6 +62,7 @@ struct _GESUriClipAssetClass /* */ GstDiscoverer *discoverer; + GstDiscoverer *sync_discoverer; gpointer _ges_reserved[GES_PADDING]; }; @@ -73,6 +74,7 @@ void ges_uri_clip_asset_new (const gchar *uri, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); +GESUriClipAsset* ges_uri_clip_asset_request_sync (const gchar *uri, GError **error); void ges_uri_clip_asset_set_timeout (GESUriClipAssetClass *class, GstClockTime timeout); const GList * ges_uri_clip_asset_get_stream_assets (GESUriClipAsset *self); diff --git a/tests/check/ges/uriclip.c b/tests/check/ges/uriclip.c index 5164dd1..fa67a45 100644 --- a/tests/check/ges/uriclip.c +++ b/tests/check/ges/uriclip.c @@ -109,34 +109,51 @@ GST_END_TEST; assert_equals_int (pact, active); \ } +static void +create_asset (GESUriClipAsset ** asset) +{ + *asset = ges_uri_clip_asset_request_sync (av_uri, NULL); + g_main_loop_quit (mainloop); +} GST_START_TEST (test_filesource_properties) { + GESClip *clip; GESTrack *track; + GESTimeline *timeline; + GESUriClipAsset *asset; + GESTimelineLayer *layer; GESTrackElement *trackelement; - GESClip *clip; ges_init (); track = ges_track_new (GES_TRACK_TYPE_AUDIO, GST_CAPS_ANY); fail_unless (track != NULL); - clip = (GESClip *) ges_uri_clip_new ((gchar *) - "crack:///there/is/no/way/this/exists"); - assert_is_type (clip, GES_TYPE_URI_CLIP); + layer = ges_timeline_layer_new (); + fail_unless (layer != NULL); + timeline = ges_timeline_new (); + fail_unless (GES_IS_TIMELINE (timeline)); + fail_unless (ges_timeline_add_layer (timeline, layer)); + fail_unless (ges_timeline_add_track (timeline, track)); + ASSERT_OBJECT_REFCOUNT (timeline, "timeline", 1); - /* Set some properties */ - g_object_set (clip, "start", (guint64) 42, "duration", (guint64) 51, - "in-point", (guint64) 12, "supported-formats", GES_TRACK_TYPE_AUDIO, - NULL); + mainloop = g_main_loop_new (NULL, FALSE); + g_timeout_add (1, (GSourceFunc) create_asset, &asset); + g_main_loop_run (mainloop); + /* Right away request the asset synchronously */ + + fail_unless (GES_IS_ASSET (asset)); + clip = ges_timeline_layer_add_asset (layer, GES_ASSET (asset), + 42, 12, 51, 1, GES_TRACK_TYPE_AUDIO); + assert_is_type (clip, GES_TYPE_URI_CLIP); assert_equals_uint64 (_START (clip), 42); assert_equals_uint64 (_DURATION (clip), 51); assert_equals_uint64 (_INPOINT (clip), 12); - trackelement = ges_clip_create_track_element (clip, track->type); - ges_container_add (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (trackelement)); - assert_is_type (trackelement, GES_TYPE_TRACK_FILESOURCE); - fail_unless (ges_track_add_element (track, trackelement)); + assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1); + trackelement = GES_CONTAINER_CHILDREN (clip)->data; + fail_unless (trackelement != NULL); /* Check that trackelement has the same properties */ assert_equals_uint64 (_START (trackelement), 42); @@ -172,7 +189,7 @@ GST_START_TEST (test_filesource_properties) ges_container_remove (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (trackelement)); - g_object_unref (track); + g_object_unref (timeline); } GST_END_TEST; -- 2.7.4