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

Rémi Denis-Courmont remi at remlab.net
Mon Nov 28 21:23:13 CET 2011


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.

+
+/**
+ * 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.

+            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



More information about the vlc-devel mailing list