[vlc-devel] [PATCH 2/2] vout: update interlacing handling

Victorien Le Couviour--Tuffet victorien.lecouviour.tuffet at gmail.com
Tue Apr 25 15:49:19 CEST 2017


Remove deinterlace from 'video-filter' vlc string variable, now handling it
with a boolean.
This fixes the bug that happened when deinterlacing a video and applying a new
filter: the deinterlace filter was not reapplied when rebuilding the filter
chain.
We couldn't retrieve this var from the GUI as the presence of this
filter can change at any time, considering that a video can be partially
interlaced many times.
It's also cleaner to handle the presence of the deinterlace filter without
using a VLC variable as we only need to know if it's there in the video output
module.
---
fully inline one liner functions
move deinterlace filter presence boolean init to interlacing init

 src/video_output/control.h       |  1 +
 src/video_output/interlacing.c   | 88 ++++------------------------------------
 src/video_output/video_output.c  | 24 +++++++++--
 src/video_output/vout_internal.h |  1 +
 4 files changed, 31 insertions(+), 83 deletions(-)

diff --git a/src/video_output/control.h b/src/video_output/control.h
index 14eec3468d..f49208ab6a 100644
--- a/src/video_output/control.h
+++ b/src/video_output/control.h
@@ -42,6 +42,7 @@ enum {
     VOUT_CONTROL_FLUSH_SUBPICTURE,      /* integer */
     VOUT_CONTROL_OSD_TITLE,             /* string */
     VOUT_CONTROL_CHANGE_FILTERS,        /* string */
+    VOUT_CONTROL_CHANGE_INTERLACE,      /* boolean */
     VOUT_CONTROL_CHANGE_SUB_SOURCES,    /* string */
     VOUT_CONTROL_CHANGE_SUB_FILTERS,    /* string */
     VOUT_CONTROL_CHANGE_SUB_MARGIN,     /* integer */
diff --git a/src/video_output/interlacing.c b/src/video_output/interlacing.c
index 308493e6ca..ab206097f6 100644
--- a/src/video_output/interlacing.c
+++ b/src/video_output/interlacing.c
@@ -62,79 +62,6 @@ static bool DeinterlaceIsModeValid(const char *mode)
     return false;
 }
 
