1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010 Laurent Aimar
6 * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
28 #include <vlc_common.h>
31 #include "vout_private.h"
32 #include "vout_internal.h"
34 /*****************************************************************************
36 *****************************************************************************/
38 * You can use the non vout filter if and only if the video properties stay the
39 * same (width/height/chroma/fps), at least for now.
41 static const char deinterlace_modes[][9]= {
55 static bool DeinterlaceIsModeValid(const char *mode)
57 for (unsigned i = 0; i < ARRAY_SIZE(deinterlace_modes); i++) {
58 if (!strcmp(deinterlace_modes[i], mode))
64 static int DeinterlaceCallback(vlc_object_t *object, char const *cmd,
65 vlc_value_t oldval, vlc_value_t newval, void *data)
67 VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(newval); VLC_UNUSED(data);
68 vout_thread_t *vout = (vout_thread_t *)object;
71 const int deinterlace_state = var_GetInteger(vout, "deinterlace");
72 char *mode = var_GetString(vout, "deinterlace-mode");
73 const bool is_needed = var_GetBool(vout, "deinterlace-needed");
74 if (!mode || !DeinterlaceIsModeValid(mode))
81 char *old = var_CreateGetString(vout, "sout-deinterlace-mode");
82 var_SetString(vout, "sout-deinterlace-mode", mode);
84 msg_Dbg(vout, "deinterlace %d, mode %s, is_needed %d", deinterlace_state, mode, is_needed);
85 vout_ControlChangeInterlacing(vout, deinterlace_state != 0 && (is_needed || deinterlace_state >= 0));
93 void vout_InitInterlacingSupport(vout_thread_t *vout, vout_thread_private_t *sys)
97 msg_Dbg(vout, "Deinterlacing available");
99 sys->interlacing.has_deint = false;
101 /* Create the configuration variables */
103 var_Create(vout, "deinterlace", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
104 int deinterlace_state = var_GetInteger(vout, "deinterlace");
106 var_Change(vout, "deinterlace", VLC_VAR_SETTEXT, _("Deinterlace"));
108 const module_config_t *optd = config_FindConfig("deinterlace");
109 var_Change(vout, "deinterlace", VLC_VAR_CLEARCHOICES);
110 if (likely(optd != NULL))
111 for (unsigned i = 0; i < optd->list_count; i++) {
112 val.i_int = optd->list.i[i];
113 var_Change(vout, "deinterlace", VLC_VAR_ADDCHOICE, val,
114 vlc_gettext(optd->list_text[i]));
116 var_AddCallback(vout, "deinterlace", DeinterlaceCallback, NULL);
118 var_Create(vout, "deinterlace-mode", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
119 char *deinterlace_mode = var_GetNonEmptyString(vout, "deinterlace-mode");
121 var_Change(vout, "deinterlace-mode", VLC_VAR_SETTEXT,
122 _("Deinterlace mode"));
124 const module_config_t *optm = config_FindConfig("deinterlace-mode");
125 var_Change(vout, "deinterlace-mode", VLC_VAR_CLEARCHOICES);
126 if (likely(optm != NULL))
127 for (unsigned i = 0; i < optm->list_count; i++) {
128 if (!DeinterlaceIsModeValid(optm->list.psz[i]))
131 val.psz_string = (char *)optm->list.psz[i];
132 var_Change(vout, "deinterlace-mode", VLC_VAR_ADDCHOICE,
133 val, vlc_gettext(optm->list_text[i]));
135 var_AddCallback(vout, "deinterlace-mode", DeinterlaceCallback, NULL);
137 var_Create(vout, "deinterlace-needed", VLC_VAR_BOOL);
138 var_AddCallback(vout, "deinterlace-needed", DeinterlaceCallback, NULL);
141 val.psz_string = deinterlace_mode ? deinterlace_mode : optm->orig.psz;
142 var_Change(vout, "deinterlace-mode", VLC_VAR_SETVALUE, val);
144 var_SetInteger(vout, "deinterlace", deinterlace_state);
145 free(deinterlace_mode);
147 sys->interlacing.is_interlaced = false;
150 void vout_ReinitInterlacingSupport(vout_thread_t *vout, vout_thread_private_t *sys)
152 sys->interlacing.is_interlaced = false;
153 var_SetBool(vout, "deinterlace-needed", false);
156 void vout_SetInterlacingState(vout_thread_t *vout, vout_thread_private_t *sys, bool is_interlaced)
158 /* Wait 30s before quiting interlacing mode */
159 const int interlacing_change = (!!is_interlaced)
160 - (!!sys->interlacing.is_interlaced);
161 if (interlacing_change == 1 ||
162 (interlacing_change == -1 &&
163 sys->interlacing.date + VLC_TICK_FROM_SEC(30) < vlc_tick_now()))
165 msg_Dbg(vout, "Detected %s video",
166 is_interlaced ? "interlaced" : "progressive");
167 var_SetBool(vout, "deinterlace-needed", is_interlaced);
168 sys->interlacing.is_interlaced = is_interlaced;
171 sys->interlacing.date = vlc_tick_now();