Commit e744df4c authored by Thomas Guillem's avatar Thomas Guillem

libvlc: add libvlc_media_discoverer_services_get

This function return the list of services discovery handled by libVLC.
parent 04236fb1
...@@ -30,6 +30,31 @@ ...@@ -30,6 +30,31 @@
extern "C" { extern "C" {
# endif # 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 /** \defgroup libvlc_media_discoverer LibVLC media discovery
* \ingroup libvlc * \ingroup libvlc
* LibVLC media discovery finds available media via various means. * LibVLC media discovery finds available media via various means.
...@@ -145,6 +170,38 @@ LIBVLC_API libvlc_event_manager_t * ...@@ -145,6 +170,38 @@ LIBVLC_API libvlc_event_manager_t *
LIBVLC_API int LIBVLC_API int
libvlc_media_discoverer_is_running( libvlc_media_discoverer_t * p_mdis ); 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 # ifdef __cplusplus
......
...@@ -385,3 +385,122 @@ libvlc_media_discoverer_is_running( libvlc_media_discoverer_t * p_mdis ) ...@@ -385,3 +385,122 @@ libvlc_media_discoverer_is_running( libvlc_media_discoverer_t * p_mdis )
{ {
return p_mdis->running; 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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment