encoding-target: Implement save/load feature
authorEdward Hervey <edward.hervey@collabora.co.uk>
Wed, 22 Dec 2010 17:16:33 +0000 (18:16 +0100)
committerEdward Hervey <bilboed@bilboed.com>
Wed, 5 Jan 2011 19:54:06 +0000 (20:54 +0100)
Fixes #637735

configure.ac
gst-libs/gst/pbutils/encoding-target.c
gst-libs/gst/pbutils/encoding-target.h
tests/check/libs/profile.c

index e575024..287cc47 100644 (file)
@@ -389,6 +389,11 @@ AG_GST_SET_LEVEL_DEFAULT($GST_GIT)
 dnl used in examples
 AG_GST_DEFAULT_ELEMENTS
 
+dnl needed for encoding-target
+GST_DATADIR="$GST_PREFIX/share"
+AC_DEFINE_UNQUOTED(GST_DATADIR, "$GST_DATADIR", [system wide data directory])
+AC_DEFINE_UNQUOTED(GST_MAJORMINOR, "$GST_MAJORMINOR", [major/minor version])
+
 dnl behaviour of speex based audio resampler
 AC_MSG_CHECKING(which audio resample format to use for integer)
 AC_ARG_WITH([audioresample_format],
index 601cdb2..6565bd9 100644 (file)
@@ -20,6 +20,9 @@
 
 #include <locale.h>
 #include <string.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 #include "encoding-target.h"
 
 /*
  * variableframerate : <variableframerate>
  *  */
 
+/*
+ * Location of profile files
+ *
+ * $GST_DATADIR/gstreamer-GST_MAJORMINOR/encoding-profile
+ * $HOME/gstreamer-GST_MAJORMINOR/encoding-profile
+ *
+ * Naming convention
+ *   $(target.category)/$(target.name).gstprof
+ *
+ * Naming restrictions:
+ *  lowercase ASCII letter for the first character
+ *  Same for all other characters + numerics + hyphens
+ */
+
+
 #define GST_ENCODING_TARGET_HEADER "_gstencodingtarget_"
 
 struct _GstEncodingTarget
@@ -700,48 +718,131 @@ beach:
 }
 
 /**
+ *
+ * returned list contents must be freed
+ */
+static GList *
+get_matching_filenames (gchar * path, gchar * filename)
+{
+  GList *res = NULL;
+  GDir *topdir;
+  const gchar *subdirname;
+
+  topdir = g_dir_open (path, 0, NULL);
+  if (G_UNLIKELY (topdir == NULL))
+    return NULL;
+
+  while ((subdirname = g_dir_read_name (topdir))) {
+    gchar *ltmp = g_build_filename (path, subdirname, NULL);
+
+    if (g_file_test (ltmp, G_FILE_TEST_IS_DIR)) {
+      gchar *tmp = g_build_filename (path, subdirname, filename, NULL);
+      /* Test to see if we have a file named like that in that directory */
+      if (g_file_test (tmp, G_FILE_TEST_EXISTS))
+        res = g_list_append (res, tmp);
+      else
+        g_free (tmp);
+    }
+    g_free (ltmp);
+  }
+
+  g_dir_close (topdir);
+
+  return res;
+}
+
+static GstEncodingTarget *
+gst_encoding_target_subload (gchar * path, const gchar * category,
+    gchar * lfilename, GError ** error)
+{
+  GstEncodingTarget *target = NULL;
+
+  if (category) {
+    gchar *filename;
+
+    filename = g_build_filename (path, category, lfilename, NULL);
+    target = gst_encoding_target_load_from (filename, error);
+    g_free (filename);
+  } else {
+    GList *tmp, *tries = get_matching_filenames (path, lfilename);
+
+    /* Try to find a file named %s.gstprofile in any subdirectories */
+    for (tmp = tries; tmp; tmp = tmp->next) {
+      target = gst_encoding_target_load_from ((gchar *) tmp->data, NULL);
+      if (target)
+        break;
+    }
+    g_list_foreach (tries, (GFunc) g_free, NULL);
+    if (tries)
+      g_list_free (tries);
+  }
+
+  return target;
+}
+
+/**
  * gst_encoding_target_load:
  * @name: the name of the #GstEncodingTarget to load.
+ * @category: (allow-none): the name of the target category. Can be %NULL
  * @error: If an error occured, this field will be filled in.
  *
  * Searches for the #GstEncodingTarget with the given name, loads it
  * and returns it.
  *
- * Warning: NOT IMPLEMENTED.
+ * If the category name is specified only targets from that category will be
+ * searched for.
  *
  * Since: 0.10.32
  *
  * Returns: (transfer full): The #GstEncodingTarget if available, else %NULL.
  */
-
 GstEncodingTarget *
-gst_encoding_target_load (const gchar * name, GError ** error)
+gst_encoding_target_load (const gchar * name, const gchar * category,
+    GError ** error)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
-}
+  gchar *lfilename, *tldir;
+  GstEncodingTarget *target = NULL;
 
-/**
- * gst_encoding_target_save:
- * @target: a #GstEncodingTarget
- * @error: If an error occured, this field will be filled in.
- *
- * Saves the @target to the default location.
- *
- * Warning: NOT IMPLEMENTED.
- *
- * Since: 0.10.32
- *
- * Returns: %TRUE if the target was correctly saved, else %FALSE.
- **/
+  g_return_val_if_fail (name != NULL, NULL);
 
-gboolean
-gst_encoding_target_save (GstEncodingTarget * target, GError ** error)
-{
-  g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE);
+  if (!validate_name (name))
+    goto invalid_name;
+
+  if (category && !validate_name (category))
+    goto invalid_category;
+
+  lfilename = g_strdup_printf ("%s.gstprofile", name);
+
+  /* Try from local profiles */
+  tldir =
+      g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+      "encoding-profile", NULL);
+  target = gst_encoding_target_subload (tldir, category, lfilename, error);
+  g_free (tldir);
+
+  if (target == NULL) {
+    /* Try from system-wide profiles */
+    tldir =
+        g_build_filename (GST_DATADIR, "gstreamer-" GST_MAJORMINOR,
+        "encoding-profile", NULL);
+    target = gst_encoding_target_subload (tldir, category, lfilename, error);
+    g_free (tldir);
+  }
 
-  /* FIXME : IMPLEMENT */
-  return FALSE;
+  g_free (lfilename);
+
+  return target;
+
+invalid_name:
+  {
+    GST_ERROR ("Invalid name for encoding target : '%s'", name);
+    return NULL;
+  }
+invalid_category:
+  {
+    GST_ERROR ("Invalid name for encoding category : '%s'", category);
+    return NULL;
+  }
 }
 
 /**
@@ -813,3 +914,39 @@ write_failed:
     return FALSE;
   }
 }
+
+/**
+ * gst_encoding_target_save:
+ * @target: a #GstEncodingTarget
+ * @error: If an error occured, this field will be filled in.
+ *
+ * Saves the @target to the default location. Unless the user has write access
+ * to the system-wide encoding target directory, it will be saved in a
+ * user-local directory.
+ *
+ * Since: 0.10.32
+ *
+ * Returns: %TRUE if the target was correctly saved, else %FALSE.
+ **/
+
+gboolean
+gst_encoding_target_save (GstEncodingTarget * target, GError ** error)
+{
+  gchar *filename;
+  gchar *lfilename;
+  gboolean res;
+
+  g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE);
+  g_return_val_if_fail (target->category != NULL, FALSE);
+
+  lfilename = g_strdup_printf ("%s.gstprofile", target->name);
+  filename =
+      g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+      "encoding-profile", target->category, lfilename, NULL);
+  g_free (lfilename);
+
+  res = gst_encoding_target_save_to (target, filename, error);
+  g_free (filename);
+
+  return TRUE;
+}
index 0f9d340..fb73654 100644 (file)
@@ -97,6 +97,7 @@ gboolean gst_encoding_target_save_to (GstEncodingTarget *target,
                                      const gchar *path,
                                      GError **error);
 GstEncodingTarget *gst_encoding_target_load (const gchar *name,
+                                            const gchar *category,
                                             GError **error);
 GstEncodingTarget *gst_encoding_target_load_from (const gchar *path,
                                                  GError **error);
