[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