encoding-target: Add API for list all categories and targets

API: gst_encoding_list_available_categories
API: gst_encoding_list_all_targets
This commit is contained in:
Edward Hervey 2011-01-03 13:20:19 +01:00 committed by Edward Hervey
parent deea1eb83f
commit a65faf2f3c
5 changed files with 235 additions and 0 deletions

View file

@ -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
<SUBSECTION Standard>
GST_ENCODING_PROFILE
GST_IS_ENCODING_PROFILE

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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);

View file

@ -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