[vlc-devel] [PATCH 2/2] vout: update interlacing handling
Victorien Le Couviour--Tuffet
victorien.lecouviour.tuffet at gmail.com
Tue Apr 25 20:35:04 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.
---
skipping filter if its malloc fails
src/video_output/control.h | 1 +
src/video_output/interlacing.c | 87 ++++------------------------------------
src/video_output/video_output.c | 25 ++++++++++--
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..3435a1ea38 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,8 @@ void vout_InitInterlacingSupport(vout_thread_t *vout, bool is_interlaced)
msg_Dbg(vout, "Deinterlacing available");
+ vout->p->filter.has_deint = false;
+
/* Create the configuration variables */
/* */
var_Create(vout, "deinterlace", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
@@ -215,7 +146,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 +191,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 e5b92a0711..853cfe07c1 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,19 @@ 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 = malloc(sizeof(*e));
+
+ if (e)
+ {
+ 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 +734,7 @@ static void ThreadChangeFilters(vout_thread_t *vout,
goto filter_load_failure;
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);
@@ -821,7 +834,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);
}
}
@@ -1560,7 +1573,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