[vlc-devel] [PATCH] add a way to enable/disable video effects via libvlc

PaulK gci at paulk.fr
Tue Nov 29 18:27:42 CET 2011


Le lundi 28 novembre 2011 à 22:23 +0200, Rémi Denis-Courmont a écrit :
> diff --git a/include/vlc/libvlc_media_player.h 
> b/include/vlc/libvlc_media_player.h
> index 529e0fd..ec4fcee 100644
> --- a/include/vlc/libvlc_media_player.h
> +++ b/include/vlc/libvlc_media_player.h
> @@ -863,6 +863,27 @@ LIBVLC_API void libvlc_set_fullscreen( 
> libvlc_media_player_t *p_mi, int b_fullsc
>  LIBVLC_API int libvlc_get_fullscreen( libvlc_media_player_t *p_mi );
>  
>  /**
> + * Set the video filters string
> + *
> + * \param p_mi the media player
> + * \param psz_filter_type the filters type
> + * \param psz_string the filters string
> + */
> +LIBVLC_API void libvlc_set_video_filters_string( libvlc_media_player_t *p_mi, 
> +                                     const char *psz_filter_type, 
> +                                     const char *psz_string );
> 
> I don't think we want to expose filter types as strings. In fact, I don't 
> really "get" this function, as it's not doing anything filter-specific.

The original idea was for the photobooth exemple: you can easily get a
string of concatenated (with ":")enabled effects via qtconfig so it's
much easier to directly pass this to libvlc. Though this is a special
case and the function to manage conversion from enabled array to a list
of what to enable and what to disable should be done at the libvlc-using
application level. Though for this, I would at least need a way to
retrieve the enabled filters for a vout… What do you think?

> +
> +/**
> + * Set (enable/disable) a video filter
> + *
> + * \param p_mi the media player
> + * \param psz_name the filter name
> + * \param b_add boolean for whether the filter is to enable or disable
> + */
> +LIBVLC_API void libvlc_set_video_filter( libvlc_media_player_t *p_mi, const 
> char *psz_name,
> +                              bool b_enable );
> +
> +/**
>   * Enable or disable key press events handling, according to the LibVLC 
> hotkeys
>   * configuration. By default and for historical reasons, keyboard events are
>   * handled by the LibVLC video widget.
> diff --git a/lib/libvlc.sym b/lib/libvlc.sym
> index 6582a96..1d8b9ef 100644
> --- a/lib/libvlc.sym
> +++ b/lib/libvlc.sym
> @@ -171,6 +171,8 @@ libvlc_retain
>  libvlc_set_fullscreen
>  libvlc_set_log_verbosity
>  libvlc_set_user_agent
> +libvlc_set_video_filter
> +libvlc_set_video_filters_string
>  libvlc_toggle_fullscreen
>  libvlc_toggle_teletext
>  libvlc_track_description_release
> diff --git a/lib/video.c b/lib/video.c
> index ff06979..0c71dab 100644
> --- a/lib/video.c
> +++ b/lib/video.c
> @@ -34,6 +34,7 @@
>  #include <vlc/libvlc_media_player.h>
>  
>  #include <vlc_common.h>
> +#include <vlc_modules.h>
>  #include <vlc_input.h>
>  #include <vlc_vout.h>
>  
> @@ -126,6 +127,164 @@ void libvlc_toggle_fullscreen( libvlc_media_player_t 
> *p_mi )
>      free (pp_vouts);
>  }
>  
> +void libvlc_set_video_filters_string( libvlc_media_player_t *p_mi, 
> +                                     const char *psz_filter_type, 
> +                                     const char *psz_string )
> +{
> +    size_t n;
> +
> +    if( strcmp( psz_filter_type, "video-splitter" ) != 0 &&
> +        strcmp( psz_filter_type, "video-filter" ) != 0 &&
> +        strcmp( psz_filter_type, "sub-source" ) != 0 &&
> +        strcmp( psz_filter_type, "sub-filter" ) != 0 )
> +    {
> +        libvlc_printerr( "Unknown or wrong video filter type." );
> +        return;
> +    }
> +
> +    vout_thread_t **pp_vouts = GetVouts( p_mi, &n );
> +
> +    for (size_t i = 0; i < n; i++)
> +    {
> +        vout_thread_t *p_vout = pp_vouts[i];
> +
> +        var_SetString( p_vout, psz_filter_type, psz_string );
> +
> +        vlc_object_release( p_vout );
> +    }
> +}
> +
> +void libvlc_set_video_filter( libvlc_media_player_t *p_mi, const char 
> *psz_name,
> +                              bool b_enable )
> +{
> +    char *psz_string = NULL;
> +    char *psz_string_p = NULL;
> +    const char *psz_filter_type;
> +
> +    static vout_thread_t *p_vout;
> +    size_t n;
> +    int i;
> +
> +    module_t *p_obj = module_find( psz_name );
> +    if( !p_obj )
> +    {
> +        libvlc_printerr( "Unable to find filter module \"%s\".", psz_name );
> +        return;
> +    }
> +
> +    if( module_provides( p_obj, "video splitter" ) )
> +    {
> +        psz_filter_type = "video-splitter";
> +    }
> +    else if( module_provides( p_obj, "video filter2" ) )
> +    {
> +        psz_filter_type = "video-filter";
> +    }
> +    else if( module_provides( p_obj, "sub source" ) )
> +    {
> +        psz_filter_type = "sub-source";
> +    }
> +    else if( module_provides( p_obj, "sub filter" ) )
> +    {
> +        psz_filter_type = "sub-filter";
> +    }
> +    else
> +    {
> +        libvlc_printerr( "Unknown video filter type." );
> +        return;
> +    }
> +
> +    vout_thread_t **pp_vouts = GetVouts( p_mi, &n );
> +
> +    // Apply the filters to all the vouts
> +    for (i = 0; i < n; i++)
> +    {
> +        vout_thread_t *p_vout = pp_vouts[i];
> +
> +        psz_string = var_GetString( p_vout, psz_filter_type );
> +
> +        if( b_enable ) // In this case, add the filter to the already there 
> filters
> +        {
> +            if( asprintf( &psz_string_p, "%s:%s", psz_string, psz_name ) == 
> -1 )
> +            {
> +                free( psz_string );
> +                return;
> +            }
> +            else
> +            {
> +                free( psz_string );
> +                psz_string = psz_string_p;
> +            }
> +        }
> +        else // In this case, remove the filter from the vout active filters 
> list
> +        {
> 
> The following code is complicated, probably wrong (e.g. escaping) and ugly 
> (e.g. use strsep() or strtok_r()).
> 
> The good news is, I hope, that the VLC UI has already addressed the problem 
> space of this function somehow. The code should be factored in the video 
> output core (if it's not already there in the core) and then reused by LibVLC.

Ok I indeed agree that it would be way better than my code that might
fail in some points (like for escaping indeed). I'll look forward using
the already-existing core function (vout_EnableFilter). 

> 
> +            int i_sub = 0; // i offset to extract the sub strings
> +            int o_off = 0; // offset on the out string
> +
> +            int len; // length of the filter name to remove
> +            char *psz_string_p; // out string
> +            char *psz_sub_string_p; // one filter (sub) string
> +
> +            len = strlen( psz_string );
> +            psz_string_p = calloc( 1, len + 1 );
> +
> +            if( psz_string_p == NULL )
> +                return;
> +
> +            for( i = 0 ; i <= len ; i++ ) 
> +            {
> +                if( psz_string[i] == ':' || psz_string[i] == '\0' ) // the 
> end of a sub string is reached
> +                {
> +                    // alloc and copy the sub string
> +                    psz_sub_string_p = calloc(1,  i - i_sub + 1 );
> +                    if( psz_sub_string_p == NULL )
> +                        return;
> +
> +                    memcpy( psz_sub_string_p, (void *) psz_string + i_sub, i 
> - i_sub ); 
> +                    psz_sub_string_p[i - i_sub] = '\0';
> +
> +                    // the psz_name part of the substring matches!
> +                    if( strcmp( psz_sub_string_p, psz_name ) == 0 ) // so we 
> got a match!
> +                    {
> +                        // we don't copy the substring to the output string
> +                        // if the matching psz_name is at the end of 
> psz_string, set the previous ':' to '\0' on the output string
> +                        if( psz_string[i] == '\0' )
> +                        {
> +                            unsigned char *p = (unsigned char *) 
> (psz_string_p + o_off - 1);
> +                            *p = '\0';
> +                        }
> +                    }
> +                    else // no match
> +                    {
> +                        // copy this substring to the output string
> +                        memcpy( (void *) (psz_string_p + o_off), 
> psz_sub_string_p, i - i_sub );
> +
> +                        // set the next byte on the output string to '\0' or 
> ':'
> +                        unsigned char *p = psz_string_p + o_off + i - i_sub;
> +                        *p = *((unsigned char *) psz_string + i);
> +
> +                        // increase the output string offset
> +                        o_off += i - i_sub + 1;
> +                    }
> +
> +                    // free the sub string
> +                    free( psz_sub_string_p );
> +
> +                    // increase the i sub string offset
> +                    i_sub = i + 1;
> +                }
> +            }
> +
> +            free( psz_string );
> +            psz_string = psz_string_p;
> +        }
> +
> +        var_SetString( p_vout, psz_filter_type, psz_string);
> +
> +        vlc_object_release( p_vout );
> +    }
> +}
> +
>  void libvlc_video_set_key_input( libvlc_media_player_t *p_mi, unsigned on )
>  {
>      var_SetBool (p_mi, "keyboard-events", !!on);
> -- 
> 1.7.4.1
> 
> 
> 
> -- 
> Rémi Denis-Courmont
> http://www.remlab.net/
> http://fi.linkedin.com/in/remidenis
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> http://mailman.videolan.org/listinfo/vlc-devel





More information about the vlc-devel mailing list