static GHashTable *parent_newparent_table = NULL;
-static GstDiscoverer *discoverer = NULL;
+G_LOCK_DEFINE_STATIC (discoverers_lock);
+static GstClockTime discovering_timeout = DEFAULT_DISCOVERY_TIMEOUT;
+static GHashTable *discoverers = NULL; /* Thread ID -> GstDiscoverer */
+static void discoverer_discovered_cb (GstDiscoverer * discoverer,
+ GstDiscovererInfo * info, GError * err, gpointer user_data);
+
+/* WITH discoverers_lock */
+static GstDiscoverer *
+create_discoverer ()
+{
+ GstDiscoverer *disco = gst_discoverer_new (discovering_timeout, NULL);
+
+ g_signal_connect (disco, "discovered", G_CALLBACK (discoverer_discovered_cb),
+ NULL);
+ GST_INFO_OBJECT (disco, "Creating new discoverer");
+ g_hash_table_insert (discoverers, g_thread_self (), disco);
+ gst_discoverer_start (disco);
+
+ return disco;
+}
+
+static GstDiscoverer *
+get_discoverer ()
+{
+ GstDiscoverer *disco;
+
+ G_LOCK (discoverers_lock);
+ g_assert (discoverers);
+ disco = g_hash_table_lookup (discoverers, g_thread_self ());
+ if (!disco) {
+ disco = create_discoverer ();
+ }
+ disco = gst_object_ref (disco);
+ G_UNLOCK (discoverers_lock);
+
+ return disco;
+}
static void
initable_iface_init (GInitableIface * initable_iface)
};
static GParamSpec *properties[PROP_LAST];
-static void discoverer_discovered_cb (GstDiscoverer * discoverer,
- GstDiscovererInfo * info, GError * err, gpointer user_data);
-
struct _GESUriClipAssetPrivate
{
GstDiscovererInfo *info;
{
gboolean ret;
const gchar *uri;
- GESUriClipAssetClass *class = GES_URI_CLIP_ASSET_GET_CLASS (asset);
+ GstDiscoverer *discoverer = get_discoverer ();
uri = ges_asset_get_id (asset);
+ GST_DEBUG_OBJECT (discoverer, "Started loading %s", uri);
+
+ ret = gst_discoverer_discover_uri_async (discoverer, uri);
+ gst_object_unref (discoverer);
- GST_DEBUG_OBJECT (asset, "Started loading %s", uri);
- ret = gst_discoverer_discover_uri_async (class->discoverer, uri);
if (ret)
return GES_ASSET_LOADING_ASYNC;
GError *lerror = NULL;
GESUriClipAsset *asset;
RequestSyncData data = { 0, };
- GESUriClipAssetClass *klass = g_type_class_peek (GES_TYPE_URI_CLIP_ASSET);
- GstClockTime timeout;
- GstDiscoverer *previous_discoverer = klass->discoverer;
+ GstDiscoverer *previous_discoverer;
asset = GES_URI_CLIP_ASSET (ges_asset_request (GES_TYPE_URI_CLIP, uri,
&lerror));
return asset;
data.ml = g_main_loop_new (NULL, TRUE);
- g_object_get (previous_discoverer, "timeout", &timeout, NULL);
- klass->discoverer = gst_discoverer_new (timeout, error);
- g_object_set (klass->discoverer, "use-cache", TRUE, NULL);
- if (!klass->discoverer) {
- klass->discoverer = previous_discoverer;
-
- return NULL;
- }
+ previous_discoverer = get_discoverer ();
+ create_discoverer ();
- g_signal_connect (klass->discoverer, "discovered",
- G_CALLBACK (klass->discovered), NULL);
- gst_discoverer_start (klass->discoverer);
ges_asset_request_async (GES_TYPE_URI_CLIP, uri, NULL,
(GAsyncReadyCallback) asset_ready_cb, &data);
g_main_loop_run (data.ml);
g_main_loop_unref (data.ml);
- gst_object_unref (klass->discoverer);
- klass->discoverer = previous_discoverer;
+ G_LOCK (discoverers_lock);
+ g_hash_table_insert (discoverers, g_thread_self (), previous_discoverer);
+ G_UNLOCK (discoverers_lock);
if (data.error) {
GST_ERROR ("Got an error requesting asset: %s", data.error->message);
ges_uri_clip_asset_class_set_timeout (GESUriClipAssetClass * klass,
GstClockTime timeout)
{
+ GHashTableIter iter;
+ gpointer value;
+
g_return_if_fail (GES_IS_URI_CLIP_ASSET_CLASS (klass));
- g_object_set (klass->discoverer, "timeout", timeout, NULL);
+ discovering_timeout = timeout;
+
+ G_LOCK (discoverers_lock);
+ g_hash_table_iter_init (&iter, discoverers);
+ while (g_hash_table_iter_next (&iter, NULL, &value))
+ g_object_set (value, "timeout", timeout, NULL);
+ G_UNLOCK (discoverers_lock);
}
/**
void
_ges_uri_asset_cleanup (void)
{
- if (discoverer)
- gst_discoverer_stop (discoverer);
- g_clear_object (&discoverer);
if (parent_newparent_table) {
g_hash_table_destroy (parent_newparent_table);
parent_newparent_table = NULL;
}
+
+ G_LOCK (discoverers_lock);
+ if (discoverers) {
+ g_hash_table_destroy (discoverers);
+ discoverers = NULL;
+ }
+ G_UNLOCK (discoverers_lock);
}
gboolean
GError *err;
GstClockTime timeout;
const gchar *timeout_str;
+ GstDiscoverer *discoverer = NULL;
g_return_val_if_fail (GES_IS_URI_CLIP_ASSET_CLASS (uriasset_class), FALSE);
g_signal_connect (klass->discoverer, "discovered",
G_CALLBACK (klass->discovered), NULL);
+ gst_discoverer_start (klass->discoverer);
+ }
+
+ G_LOCK (discoverers_lock);
+ if (discoverers == NULL) {
+ discoverers = g_hash_table_new_full (g_direct_hash,
+ (GEqualFunc) g_direct_equal, NULL, g_object_unref);
}
+ G_UNLOCK (discoverers_lock);
/* 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, g_object_unref, g_object_unref);
g_main_loop_quit (data->ml);
}
-/* TODO: Add a way to run a function in the right GES thread */
static gboolean
ges_timeline_new_from_uri_from_main_thread (TimelineConstructionData * data)
{
GESProject *project = ges_project_new (data->uri);
- GESUriClipAssetClass *klass = g_type_class_peek (GES_TYPE_URI_CLIP_ASSET);
- GstDiscoverer *previous_discoverer = klass->discoverer;
- GstClockTime timeout;
G_GNUC_UNUSED void *unused;
- g_object_get (previous_discoverer, "timeout", &timeout, NULL);
-
- /* Make sure to use a new discoverer in case we are being discovered,
- * as discovering is done one by one, and the global discoverer won't
- * have the chance to discover the project assets */
g_mutex_lock (&data->lock);
klass->discoverer = gst_discoverer_new (timeout, &data->error);
g_object_set (klass->discoverer, "use-cache", TRUE, NULL);
if (data->error) {
- klass->discoverer = previous_discoverer;
g_mutex_unlock (&data->lock);
goto done;
g_mutex_lock (&data->lock);
- /* Set previous discoverer back! */
-
- if (klass->discoverer)
- gst_object_unref (klass->discoverer);
- klass->discoverer = previous_discoverer;
-
- if (data->timeline)
- ges_timeline_commit (data->timeline);
-
if (data->loaded_sigid)
g_signal_handler_disconnect (project, data->loaded_sigid);