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

Thomas Guillem thomas at gllm.fr
Tue Apr 25 13:59:25 CEST 2017



On Tue, Apr 25, 2017, at 15:49, Victorien Le Couviour--Tuffet wrote:
> 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  */

This comment is quite useless.
Everything is in the next line:

> +    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
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list