meson: Add feature options for optional deps
[platform/upstream/gstreamer.git] / gst / gstpreset.c
index 12f4cd4..7584c5b 100644 (file)
@@ -20,6 +20,7 @@
  */
 /**
  * SECTION:gstpreset
+ * @title: GstPreset
  * @short_description: helper interface for element presets
  *
  * This interface offers methods to query and manipulate parameter preset sets.
  * for gst_preset_save_preset() and gst_preset_delete_preset() to %NULL.
  * Applications can use gst_preset_is_editable() to check for that.
  *
- * The default implementation supports presets located in a system directory, 
+ * The default implementation supports presets located in a system directory,
  * application specific directory and in the users home directory. When getting
- * a list of presets individual presets are read and overlaid in 1) system, 
+ * a list of presets individual presets are read and overlaid in 1) system,
  * 2) application and 3) user order. Whenever an earlier entry is newer, the
  * later entries will be updated. Since 1.8 you can also provide extra paths
  * where to find presets through the GST_PRESET_PATH environment variable.
- * Presets found in those paths will be concidered as "app presets".
+ * Presets found in those paths will be considered as "app presets".
  */
 /* FIXME:
  * - non racyness
@@ -285,7 +286,7 @@ preset_open_and_parse_header (GstPreset * preset, const gchar * preset_path,
   /* ERRORS */
 load_error:
   {
-    GST_WARNING_OBJECT (preset, "Unable to read preset file %s: %s",
+    GST_INFO_OBJECT (preset, "Unable to read preset file %s: %s",
         preset_path, error->message);
     g_error_free (error);
     g_key_file_free (in);
@@ -349,6 +350,26 @@ preset_merge (GKeyFile * system, GKeyFile * user)
   g_strfreev (groups);
 }
 
+typedef struct
+{
+  GKeyFile *preset;
+  guint64 version;
+} PresetAndVersion;
+
+static gint
+compare_preset_and_version (gconstpointer a, gconstpointer b,
+    gpointer user_data)
+{
+  const PresetAndVersion *pa = a, *pb = b;
+
+  if (pa->version > pb->version)
+    return -1;
+  if (pa->version < pb->version)
+    return 1;
+  else
+    return 0;
+}
+
 /* reads the user and system presets files and merges them together. This
  * function caches the GKeyFile on the element type. If there is no existing
  * preset file, a new in-memory GKeyFile will be created. */
@@ -366,12 +387,23 @@ preset_get_keyfile (GstPreset * preset)
     guint64 version_user = G_GUINT64_CONSTANT (0);
     guint64 version = G_GUINT64_CONSTANT (0);
     gboolean merged = FALSE;
-    GKeyFile *in_user = NULL, *in_app = NULL, *in_system;
-
+    GKeyFile *in_user, *in_app = NULL, *in_system;
+    GQueue in_env = G_QUEUE_INIT;
+    gboolean have_env = FALSE;
     const gchar *envvar;
 
     /* try to load the user, app and system presets, we do this to get the
      * versions of all files. */
+    preset_get_paths (preset, &preset_user_path, &preset_app_path,
+        &preset_system_path);
+    in_user = preset_open_and_parse_header (preset, preset_user_path,
+        &version_user);
+
+    if (preset_app_path) {
+      in_app = preset_open_and_parse_header (preset, preset_app_path,
+          &version_app);
+    }
+
     envvar = g_getenv ("GST_PRESET_PATH");
     if (envvar) {
       gint i;
@@ -380,27 +412,23 @@ preset_get_keyfile (GstPreset * preset)
       for (i = 0; preset_dirs[i]; i++) {
         gchar *preset_path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s.prs",
             preset_dirs[i], G_OBJECT_TYPE_NAME (preset));
+        GKeyFile *env_file;
+        guint64 env_version;
 
-        in_user = preset_open_and_parse_header (preset, preset_path,
-            &version_user);
+        env_file = preset_open_and_parse_header (preset, preset_path,
+            &env_version);
         g_free (preset_path);
-        if (in_user)
-          break;
+        if (env_file) {
+          PresetAndVersion *pv = g_new (PresetAndVersion, 1);
+          pv->preset = env_file;
+          pv->version = env_version;
+          g_queue_push_tail (&in_env, pv);
+          have_env = TRUE;
+        }
       }
       g_strfreev (preset_dirs);
     }
 
