mp4: Fix make distcheck
[vlc.git] / src / video_output / interlacing.c
blobf07ef8ef5a016521bd4732f90185027cb5dda9ed
1 /*****************************************************************************
2 * interlacing.c
3 *****************************************************************************
4 * Copyright (C) 2010 Laurent Aimar
5 * $Id$
7 * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27 #include <assert.h>
29 #include <vlc_common.h>
30 #include <vlc_vout.h>
32 #include "interlacing.h"
33 #include "vout_internal.h"
35 /*****************************************************************************
36 * Deinterlacing
37 *****************************************************************************/
38 /* XXX
39 * You can use the non vout filter if and only if the video properties stay the
40 * same (width/height/chroma/fps), at least for now.
42 static const char deinterlace_modes[][9]= {
43 "auto",
44 "discard",
45 "blend",
46 "mean",
47 "bob",
48 "linear",
49 "x",
50 "yadif",
51 "yadif2x",
52 "phosphor",
53 "ivtc",
56 static bool DeinterlaceIsModeValid(const char *mode)
58 for (unsigned i = 0; i < ARRAY_SIZE(deinterlace_modes); i++) {
59 if (!strcmp(deinterlace_modes[i], mode))
60 return true;
62 return false;
65 static int DeinterlaceCallback(vlc_object_t *object, char const *cmd,
66 vlc_value_t oldval, vlc_value_t newval, void *data)
68 VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(newval); VLC_UNUSED(data);
69 vout_thread_t *vout = (vout_thread_t *)object;
71 /* */
72 const int deinterlace_state = var_GetInteger(vout, "deinterlace");
73 char *mode = var_GetString(vout, "deinterlace-mode");
74 const bool is_needed = var_GetBool(vout, "deinterlace-needed");
75 if (!mode || !DeinterlaceIsModeValid(mode))
77 free(mode);
78 return VLC_EGENERIC;
81 /* */
82 char *old = var_CreateGetString(vout, "sout-deinterlace-mode");
83 var_SetString(vout, "sout-deinterlace-mode", mode);
85 msg_Dbg(vout, "deinterlace %d, mode %s, is_needed %d", deinterlace_state, mode, is_needed);
86 if (deinterlace_state == 0 || (deinterlace_state < 0 && !is_needed))
87 vout_control_PushBool(&vout->p->control,
88 VOUT_CONTROL_CHANGE_INTERLACE, false);
89 else
90 vout_control_PushBool(&vout->p->control,
91 VOUT_CONTROL_CHANGE_INTERLACE, true);
93 /* */
94 free(old);
95 free(mode);
96 return VLC_SUCCESS;
99 void vout_InitInterlacingSupport(vout_thread_t *vout, bool is_interlaced)
101 vlc_value_t val, text;
103 msg_Dbg(vout, "Deinterlacing available");
105 vout->p->filter.has_deint = false;
107 /* Create the configuration variables */
108 /* */
109 var_Create(vout, "deinterlace", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
110 int deinterlace_state = var_GetInteger(vout, "deinterlace");
112 text.psz_string = _("Deinterlace");
113 var_Change(vout, "deinterlace", VLC_VAR_SETTEXT, &text, NULL);
115 const module_config_t *optd = config_FindConfig("deinterlace");
116 var_Change(vout, "deinterlace", VLC_VAR_CLEARCHOICES, NULL, NULL);
117 if (likely(optd != NULL))
118 for (unsigned i = 0; i < optd->list_count; i++) {
119 val.i_int = optd->list.i[i];
120 text.psz_string = vlc_gettext(optd->list_text[i]);
121 var_Change(vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text);
123 var_AddCallback(vout, "deinterlace", DeinterlaceCallback, NULL);
124 /* */
125 var_Create(vout, "deinterlace-mode", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
126 char *deinterlace_mode = var_GetNonEmptyString(vout, "deinterlace-mode");
128 text.psz_string = _("Deinterlace mode");
129 var_Change(vout, "deinterlace-mode", VLC_VAR_SETTEXT, &text, NULL);
131 const module_config_t *optm = config_FindConfig("deinterlace-mode");
132 var_Change(vout, "deinterlace-mode", VLC_VAR_CLEARCHOICES, NULL, NULL);
133 if (likely(optm != NULL))
134 for (unsigned i = 0; i < optm->list_count; i++) {
135 if (!DeinterlaceIsModeValid(optm->list.psz[i]))
136 continue;
138 val.psz_string = (char *)optm->list.psz[i];
139 text.psz_string = vlc_gettext(optm->list_text[i]);
140 var_Change(vout, "deinterlace-mode", VLC_VAR_ADDCHOICE,
141 &val, &text);
143 var_AddCallback(vout, "deinterlace-mode", DeinterlaceCallback, NULL);
144 /* */
145 var_Create(vout, "deinterlace-needed", VLC_VAR_BOOL);
146 var_AddCallback(vout, "deinterlace-needed", DeinterlaceCallback, NULL);
148 /* Override the initial value from filters if present */
149 char *filter_mode = NULL;
150 if (vout->p->filter.has_deint)
151 filter_mode = var_CreateGetNonEmptyString(vout, "sout-deinterlace-mode");
152 if (filter_mode) {
153 deinterlace_state = 1;
154 free(deinterlace_mode);
155 deinterlace_mode = filter_mode;
158 /* */
159 val.psz_string = deinterlace_mode ? deinterlace_mode : optm->orig.psz;
160 var_Change(vout, "deinterlace-mode", VLC_VAR_SETVALUE, &val, NULL);
161 val.b_bool = is_interlaced;
162 var_Change(vout, "deinterlace-needed", VLC_VAR_SETVALUE, &val, NULL);
164 var_SetInteger(vout, "deinterlace", deinterlace_state);
165 free(deinterlace_mode);
167 vout->p->interlacing.is_interlaced = is_interlaced;
168 if (is_interlaced)
169 vout->p->interlacing.date = mdate();
172 void vout_ReinitInterlacingSupport(vout_thread_t *vout)
174 vout->p->interlacing.is_interlaced = false;
175 var_SetBool(vout, "deinterlace-needed", false);
178 void vout_SetInterlacingState(vout_thread_t *vout, bool is_interlaced)
180 /* Wait 30s before quiting interlacing mode */
181 const int interlacing_change = (!!is_interlaced)
182 - (!!vout->p->interlacing.is_interlaced);
183 if (interlacing_change == 1 ||
184 (interlacing_change == -1 &&
185 vout->p->interlacing.date + 30000000 < mdate()))
187 msg_Dbg(vout, "Detected %s video",
188 is_interlaced ? "interlaced" : "progressive");
189 var_SetBool(vout, "deinterlace-needed", is_interlaced);
190 vout->p->interlacing.is_interlaced = is_interlaced;
192 if (is_interlaced)
193 vout->p->interlacing.date = mdate();