[vlc-devel] [PATCH] This commit introduces two new ways to enable/disable effects via libvlc API: * libvlc_video_set_filters_string: permits to specify the enabled effects as a one-line string * libvlc_video_set_filter: permits to specify only one effect to enable or disable and the functions does the rest to keep it coherent

Roman Minyaylov roman.minyaylov@gmail.com roman.minyaylov at gmail.com
Sun Feb 16 14:44:50 CET 2020


From: Roman Minyaylov <roman.minyaylov at gmail.com>

---
 include/vlc/libvlc_media_player.h |  20 ++++
 lib/libvlc.sym                    |   2 +
 lib/video.c                       | 158 ++++++++++++++++++++++++++++++
 3 files changed, 180 insertions(+)

diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index aa4be73418..abb4801a83 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -1913,6 +1913,26 @@ LIBVLC_API float libvlc_video_get_adjust_float( libvlc_media_player_t *p_mi,
 LIBVLC_API void libvlc_video_set_adjust_float( libvlc_media_player_t *p_mi,
                                                    unsigned option, float value );
 
+/** 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_video_set_filters_string( libvlc_media_player_t *p_mi,
+                                     const char *psz_filter_type,
+                                     const char *psz_string );
+
+/**
+ * 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_video_set_filter( libvlc_media_player_t *p_mi, const char *psz_name,
+                              bool b_enable );
+
 /** @} video */
 
 /** \defgroup libvlc_audio LibVLC audio controls
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index 67e4dcf748..71aa591d4d 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -244,6 +244,8 @@ libvlc_video_set_logo_int
 libvlc_video_set_logo_string
 libvlc_video_set_marquee_int
 libvlc_video_set_marquee_string
+libvlc_video_set_filter
+libvlc_video_set_filters_string
 libvlc_video_set_mouse_input
 libvlc_video_set_scale
 libvlc_video_set_spu
diff --git a/lib/video.c b/lib/video.c
index 6f8e6d7f59..6356ac834f 100644
--- a/lib/video.c
+++ b/lib/video.c
@@ -903,3 +903,161 @@ float libvlc_video_get_adjust_float( libvlc_media_player_t *p_mi,
 {
     return get_float( p_mi, "adjust", adjust_option_bynumber(option) );
 }
+
+void libvlc_video_set_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_video_set_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
+        {
+            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 );
+    }
+}
-- 
2.20.1



More information about the vlc-devel mailing list