[vlc-devel] [PATCH 01/11] vout: trigger filters commands

Thomas Guillem thomas at gllm.fr
Mon May 29 18:52:55 CEST 2017


---
 src/video_output/video_output.c  | 94 +++++++++++++++++++++++++++++++++++++++-
 src/video_output/vout_internal.h |  1 +
 2 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 730b902b24..a1d3ec1911 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -46,12 +46,14 @@
 #include <vlc_spu.h>
 #include <vlc_vout_osd.h>
 #include <vlc_image.h>
+#include <vlc_plugin.h>
 
 #include <libvlc.h>
 #include "vout_internal.h"
 #include "interlacing.h"
 #include "display.h"
 #include "window.h"
+#include "../modules/modules.h"
 
 /*****************************************************************************
  * Local prototypes
@@ -140,6 +142,8 @@ static vout_thread_t *VoutCreate(vlc_object_t *object,
 
     vout_snapshot_Init(&vout->p->snapshot);
 
+    vlc_array_init(&vout->p->filter.callbacks);
+
     /* Initialize locks */
     vlc_mutex_init(&vout->p->filter.lock);
     vlc_mutex_init(&vout->p->spu_lock);
@@ -649,6 +653,85 @@ int vout_HideWindowMouse(vout_thread_t *vout, bool hide)
 }
 
 /* */
+struct filter_callback
+{
+    filter_t *  filter;
+    const char *psz_name;
+    int         type;
+};
+
+static int FilterProxyCallback(vlc_object_t *p_this, char const *psz_var,
+                         vlc_value_t oldval, vlc_value_t newval,
+                         void *p_data)
+{
+    (void) p_this; (void) oldval;
+    struct filter_callback *callback = p_data;
+    var_SetChecked(callback->filter, psz_var, callback->type, newval);
+    return 0;
+}
+
+static void ThreadDelFilterCallbacks(vout_thread_t *vout)
+{
+    for (size_t i = 0; i < vlc_array_count(&vout->p->filter.callbacks); ++i)
+    {
+        struct filter_callback *callback =
+            vlc_array_item_at_index(&vout->p->filter.callbacks, i);
+        var_DelCallback(vout, callback->psz_name, FilterProxyCallback, callback);
+        var_Destroy(vout, callback->psz_name);
+        free(callback);
+    }
+    vlc_array_clear(&vout->p->filter.callbacks);
+}
+
+static int ThreadAddFilterCallbacks(vout_thread_t *vout, filter_t *filter)
+{
+    /* Duplicate every command variables from the filter to the vout, and add a
+     * proxy callback to trigger filters events from the vout. */
+
+    vlc_plugin_t *plugin = filter->p_module->plugin;
+    for (size_t i = 0; i < plugin->conf.size; ++i)
+    {
+        module_config_t *config = &plugin->conf.items[i];
+        switch (config->i_type)
+        {
+            case CONFIG_ITEM_FLOAT:
+            case CONFIG_ITEM_INTEGER:
+            case CONFIG_ITEM_BOOL:
+            case CONFIG_ITEM_STRING:
+                break;
+            default:
+                continue;
+        }
+        int var_type = var_Type(filter, config->psz_name);
+        if (var_type & VLC_VAR_ISCOMMAND)
+        {
+#ifndef NDEBUG
+            /* Make sure that each option is unique */
+            for (size_t i = 0; i < vlc_array_count(&vout->p->filter.callbacks);
+                 ++i)
+            {
+                struct filter_callback *callback =
+                    vlc_array_item_at_index(&vout->p->filter.callbacks, i);
+                assert(strcmp(callback->psz_name, config->psz_name) != 0);
+            }
+#endif
+            struct filter_callback *callback = malloc(sizeof(*callback));
+            if (unlikely(callback == NULL))
+                return VLC_ENOMEM;
+
+            callback->filter = filter;
+            callback->psz_name = config->psz_name;
+            callback->type = var_type & VLC_VAR_CLASS;
+            vlc_array_append(&vout->p->filter.callbacks, callback);
+
+            var_Create(vout, callback->psz_name, var_type | VLC_VAR_DOINHERIT);
+            var_AddCallback(vout, callback->psz_name, FilterProxyCallback,
+                            callback);
+        }
+    }
+    return VLC_SUCCESS;
+}
+
 static picture_t *VoutVideoFilterInteractiveNewPicture(filter_t *filter)
 {
     vout_thread_t *vout = filter->owner.sys;
@@ -702,6 +785,7 @@ static void ThreadChangeFilters(vout_thread_t *vout,
                                 bool is_locked)
 {
     ThreadFilterFlush(vout, is_locked);
+    ThreadDelFilterCallbacks(vout);
 
     vlc_array_t array_static;
     vlc_array_t array_interactive;
@@ -770,10 +854,16 @@ static void ThreadChangeFilters(vout_thread_t *vout,
         for (size_t i = 0; i < vlc_array_count(array); i++) {
             vout_filter_t *e = vlc_array_item_at_index(array, i);
             msg_Dbg(vout, "Adding '%s' as %s", e->name, a == 0 ? "static" : "interactive");
-            if (!filter_chain_AppendFilter(chain, e->name, e->cfg, NULL, NULL)) {
+            filter_t *filter = filter_chain_AppendFilter(chain, e->name, e->cfg,
+                               NULL, NULL);
+            if (filter)
+                ThreadAddFilterCallbacks(vout, filter);
+            else
+            {
                 msg_Err(vout, "Failed to add filter '%s'", e->name);
                 config_ChainDestroy(e->cfg);
             }
+
             free(e->name);
             free(e);
         }
@@ -1429,6 +1519,7 @@ static int ThreadStart(vout_thread_t *vout, vout_display_state_t *state)
     video_format_Print(VLC_OBJECT(vout), "original format", &vout->p->original);
     return VLC_SUCCESS;
 error:
+    ThreadDelFilterCallbacks(vout);
     if (vout->p->filter.chain_interactive != NULL)
         filter_chain_Delete(vout->p->filter.chain_interactive);
     if (vout->p->filter.chain_static != NULL)
@@ -1454,6 +1545,7 @@ static void ThreadStop(vout_thread_t *vout, vout_display_state_t *state)
     }
 
     /* Destroy the video filters2 */
+    ThreadDelFilterCallbacks(vout);
     filter_chain_Delete(vout->p->filter.chain_interactive);
     filter_chain_Delete(vout->p->filter.chain_static);
     video_format_Clean(&vout->p->filter.format);
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index 400bcb8b61..cb64544d3d 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -125,6 +125,7 @@ struct vout_thread_sys_t
         struct filter_chain_t *chain_static;
         struct filter_chain_t *chain_interactive;
         bool            has_deint;
+        vlc_array_t     callbacks;
     } filter;
 
     /* */
-- 
2.11.0



More information about the vlc-devel mailing list