[vlc-devel] [PATCH v6 3/3] media source: add API to get available sources
Romain Vimont
rom1v at videolabs.io
Thu Nov 22 18:58:39 CET 2018
Add functions to get the list of media source metadata, optionally
only for a given category.
---
include/vlc_media_source.h | 54 ++++++++++++++
src/libvlccore.sym | 4 +
src/media_source/media_source.c | 81 ++++++++++++++++++++
test/Makefile.am | 3 +
test/src/media_source/media_source.c | 108 +++++++++++++++++++++++++++
5 files changed, 250 insertions(+)
create mode 100644 test/src/media_source/media_source.c
diff --git a/include/vlc_media_source.h b/include/vlc_media_source.h
index 650a356534..601b23aa65 100644
--- a/include/vlc_media_source.h
+++ b/include/vlc_media_source.h
@@ -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
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 9c4a7eab49..9423e2fc20 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -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
diff --git a/src/media_source/media_source.c b/src/media_source/media_source.c
index 6ff492757b..45ad983253 100644
--- a/src/media_source/media_source.c
+++ b/src/media_source/media_source.c
@@ -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);
+}
diff --git a/test/Makefile.am b/test/Makefile.am
index cd709ef232..8343bea501 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -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
index 0000000000..2b1b357373
--- /dev/null
+++ b/test/src/media_source/media_source.c
@@ -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;
+}
--
2.19.1
More information about the vlc-devel
mailing list