[vlc-devel] [PATCH] libvlc: add libvlc_media_discoverer_services_get

Thomas Guillem thomas at gllm.fr
Tue Feb 9 13:41:41 CET 2016


This function return the list of services discovery handled by libVLC.
---
 include/vlc/libvlc_media_discoverer.h |  57 +++++++++++++++++++
 lib/media_discoverer.c                | 101 ++++++++++++++++++++++++++++++++++
 2 files changed, 158 insertions(+)

diff --git a/include/vlc/libvlc_media_discoverer.h b/include/vlc/libvlc_media_discoverer.h
index 8866607..f11b2c6 100644
--- a/include/vlc/libvlc_media_discoverer.h
+++ b/include/vlc/libvlc_media_discoverer.h
@@ -30,6 +30,31 @@
 extern "C" {
 # endif
 
+/**
+ * Category of a media discoverer service
+ * \see libvlc_media_discoverer_services_get()
+ */
+typedef enum {
+    /** devices, like portable music player */
+    libvlc_media_discoverer_devices,
+    /** LAN/WAN services, like Upnp, SMB, or SAP */
+    libvlc_media_discoverer_lan,
+    /** Internet of Website channels services */
+    libvlc_media_discoverer_internet,
+    /** Computer services, like Discs or Apps */
+    libvlc_media_discoverer_mycomputer,
+} libvlc_media_discoverer_category;
+
+/**
+ * Media discoverer service
+ * \see libvlc_media_discoverer_services_get()
+ */
+typedef struct {
+    char *psz_name;
+    char *psz_longname;
+    libvlc_media_discoverer_category i_cat;
+} libvlc_media_discoverer_service;
+
 /** \defgroup libvlc_media_discoverer LibVLC media discovery
  * \ingroup libvlc
  * LibVLC media discovery finds available media via various means.
@@ -145,6 +170,38 @@ LIBVLC_API libvlc_event_manager_t *
 LIBVLC_API int
         libvlc_media_discoverer_is_running( libvlc_media_discoverer_t * p_mdis );
 
+/**
+ * Get media discoverer services by category
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_inst libvlc instance
+ * \param i_cat category of the service to fetch
+ * \param ppp_services address to store an allocated array of media discoverer
+ * services (must be freed with libvlc_media_discoverer_services_release() by
+ * the caller) [OUT]
+ *
+ * \return the number of media discoverer services (zero on error)
+ */
+LIBVLC_API unsigned int
+libvlc_media_discoverer_services_get( libvlc_instance_t *p_inst,
+                                      libvlc_media_discoverer_category i_cat,
+                                      libvlc_media_discoverer_service ***ppp_services );
+
+/**
+ * Release an array of media discoverer services
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \see libvlc_media_discoverer_services_get()
+ *
+ * \param pp_services array to release
+ * \param i_count number of elements in the array
+ */
+LIBVLC_API void
+libvlc_media_discoverer_services_release( libvlc_media_discoverer_service **pp_services,
+                                          unsigned int i_count );
+
 /**@} */
 
 # ifdef __cplusplus
diff --git a/lib/media_discoverer.c b/lib/media_discoverer.c
index ed9390b..3e76780 100644
--- a/lib/media_discoverer.c
+++ b/lib/media_discoverer.c
@@ -385,3 +385,104 @@ libvlc_media_discoverer_is_running( libvlc_media_discoverer_t * p_mdis )
 {
     return p_mdis->running;
 }
+
+void
+libvlc_media_discoverer_services_release( libvlc_media_discoverer_service **pp_services,
+                                          unsigned int i_count )
+{
+    for( unsigned int i = 0; i < i_count; ++i )
+    {
+        free( pp_services[i]->psz_name );
+        free( pp_services[i]->psz_longname );
+        free( pp_services[i] );
+    }
+    free( pp_services );
+}
+
+unsigned int
+libvlc_media_discoverer_services_get( libvlc_instance_t *p_inst,
+                                      libvlc_media_discoverer_category i_cat,
+                                      libvlc_media_discoverer_service ***ppp_services )
+{
+    int i_core_cat;
+    switch( i_cat )
+    {
+    case libvlc_media_discoverer_devices:
+        i_core_cat = SD_CAT_DEVICES;
+        break;
+    case libvlc_media_discoverer_lan:
+        i_core_cat = SD_CAT_LAN;
+        break;
+    case libvlc_media_discoverer_internet:
+        i_core_cat = SD_CAT_INTERNET;
+        break;
+    case libvlc_media_discoverer_mycomputer:
+        i_core_cat = SD_CAT_MYCOMPUTER;
+        break;
+    default:
+        vlc_assert_unreachable();
+        return 0;
+    }
+
+    /* Fetch all sd names, longnames and categories */
+    char **ppsz_names, **ppsz_longnames;
+    int *p_categories;
+    ppsz_names = vlc_sd_GetNames( p_inst->p_libvlc_int, &ppsz_longnames,
+                                  &p_categories );
+
+    if( ppsz_names == NULL )
+        return 0;
+
+    /* Count the number of sd matching our category (i_cat/i_core_cat) */
+    unsigned int i_nb_services = 0;
+    char **ppsz_name = ppsz_names;
+    int *p_category = p_categories;
+    for( ; *ppsz_name != NULL; ppsz_name++, p_category++ )
+    {
+        if( *p_category == i_core_cat )
+            i_nb_services++;
+    }
+
+    libvlc_media_discoverer_service **pp_services = i_nb_services > 0 ?
+        malloc( i_nb_services * sizeof(libvlc_media_discoverer_service *) ) : NULL;
+
+    /* Fill output pp_services or free unused name, longnames */
+    char **ppsz_longname = ppsz_longnames;
+    ppsz_name = ppsz_names;
+    p_category = p_categories;
+    unsigned int i_service_idx = 0;
+    for( ; *ppsz_name != NULL; ppsz_name++, ppsz_longname++, p_category++ )
+    {
+        if( pp_services != NULL && *p_category == i_core_cat )
+        {
+            libvlc_media_discoverer_service *p_service =
+                malloc( sizeof(libvlc_media_discoverer_service) );
+            if( p_service == NULL )
+            {
+                libvlc_media_discoverer_services_release( pp_services,
+                                                          i_service_idx );
+                pp_services = NULL;
+                i_nb_services = 0;
+            }
+            else
+            {
+                p_service->psz_name = *ppsz_name;
+                p_service->psz_longname = *ppsz_longname;
+                p_service->i_cat = i_cat;
+                pp_services[i_service_idx++] = p_service;
+            }
+        }
+        else
+        {
+            free( *ppsz_name );
+            free( *ppsz_longname );
+        }
+    }
+    free( ppsz_names );
+    free( ppsz_longnames );
+    free( p_categories );
+
+    if( i_nb_services > 0 )
+        *ppp_services = pp_services;
+    return i_nb_services;
+}
-- 
2.7.0.rc3



More information about the vlc-devel mailing list