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

Rémi Denis-Courmont remi at remlab.net
Tue Feb 9 16:07:28 CET 2016


Le 2016-02-09 14:41, Thomas Guillem a écrit :
> 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 */

Don't understand the description.

> +    libvlc_media_discoverer_internet,
> +    /** Computer services, like Discs or Apps */

Does not match reality.

> +    libvlc_media_discoverer_mycomputer,

Not so good name.

> +} 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,

Come on.

> +
> 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 );

Invalid free if i_count == 0 ??

> +}
> +
> +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;
> +}

-- 
Rémi Denis-Courmont
http://www.remlab.net/


More information about the vlc-devel mailing list