index c9df843..fef3406 100644 (file)
@@ -210,7 +210,7 @@ GST_START_TEST (test_target_naming)
 GST_END_TEST;
 
 static GstEncodingTarget *
-create_saveload_target (void)
+create_saveload_target (const gchar * targetname)
 {
   GstEncodingTarget *target;
   GstEncodingProfile *profile, *sprof;
@@ -218,7 +218,7 @@ create_saveload_target (void)
 
   GST_DEBUG ("Creating target");
 
-  target = gst_encoding_target_new ("myponytarget", "herding",
+  target = gst_encoding_target_new (targetname, "herding",
       "Plenty of pony glitter profiles", NULL);
   caps = gst_caps_from_string ("animal/x-pony");
   profile =
@@ -258,7 +258,7 @@ GST_START_TEST (test_target_profile)
   GstEncodingTarget *target;
   GstEncodingProfile *prof;
 
-  target = create_saveload_target ();
+  target = create_saveload_target ("myponytarget");
 
   /* NULL isn't a valid profile name */
   ASSERT_CRITICAL (gst_encoding_target_get_profile (target, NULL));
@@ -284,13 +284,13 @@ GST_START_TEST (test_saving_profile)
   gchar *profile_file_name;
 
   /* Create and store a target */
-  profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
-      "profile", "TestProfile2.profile", NULL);
-  orig = create_saveload_target ();
-  GST_DEBUG ("Saving target to '%s'", profile_file_name);
-  fail_unless (gst_encoding_target_save_to (orig, profile_file_name, NULL));
+  orig = create_saveload_target ("myponytarget2");
+  GST_DEBUG ("Saving target 'myponytarget2'");
+  fail_unless (gst_encoding_target_save (orig, NULL));
 
   /* Check we can load it */
+  profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+      "encoding-profile", "herding", "myponytarget2.gstprofile", NULL);
   GST_DEBUG ("Loading target from '%s'", profile_file_name);
   loaded = gst_encoding_target_load_from (profile_file_name, NULL);
   fail_unless (loaded != NULL);
@@ -437,11 +437,11 @@ remove_profile_file (void)
   gchar *profile_file_name;
 
   profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
-      "profile", "TestProfile.profile", NULL);
+      "encoding-profile", "herding", "myponytarget.gstprofile", NULL);
   g_unlink (profile_file_name);
   g_free (profile_file_name);
   profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
-      "profile", "TestProfile2.profile", NULL);
+      "encoding-profile", "herding", "myponytarget2.gstprofile", NULL);
   g_unlink (profile_file_name);
   g_free (profile_file_name);
 }
@@ -454,10 +454,11 @@ create_profile_file (void)
   GError *error = NULL;
 
   profile_dir =
-      g_build_filename (g_get_home_dir (), ".gstreamer-0.10", "profile", NULL);
+      g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+      "encoding-profile", "herding", NULL);
   profile_file_name =
-      g_build_filename (g_get_home_dir (), ".gstreamer-0.10", "profile",
-      "TestProfile.profile", NULL);
+      g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+      "encoding-profile", "herding", "myponytarget.gstprofile", NULL);
   g_mkdir_with_parents (profile_dir, S_IRUSR | S_IWUSR | S_IXUSR);
   if (!g_file_set_contents (profile_file_name, profile_string,
           strlen (profile_string), &error))