[vlc-devel] Re: RFC: refurbishing the configuration manager

Samuel Hocevar sam at zoy.org
Wed Oct 9 18:35:03 CEST 2002

On Tue, Oct 08, 2002, Gildas Bazin wrote:

> - Local configuration variables:

>      [...]

>      I don't think this kind of variables is really necessary because you
>      can create them programmatically in your module. For instance the
>      video output modules use a b_fullscreen boolean to set the currently
>      requested fullscreen mode.

   b_fullscreen is somewhat particular because it is common to all video
output modules, so we could put it in the vout_thread_t struct. The same
goes for width and height. But we can't put everything in vout_thread_t,
for instance the window title or its geometry. This would also solve an
ugliness in the MacOS X plugin where p_vout accesses p_intf->p_sys->foo,
while foo could be accessed as a variable so that the video output does
not need to include the interface's private headers.

>      [...]

>      I never had time to do this part, mainly because what I wanted to do
>      was quite complex. For instance one nice feature of these variables is
>      to allow modules to define variables that are dynamically modifiable by
>      users, but _how_ do you give a user the possibility to modify them ?
>      Certainly not through the "preferences menu" because this one is by
>      definition used to modigy the global variables in order for the user
>      to save its default configuration.

   We have access to all the object structure (run "vlc -I rc" and type
"tree" or "list" to see what I mean), so we can build a list of current
objects and ask the GUI to build windows to handle this, like we do for
the modules.

>      So you need a new menu per "living" object to allow the user to
>      dynamically modify the configuration of this object. Hmmm, not easy to
>      integrate in a GUI...

   Yes we'll probably have synchronization issues, when dealing with
an object. There are several solutions to this: crash, silently ignore
changes to a dead object, constantly monitor objects, register callbacks
to be called on object deattach/destruction... 

>      Another nice thing to have would be a scripting language that would
>      allow to modify these local variables. You would then be able to
>      control VLC with little scripts saying things like "run mympegfile1.mpg
>      in fullscreen with such video filter, and once your are finished, run 
>      this other file with those parameters....". Of course the details of
>      this scripting language still have to be defined (format, grammar,
>      etc...)

   Yes, this would definitely be cool. There's a proof of concept in the
rc plugin that also shows the callback mechanism, try this:

    # vlc -I rc
    intf gnome
    set gnome-toolbartext 1
    set gnome-toolbartext 0

  One thing to keep in mind if we are going to use a language is not
to try to complicate it. No loops, no tests, no complicated structures
(I'd even say no variables). Just a few functions like "set variable",
"new interface", "new target".

  If we want high-level stuff, we'll create Perl (or Python or Scheme
or PHP or whatever) bindings for libvlc, and feed the script to the
language interpreter that will spawn vlc.

> [...]
> Why not always specify the name of the module where this variable is 
> defined, except when this module is the main module (so general options 
> would have more simple names)?

   There are times where I'd like to set "tooltips" to 0, and have
tooltips disabled for the Gtk _and_ Gnome interfaces.

> This also has the advantage of reducing the 
> cost of the variables lookup.

   This is a good point, but not a decisive argument IMHO. Using a
simple hash function already reduces lookup times probably by an order
of magnitude, and we shouldn't see variables as a lightfast way to
share data anyway.

> >  - we should be able to create new variables for any object that suits
> >    us, and not restrain to the module discovery step
> Hmmm, I'm not really sure this is actually useful. And this would for sure 
> make things more complicated (and I'm not even talking about the fact that 
> if you do this then it is quite difficult to know if and when a variable 
> has been created). Unless I'm missing something, this feature is IMHO 
> overkill.

   I'll try to elaborate on reasons that led me to this idea:

  - the existence of a variable can be a good test on whether an object
    supports a specific feature or not without having to create a new
    function in the API, and the feature can be runtime-dependent.
  - it would allow to completely unload a plugin and reload it.
  - think about a mixer plugin; upon initialization it does not know
    how many channels it has, so you can maybe set its default gain,
    but not much more; but whenever it gets initialized, it can
    export as many variables as it has input or output channels for
    full configuration.

   Ok, maybe the mixer example isn't very good, because mixers are tied
