[vlc-devel] [PATCH 2/3] Create services_advertisement VLC object

Roland Bewick roland.bewick at gmail.com
Tue Sep 3 16:31:32 CEST 2019


On 2/09/2019 11:36 PM, Thomas Guillem wrote:
>
> On Mon, Sep 2, 2019, at 14:00, Thomas Guillem wrote:
>>
>> On Mon, Sep 2, 2019, at 07:25, Roland Bewick wrote:
>>> - Add services-advertisement object to libvlc
>>> - Parse --services-advertisement option and load modules on VLC startup
>>> - unload services advertisement modules on VLC shutdown
>>> ---
>>>   include/vlc_services_advertisement.h | 87 ++++++++++++++++++++++++++++
>>>   src/Makefile.am                      |  2 +
>>>   src/libvlc.c                         | 32 ++++++++++
>>>   src/libvlc.h                         |  2 +
>>>   src/misc/services_advertisement.c    | 84 +++++++++++++++++++++++++++
>>>   5 files changed, 207 insertions(+)
>>>   create mode 100644 include/vlc_services_advertisement.h
>>>   create mode 100644 src/misc/services_advertisement.c
>>>
>>> diff --git a/include/vlc_services_advertisement.h
>>> b/include/vlc_services_advertisement.h
>>> new file mode 100644
>>> index 0000000000..1f217cecf3
>>> --- /dev/null
>>> +++ b/include/vlc_services_advertisement.h
>>> @@ -0,0 +1,87 @@
>>> +/*****************************************************************************
>>> + * vlc_services_advertisement.h : Services Advertisement functions
>>> +
>>> *****************************************************************************
>>> + * Copyright (C) 1999-2019 VLC authors and VideoLAN
>>> + *
>>> + * Authors:
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> modify it
>>> + * under the terms of the GNU Lesser General Public License as
>>> published by
>>> + * the Free Software Foundation; either version 2.1 of the License, or
>>> + * (at your option) any later version.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>> + * GNU Lesser General Public License for more details.
>>> + *
>>> + * You should have received a copy of the GNU Lesser General Public
>>> License
>>> + * along with this program; if not, write to the Free Software
>>> Foundation,
>>> + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
>>> +
>>> *****************************************************************************/
>>> +
>>> +#ifndef VLC_SERVICES_ADVERTISEMENT_H_
>>> +#define VLC_SERVICES_ADVERTISEMENT_H_
>>> +
>>> +#include <vlc_input.h>
>>> +
>>> +/**
>>> + * \file
>>> + * This file lists functions and structures for service advertisement
>>> (SA) in vlc
>>> + */
>>> +
>>> +# ifdef __cplusplus
>>> +extern "C" {
>>> +# endif
>>> +
>>> +/**
>>> + * @{
>>> + */
>>> +
>>> +/**
>>> + * Main service advertisement structure to build a SA module
>>> + */
>>> +typedef struct services_advertisement_t
>> It should be named vlc_services_advertisement_t
>>
>>> +{
>>> +    struct vlc_object_t obj;
>>> +
>>> +    struct services_advertisement_t *p_next;  /** Points to the next
>>> SA element */
>>> +
>>> +    module_t *          p_module;             /**< Loaded module */
>>> +
>>> +    char *psz_name;                           /**< Main name of the SA
>>> */
>>> +    config_chain_t *p_cfg;                    /**< Configuration for
>>> the SA */
>>> +
>>> +    const char *description;                  /**< Human-readable name
>>> */
>>> +
>>> +    void *p_sys;                              /**< Custom private data
>>> */
>>> +} services_advertisement_t;
>> There are some members that should not be visible by a SA module, like p_next
>> You don't want to allow a SA module to mess with next SA modules for examples.
>> You should split this struct in two, the public one and the private one.
>>
>> Example, In the internal part:
>> struct vlc_services_advertisement_priv_t
>> {
>>      struct vlc_services_advertisement_t sa;
>>      struct vlc_services_advertisement_t *next;
> And by the way, why do you need next here ? There should be only one SA module per VLC instance.

I'm happy with this. Is there possibility of two separate interfaces 
wanting to advertise themselves? if we need to support more than one 
service type, libmicrodns might need to be modified again.

>
>> };
>>
>> You allocate vlc_services_advertisement_priv_t directly, but pass
>> &priv->sa to the modules.
>>
>> If needed,  in your internal sa implemenation, you can add this helper
>> to get the private struct from the public one.
>>
>> static inline struct vlc_services_advertisement_priv_t *sa_get_priv(
>> struct vlc_services_advertisement_t *sa)
>> {
>>      return container_of( sa, struct vlc_services_advertisement_priv_t,
>> sa );
>> }
>>
>>> +
>>> +
>>> +/***********************************************************************
>>> + * Service Advertisement
>>> +
>>> ***********************************************************************/
>>> +
>>> +/**
>>> + * Loads a service advertisement (SA) module for the given
>>> configuration
>>> + * and adds it to the VLC's list of SA modules.
>>> + *
>>> + * @param chain configuration chain string
>>> + * @return VLC_SUCCESS or an error code
>>> + */
>>> +int vlc_sa_Create( libvlc_int_t *libvlc, const char *chain );
>>> +
>>> +/**
>>> + * Stops and unloads all services advertisement modules.
>>> + *
>>> + * @param libvlc the LibVLC instance
>>> + */
>>> +void vlc_sa_DestroyAll( libvlc_int_t *libvlc );
>>> +
>>> +
>>> +/** @} */
>>> +# ifdef __cplusplus
>>> +}
>>> +# endif
>>> +
>>> +#endif
>>> diff --git a/src/Makefile.am b/src/Makefile.am
>>> index 9f0b6df13a..09a69b99b4 100644
>>> --- a/src/Makefile.am
>>> +++ b/src/Makefile.am
>>> @@ -85,6 +85,7 @@ pluginsinclude_HEADERS = \
>>>   	../include/vlc_probe.h \
>>>   	../include/vlc_rand.h \
>>>   	../include/vlc_services_discovery.h \
>>> +	../include/vlc_services_advertisement.h \
>>>   	../include/vlc_fingerprinter.h \
>>>   	../include/vlc_interrupt.h \
>>>   	../include/vlc_renderer_discovery.h \
>>> @@ -364,6 +365,7 @@ libvlccore_la_SOURCES = \
>>>   	misc/interrupt.c \
>>>   	misc/keystore.c \
>>>   	misc/renderer_discovery.c \
>>> +	misc/services_advertisement.c \
>>>   	misc/threads.c \
>>>   	misc/cpu.c \
>>>   	misc/epg.c \
>>> diff --git a/src/libvlc.c b/src/libvlc.c
>>> index ee88d363d4..8afdc64b14 100644
>>> --- a/src/libvlc.c
>>> +++ b/src/libvlc.c
>>> @@ -63,6 +63,7 @@
>>>   #include <vlc_modules.h>
>>>   #include <vlc_media_library.h>
>>>   #include <vlc_thumbnailer.h>
>>> +#include <vlc_services_advertisement.h>
>>>   
>>>   #include "libvlc.h"
>>>   
>>> @@ -92,6 +93,7 @@ libvlc_int_t * libvlc_InternalCreate( void )
>>>       priv = libvlc_priv (p_libvlc);
>>>       vlc_mutex_init(&priv->lock);
>>>       priv->interfaces = NULL;
>>> +    priv->services_advertisements = NULL;
>>>       priv->main_playlist = NULL;
>>>       priv->p_vlm = NULL;
>>>       priv->media_source_provider = NULL;
>>> @@ -116,6 +118,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
>>>       char *       psz_modules = NULL;
>>>       char *       psz_parser = NULL;
>>>       char *       psz_control = NULL;
>>> +    char *       psz_services_advertisement = NULL;
>>>       char        *psz_val;
>>>       int          i_ret = VLC_EGENERIC;
>>>   
>>> @@ -330,6 +333,32 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc,
>>> int i_argc,
>>>       if( var_InheritBool( p_libvlc, "network-synchronisation") )
>>>           libvlc_InternalAddIntf( p_libvlc, "netsync,none" );
>>>   
>>> +    /*
>>> +     * Load service advertisement modules
>>> +     */
>>> +    psz_services_advertisement = var_InheritString( p_libvlc,
>>> +                                                    "services-advertisement" );
>>> +    psz_parser = psz_services_advertisement;
>>> +
>>> +    while( psz_parser && *psz_parser )
>>> +    {
>>> +        char *psz_module, *psz_temp;
>>> +        psz_module = psz_parser;
>>> +        psz_parser = strchr( psz_module, ':' );
>>> +        if( psz_parser )
>>> +        {
>>> +            *psz_parser = '\0';
>>> +            psz_parser++;
>>> +        }
>>> +        if( asprintf( &psz_temp, "%s,none", psz_module ) != -1)
>>> +        {
>>> +            vlc_sa_Create( p_libvlc, psz_temp );
>>> +            free( psz_temp );
>>> +        }
>>> +    }
>>> +
>>> +    free( psz_services_advertisement );
>>> +
>>>   #ifdef __APPLE__
>>>       var_Create( p_libvlc, "drawable-view-top", VLC_VAR_INTEGER );
>>>       var_Create( p_libvlc, "drawable-view-left", VLC_VAR_INTEGER );
>>> @@ -395,6 +424,9 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
>>>       msg_Dbg( p_libvlc, "removing all interfaces" );
>>>       intf_DestroyAll( p_libvlc );
>>>   
>>> +    /* Ask the service announcement modules to stop and destroy them */
>>> +    vlc_sa_DestroyAll( p_libvlc );
>>> +
>>>       if ( priv->p_thumbnailer )
>>>           vlc_thumbnailer_Release( priv->p_thumbnailer );
>>>   
>>> diff --git a/src/libvlc.h b/src/libvlc.h
>>> index ff50bd9218..8f97b456f5 100644
>>> --- a/src/libvlc.h
>>> +++ b/src/libvlc.h
>>> @@ -193,6 +193,7 @@ typedef struct vlc_actions_t vlc_actions_t;
>>>   typedef struct vlc_playlist vlc_playlist_t;
>>>   typedef struct vlc_media_source_provider_t vlc_media_source_provider_t;
>>>   typedef struct intf_thread_t intf_thread_t;
>>> +typedef struct services_advertisement_t services_advertisement_t;
>>>   
>>>   typedef struct libvlc_priv_t
>>>   {
>>> @@ -210,6 +211,7 @@ typedef struct libvlc_priv_t
>>>       vlc_actions_t *actions; ///< Hotkeys handler
>>>       struct vlc_medialibrary_t *p_media_library; ///< Media library
>>> instance
>>>       struct vlc_thumbnailer_t *p_thumbnailer; ///< Lazily instantiated
>>> media thumbnailer
>>> +    services_advertisement_t * services_advertisements; // Linked-list
>>> of SA modules
>>>   
>>>       /* Exit callback */
>>>       vlc_exit_t       exit;
>>> diff --git a/src/misc/services_advertisement.c
>>> b/src/misc/services_advertisement.c
>>> new file mode 100644
>>> index 0000000000..c28db5e95c
>>> --- /dev/null
>>> +++ b/src/misc/services_advertisement.c
>>> @@ -0,0 +1,84 @@
>>> +/*****************************************************************************
>>> + * services_advertisement.c : Manage services advertisement modules
>>> +
>>> *****************************************************************************
>>> + * Copyright (C) 1999-2019 VLC authors and VideoLAN
>>> + *
>>> + * Authors:
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> modify it
>>> + * under the terms of the GNU Lesser General Public License as
>>> published by
>>> + * the Free Software Foundation; either version 2.1 of the License, or
>>> + * (at your option) any later version.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>> + * GNU Lesser General Public License for more details.
>>> + *
>>> + * You should have received a copy of the GNU Lesser General Public
>>> License
>>> + * along with this program; if not, write to the Free Software
>>> Foundation,
>>> + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
>>> +
>>> *****************************************************************************/
>>> +#ifdef HAVE_CONFIG_H
>>> +# include "config.h"
>>> +#endif
>>> +#include <assert.h>
>>> +
>>> +#include <vlc_common.h>
>>> +#include <vlc_services_advertisement.h>
>>> +#include <vlc_modules.h>
>>> +#include "../libvlc.h"
>>> +
>>> +int vlc_sa_Create( libvlc_int_t *libvlc, const char *chain )
>>> +{
>>> +    assert( libvlc );
>>> +    libvlc_priv_t *priv = libvlc_priv( libvlc );
>>> +
>>> +    services_advertisement_t *sa = vlc_custom_create( libvlc, sizeof(
>>> *sa ),
>>> +                                                 "services
>>> advertisement" );
>>> +    if( unlikely( sa == NULL ) )
>>> +        return VLC_ENOMEM;
>>> +
>>> +    free( config_ChainCreate( &sa->psz_name, &sa->p_cfg, chain ) );
>>> +
>>> +    sa->description = NULL;
>>> +
>>> +    sa->p_module = module_need( sa, "services_advertisement",
>>> +                                sa->psz_name, true );
>>> +    if ( sa->p_module == NULL )
>>> +    {
>>> +        msg_Err( sa, "no suitable services advertisement module" );
>>> +        return VLC_EGENERIC;
>>> +    }
>>> +
>>> +    vlc_mutex_lock( &priv->lock );
>>> +    sa->p_next = priv->services_advertisements;
>>> +    priv->services_advertisements = sa;
>>> +    vlc_mutex_unlock( &priv->lock );
>>> +
>>> +    return VLC_SUCCESS;
>>> +}
>>> +
>>> +void vlc_sa_DestroyAll( libvlc_int_t *libvlc )
>>> +{
>>> +    libvlc_priv_t *priv = libvlc_priv( libvlc );
>>> +
>>> +    vlc_mutex_lock( &priv->lock );
>>> +    services_advertisement_t *sa, **pp =
>>> &priv->services_advertisements;
>>> +
>>> +    while( ( sa = *pp ) != NULL )
>>> +    {
>>> +        *pp = sa->p_next;
>>> +        vlc_mutex_unlock( &priv->lock );
>>> +
>>> +        if( sa->p_module )
>>> +            module_unneed( sa, sa->p_module );
>>> +
>>> +        config_ChainDestroy( sa->p_cfg );
>>> +        free( sa->psz_name );
>>> +        vlc_object_delete( sa );
>>> +
>>> +        vlc_mutex_lock( &priv->lock );
>>> +    }
>>> +    vlc_mutex_unlock( &priv->lock );
>>> +}
>>> \ No newline at end of file
>>> -- 
>>> 2.17.1
>>>
>>> _______________________________________________
>>> vlc-devel mailing list
>>> To unsubscribe or modify your subscription options:
>>> https://mailman.videolan.org/listinfo/vlc-devel
>> _______________________________________________
>> vlc-devel mailing list
>> To unsubscribe or modify your subscription options:
>> https://mailman.videolan.org/listinfo/vlc-devel
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list