From d8f5b6322fc12d91a15eccfce28365cc7942e573 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 22 Dec 2010 18:16:33 +0100 Subject: [PATCH] encoding-target: Implement save/load feature Fixes #637735 --- configure.ac | 5 + gst-libs/gst/pbutils/encoding-target.c | 187 ++++++++++++++++++++++++++++----- gst-libs/gst/pbutils/encoding-target.h | 1 + tests/check/libs/profile.c | 27 ++--- 4 files changed, 182 insertions(+), 38 deletions(-) diff --git a/configure.ac b/configure.ac index e575024..287cc47 100644 --- a/configure.ac +++ b/configure.ac @@ -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], diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 601cdb2..6565bd9 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -20,6 +20,9 @@ #include #include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "encoding-target.h" /* @@ -49,6 +52,21 @@ * 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; +} diff --git a/gst-libs/gst/pbutils/encoding-target.h b/gst-libs/gst/pbutils/encoding-target.h index 0f9d340..fb73654 100644 --- a/gst-libs/gst/pbutils/encoding-target.h +++ b/gst-libs/gst/pbutils/encoding-target.h @@ -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); diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index c9df843..fef3406 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -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)) -- 2.7.4