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

Victorien Le Couviour--Tuffet victorien.lecouviour.tuffet at gmail.com
Tue Apr 25 13:38:10 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.
---
 src/video_output/control.h       |  1 +
 src/video_output/interlacing.c   | 74 +++++-----------------------------------
 src/video_output/video_output.c  | 27 ++++++++++++---
 src/video_output/vout_internal.h |  1 +
 4 files changed, 33 insertions(+), 70 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..9fa6bedbb8 100644
--- a/src/video_output/interlacing.c
+++ b/src/video_output/interlacing.c
@@ -62,77 +62,21 @@ 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;
+    return vout->p->filter.has_deint;
 }
 
-static void DeinterlaceRemove(vout_thread_t *vout)
+static inline 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);
+    vout_control_PushBool(&vout->p->control,
+                          VOUT_CONTROL_CHANGE_INTERLACE, false);
 }
-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 inline void DeinterlaceAdd(vout_thread_t *vout)
+{
+    vout_control_PushBool(&vout->p->control,
+                          VOUT_CONTROL_CHANGE_INTERLACE, true);
 }
 
 static int DeinterlaceCallback(vlc_object_t *object, char const *cmd,
@@ -260,5 +204,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..be29feb6f8 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -212,6 +212,9 @@ static vout_thread_t *VoutCreate(vlc_object_t *object,
     if (vout->p->input)
         spu_Attach(vout->p->spu, vout->p->input, true);
 
+    /* */
+    vout->p->filter.has_deint = false;
+
     return vout;
 }
 
@@ -698,6 +701,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 +711,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 +736,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 +835,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 +1574,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