-    preset_get_paths (preset, &preset_user_path, &preset_app_path,
-        &preset_system_path);
-    if (!in_user) {
-      in_user = preset_open_and_parse_header (preset, preset_user_path,
-          &version_user);
-    }
-
-    if (preset_app_path) {
-      in_app = preset_open_and_parse_header (preset, preset_app_path,
-          &version_app);
-    }
     in_system = preset_open_and_parse_header (preset, preset_system_path,
         &version_system);
 
@@ -409,8 +437,34 @@ preset_get_keyfile (GstPreset * preset)
       presets = in_system;
       version = version_system;
     }
+
+    if (have_env) {
+      GList *l;
+
+      /* merge the ones from the environment paths. If any of them has a
+       * higher version, take that as the "master" version. Lower versions are
+       * then just merged in. */
+      g_queue_sort (&in_env, compare_preset_and_version, NULL);
+      /* highest version to lowest */
+      for (l = in_env.head; l; l = l->next) {
+        PresetAndVersion *pv = l->data;
+
+        if (version > pv->version) {
+          preset_merge (presets, pv->preset);
+          g_key_file_free (pv->preset);
+        } else {
+          if (presets)
+            g_key_file_free (presets);
+          presets = pv->preset;
+          version = pv->version;
+        }
+        g_free (pv);
+      }
+      g_queue_clear (&in_env);
+    }
+
     if (in_app) {
-      /* if system version is higher, merge */
+      /* if system/env version is higher, merge */
       if (version > version_app) {
         preset_merge (presets, in_app);
         g_key_file_free (in_app);
@@ -422,7 +476,7 @@ preset_get_keyfile (GstPreset * preset)
       }
     }
     if (in_user) {
-      /* if system or app version is higher, merge */
+      /* if system/env or app version is higher, merge */
       if (version > version_user) {
         preset_merge (presets, in_user);
         g_key_file_free (in_user);
@@ -617,7 +671,7 @@ gst_preset_default_load_preset (GstPreset * preset, const gchar * name)
     /* check if we have a settings for this element property */
     if (!(str = g_key_file_get_value (presets, name, props[i], NULL))) {
       /* the element has a property but the parameter is not in the keyfile */
-      GST_WARNING_OBJECT (preset, "parameter '%s' not in preset", props[i]);
+      GST_INFO_OBJECT (preset, "parameter '%s' not in preset", props[i]);
       continue;
     }
 
@@ -802,6 +856,12 @@ gst_preset_default_save_preset (GstPreset * preset, const gchar * name)
       continue;
     }
 
+    if (property->flags & G_PARAM_DEPRECATED) {
+      GST_INFO_OBJECT (preset, "Not saving property %s as it is deprecated",
+          property->name);
+      continue;
+    }
+
     g_value_init (&gvalue, property->value_type);
     if (is_child_proxy) {
       gst_child_proxy_get_property ((GstChildProxy *) preset, props[i],
@@ -1151,10 +1211,10 @@ gst_preset_get_meta (GstPreset * preset, const gchar * name, const gchar * tag,
 
 /**
  * gst_preset_set_app_dir:
- * @app_dir: the application specific preset dir
+ * @app_dir: (type filename): the application specific preset dir
  *
  * Sets an extra directory as an absolute path that should be considered when
- * looking for presets. Any presets in the application dir will shadow the 
+ * looking for presets. Any presets in the application dir will shadow the
  * system presets.
  *
  * Returns: %TRUE for success, %FALSE if the dir already has been set
@@ -1177,7 +1237,7 @@ gst_preset_set_app_dir (const gchar * app_dir)
  * Gets the directory for application specific presets if set by the
  * application.
  *
- * Returns: (nullable): the directory or %NULL, don't free or modify
+ * Returns: (nullable) (type filename): the directory or %NULL, don't free or modify
  * the string
  */
 const gchar *