-static char *FilterFind(char *filter_base, const char *module_name)
-{
-    const size_t module_length = strlen(module_name);
-    const char *filter = filter_base;
-
-    if (!filter || module_length <= 0)
-        return NULL;
-
-    for (;;) {
-        char *start = strstr(filter, module_name);
-        if (!start)
-            return NULL;
-        if (start[module_length] == '\0' || start[module_length] == ':')
-            return start;
-        filter = &start[module_length];
-    }
-}
-
-static bool DeinterlaceIsPresent(vout_thread_t *vout)
-{
-    char *filter = var_GetNonEmptyString(vout, "video-filter");
-
-    bool is_found = FilterFind(filter, "deinterlace") != NULL;
-
-    free(filter);
-
-    return is_found;
-}
-
-static void DeinterlaceRemove(vout_thread_t *vout)
-{
-    char *filter = var_GetNonEmptyString(vout, "video-filter");
-
-    char *start = FilterFind(filter, "deinterlace");
-    if (!start) {
-        free(filter);
-        return;
-    }
-
-    /* */
-    strcpy(&start[0], &start[strlen("deinterlace")]);
-    if (*start == ':')
-        memmove(start, start + 1, strlen(start) /* + 1 - 1 */);
-
-    var_SetString(vout, "video-filter", filter);
-    free(filter);
-}
-static void DeinterlaceAdd(vout_thread_t *vout)
-{
-    char *filter = var_GetNonEmptyString(vout, "video-filter");
-
-    if (FilterFind(filter, "deinterlace")) {
-        free(filter);
-        return;
-    }
-
-    /* */
-    if (filter) {
-        char *tmp = filter;
-        if (asprintf(&filter, "%s:%s", tmp, "deinterlace") < 0)
-            filter = tmp;
-        else
-            free(tmp);
-    } else {
-        filter = strdup("deinterlace");
-    }
-
-    if (filter) {
-        var_SetString(vout, "video-filter", filter);
-        free(filter);
-    }
-}
-
 static int DeinterlaceCallback(vlc_object_t *object, char const *cmd,
                                vlc_value_t oldval, vlc_value_t newval, void *data)
 {
@@ -154,9 +81,11 @@ static int DeinterlaceCallback(vlc_object_t *object, char const *cmd,
 
     msg_Dbg(vout, "deinterlace %d, mode %s, is_needed %d", deinterlace_state, mode, is_needed);
     if (deinterlace_state == 0 || (deinterlace_state < 0 && !is_needed))
-        DeinterlaceRemove(vout);
-    else if (!DeinterlaceIsPresent(vout))
-        DeinterlaceAdd(vout);
+        vout_control_PushBool(&vout->p->control,
+                              VOUT_CONTROL_CHANGE_INTERLACE, false);
+    else if (!vout->p->filter.has_deint)
+        vout_control_PushBool(&vout->p->control,
+                              VOUT_CONTROL_CHANGE_INTERLACE, true);
     else if (old && strcmp(old, mode))
         var_TriggerCallback(vout, "video-filter");
 
@@ -172,6 +101,9 @@ void vout_InitInterlacingSupport(vout_thread_t *vout, bool is_interlaced)
 
     msg_Dbg(vout, "Deinterlacing available");
 
+    /* Init the deinterlace filter presence boolean  */
+    vout->p->filter.has_deint = false;
+
     /* Create the configuration variables */
     /* */
     var_Create(vout, "deinterlace", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
@@ -215,7 +147,7 @@ void vout_InitInterlacingSupport(vout_thread_t *vout, bool is_interlaced)
 
     /* Override the initial value from filters if present */
     char *filter_mode = NULL;
-    if (DeinterlaceIsPresent(vout))
+    if (vout->p->filter.has_deint)
         filter_mode = var_CreateGetNonEmptyString(vout, "sout-deinterlace-mode");
     if (filter_mode) {
         deinterlace_state = 1;
@@ -260,5 +192,3 @@ void vout_SetInterlacingState(vout_thread_t *vout, bool is_interlaced)
     if (is_interlaced)
         vout->p->interlacing.date = mdate();
 }
-
-
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 6ea72ba468..ede3c1625d 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -698,6 +698,7 @@ typedef struct {
 static void ThreadChangeFilters(vout_thread_t *vout,
                                 const video_format_t *source,
                                 const char *filters,
+                                int deinterlace,
                                 bool is_locked)
 {
     ThreadFilterFlush(vout, is_locked);
@@ -707,6 +708,18 @@ static void ThreadChangeFilters(vout_thread_t *vout,
 
     vlc_array_init(&array_static);
     vlc_array_init(&array_interactive);
+
+    if ((vout->p->filter.has_deint =
+         deinterlace == 1 || (deinterlace == -1 && vout->p->filter.has_deint)))
+    {
+        vout_filter_t *e;
+
+        if (!(e = malloc(sizeof(*e))))
+            return ;
+        config_ChainCreate(&e->name, &e->cfg, "deinterlace");
+        vlc_array_append(&array_static, e);
+    }
+
     char *current = filters ? strdup(filters) : NULL;
     while (current) {
         config_chain_t *cfg;
@@ -720,8 +733,7 @@ static void ThreadChangeFilters(vout_thread_t *vout,
                 return ;
             e->name = name;
             e->cfg  = cfg;
-            if (!strcmp(e->name, "deinterlace") ||
-                !strcmp(e->name, "postproc")) {
+            if (!strcmp(e->name, "postproc")) {
                 vlc_array_append(&array_static, e);
             } else {
                 vlc_array_append(&array_interactive, e);
@@ -820,7 +832,7 @@ static int ThreadDisplayPreparePicture(vout_thread_t *vout, bool reuse, bool fra
                     }
                 }
                 if (!VideoFormatIsCropArEqual(&decoded->format, &vout->p->filter.format))
-                    ThreadChangeFilters(vout, &decoded->format, vout->p->filter.configuration, true);
+                    ThreadChangeFilters(vout, &decoded->format, vout->p->filter.configuration, -1, true);
             }
         }
 
@@ -1559,7 +1571,11 @@ static int ThreadControl(vout_thread_t *vout, vout_control_cmd_t cmd)
         ThreadDisplayOsdTitle(vout, cmd.u.string);
         break;
     case VOUT_CONTROL_CHANGE_FILTERS:
-        ThreadChangeFilters(vout, NULL, cmd.u.string, false);
+        ThreadChangeFilters(vout, NULL, cmd.u.string, -1, false);
+        break;
+    case VOUT_CONTROL_CHANGE_INTERLACE:
+        ThreadChangeFilters(vout, NULL, vout->p->filter.configuration,
+                            cmd.u.boolean ? 1 : 0, false);
         break;
     case VOUT_CONTROL_CHANGE_SUB_SOURCES:
         ThreadChangeSubSources(vout, cmd.u.string);
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index c7d33bafb6..400bcb8b61 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -124,6 +124,7 @@ struct vout_thread_sys_t
         video_format_t  format;
         struct filter_chain_t *chain_static;
         struct filter_chain_t *chain_interactive;
+        bool            has_deint;
     } filter;
 
     /* */
-- 
2.12.0



More information about the vlc-devel mailing list