From: Edward Hervey Date: Mon, 3 Jan 2011 12:20:19 +0000 (+0100) Subject: encoding-target: Add API for list all categories and targets X-Git-Tag: 1.19.3~511^2~6555^2~1254 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a65faf2f3c687a66f72213d965555c8a4631e2e2;p=platform%2Fupstream%2Fgstreamer.git encoding-target: Add API for list all categories and targets API: gst_encoding_list_available_categories API: gst_encoding_list_all_targets --- diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index e42c956..29969fe 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -1964,6 +1964,8 @@ gst_encoding_target_save gst_encoding_target_save_to gst_encoding_target_load gst_encoding_target_load_from +gst_encoding_list_all_targets +gst_encoding_list_available_categories GST_ENCODING_PROFILE GST_IS_ENCODING_PROFILE diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 6565bd9..faee8c3 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -950,3 +950,184 @@ gst_encoding_target_save (GstEncodingTarget * target, GError ** error) return TRUE; } + +static GList * +get_categories (gchar * path) +{ + 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)) { + res = g_list_append (res, (gpointer) g_strdup (subdirname)); + } + g_free (ltmp); + } + + g_dir_close (topdir); + + return res; +} + +/** + * gst_encoding_list_available_categories: + * + * Lists all #GstEncodingTarget categories present on disk. + * + * Returns: (transfer full) (element-type gchar*): A list + * of #GstEncodingTarget categories. +*/ +GList * +gst_encoding_list_available_categories (void) +{ + GList *res = NULL; + GList *tmp1, *tmp2; + gchar *topdir; + + /* First try user-local categories */ + topdir = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "encoding-profile", NULL); + res = get_categories (topdir); + g_free (topdir); + + /* Extend with system-wide categories */ + topdir = g_build_filename (GST_DATADIR, "gstreamer-" GST_MAJORMINOR, + "encoding-profile", NULL); + tmp1 = get_categories (topdir); + g_free (topdir); + + for (tmp2 = tmp1; tmp2; tmp2 = tmp2->next) { + gchar *name = (gchar *) tmp2->data; + if (!g_list_find_custom (res, name, (GCompareFunc) g_strcmp0)) + res = g_list_append (res, (gpointer) name); + else + g_free (name); + } + g_free (tmp1); + + return res; +} + +static inline GList * +sub_get_all_targets (gchar * subdir) +{ + GList *res = NULL; + const gchar *filename; + GDir *dir; + GstEncodingTarget *target; + + dir = g_dir_open (subdir, 0, NULL); + if (G_UNLIKELY (dir == NULL)) + return NULL; + + while ((filename = g_dir_read_name (dir))) { + gchar *fullname; + + /* Only try files ending with .gstprofile */ + if (!g_str_has_suffix (filename, ".gstprofile")) + continue; + + fullname = g_build_filename (subdir, filename, NULL); + target = gst_encoding_target_load_from (fullname, NULL); + if (target) { + res = g_list_append (res, target); + } else + GST_WARNING ("Failed to get a target from %s", fullname); + g_free (fullname); + } + g_dir_close (dir); + + return res; +} + +static inline GList * +get_all_targets (gchar * topdir, const gchar * categoryname) +{ + GList *res = NULL; + + if (categoryname) { + gchar *subdir = g_build_filename (topdir, categoryname, NULL); + /* Try to open the directory */ + res = sub_get_all_targets (subdir); + g_free (subdir); + } else { + const gchar *subdirname; + GDir *dir = g_dir_open (topdir, 0, NULL); + + if (G_UNLIKELY (dir == NULL)) + return NULL; + + while ((subdirname = g_dir_read_name (dir))) { + gchar *ltmp = g_build_filename (topdir, subdirname, NULL); + + if (g_file_test (ltmp, G_FILE_TEST_IS_DIR)) { + res = g_list_concat (res, sub_get_all_targets (ltmp)); + } + g_free (ltmp); + } + g_dir_close (dir); + } + + return res; +} + +static guint +compare_targets (const GstEncodingTarget * ta, const GstEncodingTarget * tb) +{ + if (!g_strcmp0 (ta->name, tb->name) + && !g_strcmp0 (ta->category, tb->category)) + return -1; + + return 0; +} + +/** + * gst_encoding_list_all_targets: + * @categoryname: (allow-none): The category, for ex: #GST_ENCODING_CATEGORY_DEVICE. + * Can be NULL. + * + * List all available #GstEncodingTarget for the specified category, or all categories + * if @categoryname is NULL. + * + * Returns: (transfer full) (element-type GstEncodingTarget): The list of #GstEncodingTarget + */ +GList * +gst_encoding_list_all_targets (const gchar * categoryname) +{ + GList *res; + GList *tmp1, *tmp2; + gchar *topdir; + + /* Get user-locals */ + topdir = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "encoding-profile", NULL); + res = get_all_targets (topdir, categoryname); + g_free (topdir); + + /* Get system-wide */ + topdir = g_build_filename (GST_DATADIR, "gstreamer-" GST_MAJORMINOR, + "encoding-profile", NULL); + tmp1 = get_all_targets (topdir, categoryname); + g_free (topdir); + + /* Merge system-wide targets */ + /* FIXME : We should merge the system-wide profiles into the user-locals + * instead of stopping at identical target names */ + for (tmp2 = tmp1; tmp2; tmp2 = tmp2->next) { + GstEncodingTarget *target = (GstEncodingTarget *) tmp2->data; + if (g_list_find_custom (res, target, (GCompareFunc) compare_targets)) + gst_encoding_target_unref (target); + else + res = g_list_append (res, target); + } + g_list_free (tmp1); + + return res; +} diff --git a/gst-libs/gst/pbutils/encoding-target.h b/gst-libs/gst/pbutils/encoding-target.h index fb73654..bb5b409 100644 --- a/gst-libs/gst/pbutils/encoding-target.h +++ b/gst-libs/gst/pbutils/encoding-target.h @@ -102,6 +102,9 @@ GstEncodingTarget *gst_encoding_target_load (const gchar *name, GstEncodingTarget *gst_encoding_target_load_from (const gchar *path, GError **error); +GList *gst_encoding_list_available_categories (void); +GList *gst_encoding_list_all_targets (const gchar * categoryname); + G_END_DECLS #endif /* __GST_PROFILE_REGISTRY_H__ */ diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index adedbba..deed294 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -464,6 +464,52 @@ GST_START_TEST (test_loading_profile) GST_END_TEST; +GST_START_TEST (test_target_list) +{ + GList *categories; + GList *targets; + GList *tmp; + + /* Make sure we get our test category in the available categories */ + categories = gst_encoding_list_available_categories (); + fail_if (categories == NULL); + fail_if (g_list_find_custom (categories, "herding", + (GCompareFunc) g_strcmp0) == NULL); + g_list_foreach (categories, (GFunc) g_free, NULL); + g_list_free (categories); + + /* Try getting all available targets with a specified category */ + targets = gst_encoding_list_all_targets ("herding"); + fail_if (targets == NULL); + for (tmp = targets; tmp; tmp = tmp->next) { + GstEncodingTarget *target = (GstEncodingTarget *) tmp->data; + if (!g_strcmp0 (gst_encoding_target_get_name (target), "myponytarget")) + break; + } + /* If tmp is NULL, it means we iterated the whole list without finding + * our target */ + fail_if (tmp == NULL); + g_list_foreach (targets, (GFunc) gst_mini_object_unref, NULL); + g_list_free (targets); + + /* Try getting all available targets without a specified category */ + targets = gst_encoding_list_all_targets (NULL); + fail_if (targets == NULL); + for (tmp = targets; tmp; tmp = tmp->next) { + GstEncodingTarget *target = (GstEncodingTarget *) tmp->data; + if (!g_strcmp0 (gst_encoding_target_get_name (target), "myponytarget")) + break; + } + /* If tmp is NULL, it means we iterated the whole list without finding + * our target */ + fail_if (tmp == NULL); + g_list_foreach (targets, (GFunc) gst_mini_object_unref, NULL); + g_list_free (targets); +} + +GST_END_TEST; + + static const gchar *profile_string = "\ [_gstencodingtarget_]\n\ name=myponytarget\n\ @@ -564,6 +610,7 @@ profile_suite (void) if (can_write) { tcase_add_test (tc_chain, test_loading_profile); tcase_add_test (tc_chain, test_saving_profile); + tcase_add_test (tc_chain, test_target_list); } tcase_add_unchecked_fixture (tc_chain, test_setup, test_teardown); diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index 333bc68..63c125d 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -65,6 +65,8 @@ EXPORTS gst_encoding_container_profile_get_profiles gst_encoding_container_profile_get_type gst_encoding_container_profile_new + gst_encoding_list_all_targets + gst_encoding_list_available_categories gst_encoding_profile_find gst_encoding_profile_get_description gst_encoding_profile_get_format