media source: add API to get available sources
authorRomain Vimont <rom1v@videolabs.io>
Thu, 22 Nov 2018 11:14:09 +0000 (12:14 +0100)
committerThomas Guillem <thomas@gllm.fr>
Mon, 26 Nov 2018 10:56:19 +0000 (11:56 +0100)
Add functions to get the list of media source metadata, optionally
only for a given category.

Signed-off-by: Thomas Guillem <thomas@gllm.fr>
include/vlc_media_source.h
src/libvlccore.sym
src/media_source/media_source.c
test/Makefile.am
test/src/media_source/media_source.c [new file with mode: 0644]

index ac56124..02c94eb 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <vlc_common.h>
 #include <vlc_input_item.h>
+#include <vlc_services_discovery.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -229,6 +230,59 @@ VLC_API vlc_media_source_t *
 vlc_media_source_provider_GetMediaSource(vlc_media_source_provider_t *,
                                          const char *name);
 
+/**
+ * Structure containing the description of a media source.
+ */
+struct vlc_media_source_meta
+{
+    char *name;
+    char *longname;
+    enum services_discovery_category_e category;
+};
+
+/** List of media source metadata (opaque). */
+typedef struct vlc_media_source_meta_list vlc_media_source_meta_list_t;
+
+/**
+ * Return the list of metadata of available media sources.
+ *
+ * If category is not 0, then only media sources for the requested category are
+ * listed.
+ *
+ * The result must be deleted by vlc_media_source_meta_list_Delete() (if not
+ * null).
+ *
+ * Return NULL either on error or on empty list (this is due to the behavior
+ * of the underlying vlc_sd_GetNames()).
+ *
+ * \param provider the media source provider
+ * \param category the category to list (0 for all)
+ */
+VLC_API vlc_media_source_meta_list_t *
+vlc_media_source_provider_List(vlc_media_source_provider_t *,
+                               enum services_discovery_category_e category);
+
+/**
+ * Return the number of items in the list.
+ */
+VLC_API size_t
+vlc_media_source_meta_list_Count(vlc_media_source_meta_list_t *);
+
+/**
+ * Return the item at index.
+ */
+VLC_API struct vlc_media_source_meta *
+vlc_media_source_meta_list_Get(vlc_media_source_meta_list_t *, size_t index);
+
+/**
+ * Delete the list.
+ *
+ * Any struct vlc_media_source_meta retrieved from this list become invalid
+ * after this call.
+ */
+VLC_API void
+vlc_media_source_meta_list_Delete(vlc_media_source_meta_list_t *);
+
 /** @} */
 
 #ifdef __cplusplus
index 9c4a7ea..9423e2f 100644 (file)
@@ -950,6 +950,10 @@ vlc_media_source_Hold
 vlc_media_source_Release
 vlc_media_source_provider_Get
 vlc_media_source_provider_GetMediaSource
+vlc_media_source_provider_List
+vlc_media_source_meta_list_Count
+vlc_media_source_meta_list_Get
+vlc_media_source_meta_list_Delete
 vlc_media_tree_AddListener
 vlc_media_tree_RemoveListener
 vlc_media_tree_Lock
index 6f952cd..1bf7c4d 100644 (file)
@@ -28,6 +28,7 @@
 #include <vlc_atomic.h>
 #include <vlc_playlist.h>
 #include <vlc_services_discovery.h>
+#include <vlc_vector.h>
 #include "libvlc.h"
 #include "media_tree.h"
 
@@ -272,3 +273,83 @@ vlc_media_source_provider_GetMediaSource(vlc_media_source_provider_t *provider,
 
     return ms;
 }
+
+struct vlc_media_source_meta_list
+{
+    struct VLC_VECTOR(struct vlc_media_source_meta) vec;
+};
+
+struct vlc_media_source_meta_list *
+vlc_media_source_provider_List(vlc_media_source_provider_t *provider,
+                               enum services_discovery_category_e category)
+{
+    char **longnames;
+    int *categories;
+    char **names = vlc_sd_GetNames(provider, &longnames, &categories);
+    if (!names)
+        /* vlc_sd_GetNames() returns NULL both on error or no result */
+        return NULL;
+
+    struct vlc_media_source_meta_list *list = malloc(sizeof(*list));
+    if (unlikely(!list))
+        return NULL;
+
+    vlc_vector_init(&list->vec);
+    for (size_t i = 0; names[i]; ++i)
+    {
+        if (category && categories[i] != (int) category)
+        {
+            free(names[i]);
+            free(longnames[i]);
+            /* only list items for the requested category */
+            continue;
+        }
+
+        struct vlc_media_source_meta meta = {
+            .name = names[i],
+            .longname = longnames[i],
+            .category = categories[i],
+        };
+        bool ok = vlc_vector_push(&list->vec, meta);
+        if (unlikely(!ok)) {
+            /* failure, clean up */
+            for (char **p = names; *p; ++p)
+                free(*p);
+            for (char **p = longnames; *p; ++p)
+                free(*p);
+            vlc_vector_destroy(&list->vec);
+            free(list);
+            list = NULL;
+            break;
+        }
+    }
+
+    free(names);
+    free(longnames);
+    free(categories);
+
+    return list;
+}
+
+size_t
+vlc_media_source_meta_list_Count(vlc_media_source_meta_list_t *list)
+{
+    return list->vec.size;
+}
+
+struct vlc_media_source_meta *
+vlc_media_source_meta_list_Get(vlc_media_source_meta_list_t *list, size_t index)
+{
+    return &list->vec.data[index];
+}
+
+void
+vlc_media_source_meta_list_Delete(vlc_media_source_meta_list_t *list) {
+    for (size_t i = 0; i < list->vec.size; ++i)
+    {
+        free(list->vec.data[i].name);
+        free(list->vec.data[i].longname);
+    }
+    vlc_vector_destroy(&list->vec);
+    free(list);
+}
index cd709ef..8343bea 100644 (file)
@@ -29,6 +29,7 @@ check_PROGRAMS = \
        test_src_input_thumbnail \
        test_src_input_player \
        test_src_interface_dialog \
