[vlc-commits] libvlc: add libvlc_media_discoverer_services_get
Thomas Guillem
git at videolan.org
Thu Feb 11 15:39:25 CET 2016
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Tue Feb 9 11:19:33 2016 +0100| [e744df4cc5ed9f89608211cca07f9681acb796f6] | committer: Thomas Guillem
libvlc: add libvlc_media_discoverer_services_get
This function return the list of services discovery handled by libVLC.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e744df4cc5ed9f89608211cca07f9681acb796f6
---
include/vlc/libvlc_media_discoverer.h | 57 ++++++++++++++++
lib/media_discoverer.c | 119 +++++++++++++++++++++++++++++++++
2 files changed, 176 insertions(+)
diff --git a/include/vlc/libvlc_media_discoverer.h b/include/vlc/libvlc_media_discoverer.h
index 8866607..170da95 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,
+ /** Podcasts */
+ libvlc_media_discoverer_podcasts,
+ /** Local directories, like Video, Music or Pictures directories */
+ libvlc_media_discoverer_localdirs,
+} 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 services 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..b64c452 100644
--- a/lib/media_discoverer.c
+++ b/lib/media_discoverer.c
@@ -385,3 +385,122 @@ 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 )
+{
+ if( i_count > 0 )
+ {
+ for( unsigned int i = 0; i < i_count; ++i )
+ {
+ free( pp_services[i]->psz_name );
+ free( pp_services[i]->psz_longname );
+ }
+ free( *pp_services );
+ 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 )
+{
+ assert( p_inst != NULL && ppp_services != NULL );
+
+ 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_podcasts:
+ i_core_cat = SD_CAT_INTERNET;
+ break;
+ case libvlc_media_discoverer_localdirs:
+ i_core_cat = SD_CAT_MYCOMPUTER;
+ break;
+ default:
+ vlc_assert_unreachable();
+ *ppp_services = NULL;
+ 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 )
+ {
+ *ppp_services = 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 = NULL, *p_services = NULL;
+ if( i_nb_services > 0 )
+ {
+ /* Double alloc here, so that the caller iterates through pointers of
+ * struct instead of structs. This allows us to modify the struct
+ * without breaking the API. */
+
+ pp_services = malloc( i_nb_services
+ * sizeof(libvlc_media_discoverer_service *) );
+ p_services = malloc( i_nb_services
+ * sizeof(libvlc_media_discoverer_service) );
+ if( pp_services == NULL || p_services == NULL )
+ {
+ free( pp_services );
+ free( p_services );
+ pp_services = NULL;
+ p_services = NULL;
+ i_nb_services = 0;
+ /* Even if alloc fails, the next loop must be run in order to free
+ * names returned by vlc_sd_GetNames */
+ }
+ }
+
+ /* Fill output pp_services or free unused name, longname */
+ char **ppsz_longname = ppsz_longnames;
+ ppsz_name = ppsz_names;
+ p_category = p_categories;
+ unsigned int i_service_idx = 0;
+ libvlc_media_discoverer_service *p_service = p_services;
+ for( ; *ppsz_name != NULL; ppsz_name++, ppsz_longname++, p_category++,
+ p_service++ )
+ {
+ if( pp_services != NULL && *p_category == i_core_cat )
+ {
+ 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 );
+
+ *ppp_services = pp_services;
+ return i_nb_services;
+}
More information about the vlc-commits
mailing list