hard enough to vlc to have a proper API. I thought about another one:
imagine a module that can create modules at runtime (for instance an
XMMS plugin loader); it will have to create variables on the fly when
interpreting the plugin capabilites.

> I also don't think that we need to differentiate between the creation of a 
> global or local config variable, because afaics a config variable always 
> need to be created as both. It is as useful to have a static version of the 
> config variable as a dynamic version (remember, one is used for the default 
> configuration of an object and the other is used for the dynamic 
> configuration of this object).

   This can be done in a transparent way; by default all variables can be
set to the p_libvlc or p_vlc object. When a variable is set, it is either
written to p_vlc, or transparently created in the local object and stored
in the local object. When a variable is read, it is read from the local
object if it exists, otherwise it is read from the parent object, and so
on until it is found (and we always reach p_libvlc this way).

> What I have in mind would rather be to keep the current way of declaring 
> config variables ( to create the global (static) version of the config 
> variables). Then when a new object is spawned, we would create a local 
> version of these config variables (just by duplication module_config_t), 
> that way the new object starts with the user's defaults. 

   This does not seem unlike what I said above, except I do
copy-on-write (not sure my way iss really better because multiple
reads can take time).

> >     /* New stuff */
> >     void var_New( vlc_object_t *, char *psz_name, int i_type );
> >     void var_SetScope( vlc_object_t *, char *psz_name, int i_scope );
> >     void var_Delete( vlc_object_t *, char *psz_name );
> > 
> >     /* i_type could be one of STRING, BOOLEAN, INT, INT_FROM_LIST, FLOAT,
> >      * FLOAT_FROM_LIST, STRING_FROM_LIST, but also derivate types such as 
> >      * FONT, TIMESTAMP... */
> > 
> >     /* i_scope could be one of OBJECT_LOCAL, VLC_LOCAL, GLOBAL... */
> > 
> As explained above, I would rather keep the current macros (add_string, add 
> string_from_list, etc...).

   We could adapt the current macros so that they call the proper
functions in this API. This would allow minimal code changes in the

> >     /* Functions that we already have (could be merged into one function
> >      * and several macros) */
> >     int var_SetInt( vlc_object_t *, char *psz_name, s64 i_value );
> >     int var_SetString( vlc_object_t *, char *psz_name, char *psz_value );
> >     int var_SetFloat( vlc_object_t *, char *psz_name, float f_value );
> > 
> >     s64 var_GetInt( vlc_object_t *, char *psz_name );
> >     char * var_GetString( vlc_object_t *, char *psz_name );
> >     float var_GetFloat( vlc_object_t *, char *psz_name );
> > 
> These would be the functions to modify the local config variables.
> We would also need to handle the global variables but instead of extending 
> the above functions I would rather add a new set of functions.

   Or just add a flag to the prototypes? I'm all for reducing the
amount of functions in VLC by the way, especially those which do
"almost" the same thing. We could even have a vlc_var_t typedef which
is an union of s64, mtime_t, void *, char *, float and whatever, so
that we'd only have one var_Set() and one var_Get functions. And it
would even fit in a register (or at least in a return value).

> int globalVar_SetInt(  char *psz_module, char *psz_name, s64 i_value );
> int globalVar_SetString( char *psz_module, char *psz_name, char *psz_value);
> int globalVar_SetFloat( char *psz_module, char *psz_name, float f_value);
> The "char *psz_module" parameter is needed to define a namespace for the 
> config variable (the namespace is the module name).

   Makes sense to me, but tokenizing psz_name = "module::name" is not
that costly IMHO.

   Thanks a lot for your comments.

This is the vlc-devel mailing-list, see http://www.videolan.org/vlc/
To unsubscribe, please read http://www.videolan.org/lists.html
If you are in trouble, please contact <postmaster at videolan.org>

More information about the vlc-devel mailing list