+       test_src_media_source \
        test_src_misc_bits \
        test_src_misc_epg \
        test_src_misc_keystore \
@@ -131,6 +132,8 @@ test_src_misc_keystore_SOURCES = src/misc/keystore.c
 test_src_misc_keystore_LDADD = $(LIBVLCCORE) $(LIBVLC)
 test_src_interface_dialog_SOURCES = src/interface/dialog.c
 test_src_interface_dialog_LDADD = $(LIBVLCCORE) $(LIBVLC)
+test_src_media_source_LDADD = $(LIBVLCCORE) $(LIBVLC)
+test_src_media_source_SOURCES = src/media_source/media_source.c
 test_modules_packetizer_helpers_SOURCES = modules/packetizer/helpers.c
 test_modules_packetizer_helpers_LDADD = $(LIBVLCCORE) $(LIBVLC)
 test_modules_packetizer_hxxx_SOURCES = modules/packetizer/hxxx.c
diff --git a/test/src/media_source/media_source.c b/test/src/media_source/media_source.c
new file mode 100644 (file)
index 0000000..2b1b357
--- /dev/null
@@ -0,0 +1,108 @@
+/*****************************************************************************
+ * test/src/media_source.c
+ *****************************************************************************
+ * Copyright (C) 2018 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "../../libvlc/test.h"
+#include "../lib/libvlc_internal.h"
+
+#include <assert.h>
+#include <vlc_common.h>
+#include <vlc_media_source.h>
+#include <vlc_vector.h>
+#include <vlc/vlc.h>
+
+static const char *libvlc_argv[] = {
+    "-v",
+    "--ignore-config",
+    "-Idummy",
+    "--no-media-library",
+};
+
+static void
+test_list(void)
+{
+    libvlc_instance_t *vlc = libvlc_new(ARRAY_SIZE(libvlc_argv), libvlc_argv);
+    assert(vlc);
+
+    vlc_media_source_provider_t *provider =
+            vlc_media_source_provider_Get(vlc->p_libvlc_int);
+    assert(provider);
+
+    vlc_media_source_meta_list_t *list =
+            vlc_media_source_provider_List(provider, 0);
+    assert(list);
+
+    size_t count = vlc_media_source_meta_list_Count(list);
+    assert(count);
+    for (size_t i = 0; i < count; ++i)
+    {
+        struct vlc_media_source_meta *meta =
+                vlc_media_source_meta_list_Get(list, i);
+        assert(meta);
+        assert(meta->name);
+        assert(meta->longname);
+        assert(meta->category); /* there is no category 0 */
+    }
+
+    vlc_media_source_meta_list_Delete(list);
+    libvlc_release(vlc);
+}
+
+static void
+test_list_filtered_by_category(void)
+{
+    libvlc_instance_t *vlc = libvlc_new(ARRAY_SIZE(libvlc_argv), libvlc_argv);
+    assert(vlc);
+
+    vlc_media_source_provider_t *provider =
+            vlc_media_source_provider_Get(vlc->p_libvlc_int);
+    assert(provider);
+
+    vlc_media_source_meta_list_t *list =
+            vlc_media_source_provider_List(provider, SD_CAT_LAN);
+    assert(list);
+
+    size_t count = vlc_media_source_meta_list_Count(list);
+    assert(count);
+    for (size_t i = 0; i < count; ++i)
+    {
+        struct vlc_media_source_meta *meta =
+                vlc_media_source_meta_list_Get(list, i);
+        assert(meta);
+        assert(meta->name);
+        assert(meta->longname);
+        assert(meta->category == SD_CAT_LAN);
+    }
+
+    vlc_media_source_meta_list_Delete(list);
+    libvlc_release(vlc);
+}
+
+int main(void)
+{
+    test_init();
+
+    test_list();
+    test_list_filtered_by_category();
+    return 0;
+}