371 GST_DEBUG_OBJECT (registry, "adding plugin %p for filename \"%s\"", |
371 GST_DEBUG_OBJECT (registry, "adding plugin %p for filename \"%s\"", |
372 plugin, GST_STR_NULL (plugin->filename)); |
372 plugin, GST_STR_NULL (plugin->filename)); |
373 |
373 |
374 registry->plugins = g_list_prepend (registry->plugins, plugin); |
374 registry->plugins = g_list_prepend (registry->plugins, plugin); |
375 |
375 |
376 gst_object_ref (plugin); |
376 gst_object_ref_sink (plugin); |
377 gst_object_sink (plugin); |
|
378 GST_OBJECT_UNLOCK (registry); |
377 GST_OBJECT_UNLOCK (registry); |
379 |
378 |
380 GST_LOG_OBJECT (registry, "emitting plugin-added for filename \"%s\"", |
379 GST_LOG_OBJECT (registry, "emitting plugin-added for filename \"%s\"", |
381 GST_STR_NULL (plugin->filename)); |
380 GST_STR_NULL (plugin->filename)); |
382 g_signal_emit (G_OBJECT (registry), gst_registry_signals[PLUGIN_ADDED], 0, |
381 g_signal_emit (registry, gst_registry_signals[PLUGIN_ADDED], 0, plugin); |
383 plugin); |
|
384 |
382 |
385 return TRUE; |
383 return TRUE; |
386 } |
384 } |
387 |
385 |
388 static void |
386 static void |
389 gst_registry_remove_features_for_plugin_unlocked (GstRegistry * registry, |
387 gst_registry_remove_features_for_plugin_unlocked (GstRegistry * registry, |
390 GstPlugin * plugin) |
388 GstPlugin * plugin) |
391 { |
389 { |
392 GList *f; |
390 GList *f; |
|
391 const gchar *name; |
393 |
392 |
394 g_return_if_fail (GST_IS_REGISTRY (registry)); |
393 g_return_if_fail (GST_IS_REGISTRY (registry)); |
395 g_return_if_fail (GST_IS_PLUGIN (plugin)); |
394 g_return_if_fail (GST_IS_PLUGIN (plugin)); |
|
395 |
|
396 name = gst_plugin_get_name (plugin); |
396 |
397 |
397 /* Remove all features for this plugin */ |
398 /* Remove all features for this plugin */ |
398 f = registry->features; |
399 f = registry->features; |
399 while (f != NULL) { |
400 while (f != NULL) { |
400 GList *next = g_list_next (f); |
401 GList *next = g_list_next (f); |
401 GstPluginFeature *feature = f->data; |
402 GstPluginFeature *feature = f->data; |
402 |
403 |
403 if (feature && !strcmp (feature->plugin_name, gst_plugin_get_name (plugin))) { |
404 if (G_UNLIKELY (feature && !strcmp (feature->plugin_name, name))) { |
404 GST_DEBUG_OBJECT (registry, "removing feature %p (%s) for plugin %s", |
405 GST_DEBUG_OBJECT (registry, "removing feature %p (%s) for plugin %s", |
405 feature, gst_plugin_feature_get_name (feature), |
406 feature, gst_plugin_feature_get_name (feature), name); |
406 gst_plugin_get_name (plugin)); |
|
407 |
407 |
408 registry->features = g_list_delete_link (registry->features, f); |
408 registry->features = g_list_delete_link (registry->features, f); |
409 g_hash_table_remove (registry->feature_hash, feature->name); |
409 g_hash_table_remove (registry->feature_hash, feature->name); |
410 gst_object_unref (feature); |
410 gst_object_unref (feature); |
411 } |
411 } |
473 feature->name); |
473 feature->name); |
474 if (G_UNLIKELY (existing_feature)) { |
474 if (G_UNLIKELY (existing_feature)) { |
475 GST_DEBUG_OBJECT (registry, "replacing existing feature %p (%s)", |
475 GST_DEBUG_OBJECT (registry, "replacing existing feature %p (%s)", |
476 existing_feature, feature->name); |
476 existing_feature, feature->name); |
477 /* Remove the existing feature from the list now, before we insert the new |
477 /* Remove the existing feature from the list now, before we insert the new |
478 * one, but don't unref yet because the hash is still storing a reference to * it. */ |
478 * one, but don't unref yet because the hash is still storing a reference to |
|
479 * it. */ |
479 registry->features = g_list_remove (registry->features, existing_feature); |
480 registry->features = g_list_remove (registry->features, existing_feature); |
480 } |
481 } |
481 |
482 |
482 GST_DEBUG_OBJECT (registry, "adding feature %p (%s)", feature, feature->name); |
483 GST_DEBUG_OBJECT (registry, "adding feature %p (%s)", feature, feature->name); |
483 |
484 |
484 registry->features = g_list_prepend (registry->features, feature); |
485 registry->features = g_list_prepend (registry->features, feature); |
485 g_hash_table_replace (registry->feature_hash, feature->name, feature); |
486 g_hash_table_replace (registry->feature_hash, feature->name, feature); |
486 |
487 |
487 if (G_UNLIKELY (existing_feature)) { |
488 if (G_UNLIKELY (existing_feature)) { |
488 /* We unref now. No need to remove the feature name from the hash table, it * got replaced by the new feature */ |
489 /* We unref now. No need to remove the feature name from the hash table, it |
|
490 * got replaced by the new feature */ |
489 gst_object_unref (existing_feature); |
491 gst_object_unref (existing_feature); |
490 } |
492 } |
491 |
493 |
492 gst_object_ref (feature); |
494 gst_object_ref_sink (feature); |
493 gst_object_sink (feature); |
|
494 GST_OBJECT_UNLOCK (registry); |
495 GST_OBJECT_UNLOCK (registry); |
495 |
496 |
496 GST_LOG_OBJECT (registry, "emitting feature-added for %s", feature->name); |
497 GST_LOG_OBJECT (registry, "emitting feature-added for %s", feature->name); |
497 g_signal_emit (G_OBJECT (registry), gst_registry_signals[FEATURE_ADDED], 0, |
498 g_signal_emit (registry, gst_registry_signals[FEATURE_ADDED], 0, feature); |
498 feature); |
|
499 |
499 |
500 return TRUE; |
500 return TRUE; |
501 } |
501 } |
502 |
502 |
503 /** |
503 /** |
859 |
861 |
860 static gboolean |
862 static gboolean |
861 gst_registry_scan_path_level (GstRegistry * registry, const gchar * path, |
863 gst_registry_scan_path_level (GstRegistry * registry, const gchar * path, |
862 int level) |
864 int level) |
863 { |
865 { |
864 GDir *directory[2]; |
|
865 GDir *dir; |
866 GDir *dir; |
866 const gchar *dirent; |
867 const gchar *dirent; |
867 gchar *filename; |
868 gchar *filename; |
868 GstPlugin *plugin; |
869 GstPlugin *plugin; |
869 GstPlugin *newplugin; |
870 GstPlugin *newplugin; |
870 gboolean changed = FALSE; |
871 gboolean changed = FALSE; |
871 |
872 |
872 #ifdef __SYMBIAN32__ |
873 #ifdef __SYMBIAN32__ |
873 GMappedFile *mapped = NULL; |
874 GMappedFile *mapped = NULL; |
874 gchar *contents = NULL; |
875 gchar *contents = NULL; |
875 gchar** arglist=NULL; |
876 gchar** arglist=NULL, **arglistbackup = NULL; |
876 GError *err = NULL; |
877 GError *err = NULL; |
877 char* file; |
878 char* file; |
878 gint i = 2; |
879 #endif |
879 #endif |
880 |
880 directory[0] = g_dir_open ( PLUGIN_LIST, 0, NULL ); |
881 dir = g_dir_open (path, 0, NULL); |
881 directory[1] = g_dir_open ( PLUGIN_LIST_IN_ROM, 0, NULL ); |
882 if (!dir) |
882 while( i ){ |
883 return FALSE; |
883 --i; |
884 |
884 dir = directory[i]; |
885 while ((dirent = g_dir_read_name (dir))) { |
885 if (!dir) |
886 struct stat file_status; |
886 continue; |
887 |
887 |
888 filename = g_build_filename (path, dirent, NULL); |
888 while ((dirent = g_dir_read_name (dir))) |
889 #ifdef __SYMBIAN32__ |
889 { |
890 /// check the extention.. |
890 #ifdef __SYMBIAN32__ |
891 if (!g_str_has_suffix (dirent, GSTREAMER_TXT_FILE_SUFFIX)){ |
|
892 continue; |
|
893 } |
|
894 //filename = g_strjoin ("\\", PLUGIN_LIST, dirent, NULL); |
|
895 mapped = g_mapped_file_new (filename, FALSE, &err); |
|
896 if( !mapped ) |
|
897 { |
|
898 return FALSE; |
|
899 } |
|
900 |
891 |
901 |
892 if( i == 1 ) |
|
893 filename = g_strjoin ("\\", PLUGIN_LIST_IN_ROM, dirent, NULL); |
|
894 else |
|
895 filename = g_strjoin ("\\", PLUGIN_LIST, dirent, NULL); |
|
896 mapped = g_mapped_file_new (filename, FALSE, &err); |
|
897 contents = g_mapped_file_get_contents (mapped); |
902 contents = g_mapped_file_get_contents (mapped); |
898 arglist = g_strsplit(contents, "\r\n", -1 ); |
903 arglist = g_strsplit(contents, "\r\n", -1 ); |
899 |
904 //g_free (contents); |
900 g_free (filename); |
905 g_free (filename); |
901 |
906 arglistbackup = arglist; |
902 while( *arglist ) |
907 while( *arglist ) |
903 { |
908 { |
904 filename = *arglist; |
909 dirent = *arglist; |
905 // trim white spaces from start |
910 filename = *arglist; |
906 while(*filename ==' ' ) |
911 // trim white spaces from start |
907 filename++; |
912 while(*filename ==' ' ) |
908 |
913 filename++; |
909 file = filename; |
914 |
910 |
915 file = filename; |
911 // trim white spaces from last |
916 |
912 while(*file != ' ' && *file != '\0') |
917 // trim white spaces from last |
913 file++; |
918 while(*file != ' ' && *file != '\0') |
914 *file = '\0'; |
919 file++; |
915 |
920 *file = '\0'; |
916 arglist++; |
921 |
917 /// get the full path of DLL |
922 arglist++; |
918 filename = libgstreamer_get_dll_path( filename ); |
923 /// get the full path of DLL |
919 |
924 filename = libgstreamer_get_dll_path( filename ); |
920 #else |
925 #endif |
921 |
926 if (g_stat (filename, &file_status) < 0) { |
922 filename = g_strjoin ("\\", path, dirent, NULL); |
927 /* Plugin will be removed from cache after the scan completes if it |
923 #endif |
928 * is still marked 'cached' */ |
924 GST_LOG_OBJECT (registry, "examining file: %s", filename); |
929 g_free (filename); |
925 |
930 continue; |
926 if (g_file_test (filename, G_FILE_TEST_IS_DIR)) { |
931 } |
|
932 |
|
933 if (file_status.st_mode & S_IFDIR) { |
|
934 /* skip the .debug directory, these contain elf files that are not |
|
935 * useful or worse, can crash dlopen () */ |
|
936 if (g_str_equal (dirent, ".debug") || g_str_equal (dirent, ".git")) { |
|
937 GST_LOG_OBJECT (registry, "ignoring .debug or .git directory"); |
|
938 g_free (filename); |
|
939 continue; |
|
940 } |
|
941 /* FIXME 0.11: Don't recurse into directories, this behaviour |
|
942 * is inconsistent with other PATH environment variables |
|
943 */ |
927 if (level > 0) { |
944 if (level > 0) { |
928 GST_LOG_OBJECT (registry, "found directory, recursing"); |
945 GST_LOG_OBJECT (registry, "recursing into directory %s", filename); |
929 changed |= gst_registry_scan_path_level (registry, filename, level - 1); |
946 changed |= gst_registry_scan_path_level (registry, filename, level - 1); |
930 } else { |
947 } else { |
931 GST_LOG_OBJECT (registry, |
948 GST_LOG_OBJECT (registry, "not recursing into directory %s, " |
932 "found directory, but recursion level is too deep"); |
949 "recursion level too deep", filename); |
933 } |
950 } |
934 g_free (filename); |
951 g_free (filename); |
935 continue; |
952 continue; |
936 } |
953 } |
937 if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { |
954 if (!(file_status.st_mode & S_IFREG)) { |
938 GST_LOG_OBJECT (registry, "not a regular file, ignoring"); |
955 GST_LOG_OBJECT (registry, "%s is not a regular file, ignoring", filename); |
939 g_free (filename); |
|
940 continue; |
|
941 } |
|
942 if (!g_str_has_suffix (filename, ".so") && |
|
943 !g_str_has_suffix (filename, ".sl") && |
|
944 !g_str_has_suffix (filename, ".dll") && |
|
945 !g_str_has_suffix (filename, ".dynlib")) { |
|
946 GST_LOG_OBJECT (registry, |
|
947 "extension is not recognized as module file, ignoring"); |
|
948 g_free (filename); |
956 g_free (filename); |
949 continue; |
957 continue; |
950 } |
958 } |
|
959 if (!g_str_has_suffix (dirent, G_MODULE_SUFFIX) |
|
960 #ifdef GST_EXTRA_MODULE_SUFFIX |
|
961 && !g_str_has_suffix (dirent, GST_EXTRA_MODULE_SUFFIX) |
|
962 #endif |
|
963 ) { |
|
964 GST_LOG_OBJECT (registry, "extension is not recognized as module file, " |
|
965 "ignoring file %s", filename); |
|
966 g_free (filename); |
|
967 continue; |
|
968 } |
|
969 |
|
970 GST_LOG_OBJECT (registry, "file %s looks like a possible module", filename); |
951 |
971 |
952 /* plug-ins are considered unique by basename; if the given name |
972 /* plug-ins are considered unique by basename; if the given name |
953 * was already seen by the registry, we ignore it */ |
973 * was already seen by the registry, we ignore it */ |
954 plugin = gst_registry_lookup (registry, filename); |
974 plugin = gst_registry_lookup (registry, filename); |
955 if (plugin) { |
975 if (plugin) { |
956 struct stat file_status; |
976 gboolean env_vars_changed, deps_changed = FALSE; |
957 |
977 |
958 if (stat (filename, &file_status)) { |
|
959 /* Plugin will be removed from cache after the scan completes if it |
|
960 * is still marked 'cached' */ |
|
961 g_free (filename); |
|
962 gst_object_unref (plugin); |
|
963 continue; |
|
964 } |
|
965 if (plugin->registered) { |
978 if (plugin->registered) { |
966 GST_DEBUG_OBJECT (registry, |
979 GST_DEBUG_OBJECT (registry, |
967 "plugin already registered from path \"%s\"", |
980 "plugin already registered from path \"%s\"", |
968 GST_STR_NULL (plugin->filename)); |
981 GST_STR_NULL (plugin->filename)); |
969 g_free (filename); |
982 g_free (filename); |
970 gst_object_unref (plugin); |
983 gst_object_unref (plugin); |
971 continue; |
984 continue; |
972 } |
985 } |
|
986 |
|
987 env_vars_changed = _priv_plugin_deps_env_vars_changed (plugin); |
|
988 |
973 if (plugin->file_mtime == file_status.st_mtime && |
989 if (plugin->file_mtime == file_status.st_mtime && |
974 plugin->file_size == file_status.st_size) { |
990 plugin->file_size == file_status.st_size && !env_vars_changed && |
|
991 !(deps_changed = _priv_plugin_deps_files_changed (plugin))) { |
975 GST_LOG_OBJECT (registry, "file %s cached", filename); |
992 GST_LOG_OBJECT (registry, "file %s cached", filename); |
976 plugin->flags &= ~GST_PLUGIN_FLAG_CACHED; |
993 plugin->flags &= ~GST_PLUGIN_FLAG_CACHED; |
977 GST_LOG_OBJECT (registry, "marking plugin %p as registered as %s", |
994 GST_LOG_OBJECT (registry, "marking plugin %p as registered as %s", |
978 plugin, filename); |
995 plugin, filename); |
979 plugin->registered = TRUE; |
996 plugin->registered = TRUE; |
985 changed = TRUE; |
1002 changed = TRUE; |
986 } |
1003 } |
987 } else { |
1004 } else { |
988 GST_INFO_OBJECT (registry, "cached info for %s is stale", filename); |
1005 GST_INFO_OBJECT (registry, "cached info for %s is stale", filename); |
989 GST_DEBUG_OBJECT (registry, "mtime %ld != %ld or size %" |
1006 GST_DEBUG_OBJECT (registry, "mtime %ld != %ld or size %" |
990 G_GINT64_FORMAT " != %" |
1007 G_GINT64_FORMAT " != %" G_GINT64_FORMAT " or external dependency " |
991 G_GINT64_FORMAT, plugin->file_mtime, file_status.st_mtime, |
1008 "env_vars changed: %d or external dependencies changed: %d", |
992 (gint64) plugin->file_size, (gint64) file_status.st_size); |
1009 plugin->file_mtime, file_status.st_mtime, |
|
1010 (gint64) plugin->file_size, (gint64) file_status.st_size, |
|
1011 env_vars_changed, deps_changed); |
993 gst_registry_remove_plugin (gst_registry_get_default (), plugin); |
1012 gst_registry_remove_plugin (gst_registry_get_default (), plugin); |
994 /* We don't use a GError here because a failure to load some shared |
1013 /* We don't use a GError here because a failure to load some shared |
995 * objects as plugins is normal (particularly in the uninstalled case) |
1014 * objects as plugins is normal (particularly in the uninstalled case) |
996 */ |
1015 */ |
997 newplugin = gst_plugin_load_file (filename, NULL); |
1016 newplugin = gst_plugin_load_file (filename, NULL); |
998 if (newplugin) { |
1017 if (newplugin) { |
999 GST_DEBUG_OBJECT (registry, "marking new plugin %p as registered", |
1018 GST_DEBUG_OBJECT (registry, "marking new plugin %p as registered", |