vlc | branch: master | Thomas Guillem <[email protected]> | 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; +} _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
