1 /*****************************************************************************
2 * vout_display.c: "vout display" -> "video output" wrapper
3 *****************************************************************************
4 * Copyright (C) 2009 Laurent Aimar
7 * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 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 General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_vout_wrapper.h>
36 #include "vout_internal.h"
39 /* Minimum number of direct pictures the video output will accept without
40 * creating additional pictures in system memory */
41 #ifdef OPTIMIZE_MEMORY
42 # define VOUT_MIN_DIRECT_PICTURES (VOUT_MAX_PICTURES/2)
44 # define VOUT_MIN_DIRECT_PICTURES (3*VOUT_MAX_PICTURES/4)
47 /*****************************************************************************
49 *****************************************************************************/
51 static int Forward(vlc_object_t *, char const *,
52 vlc_value_t, vlc_value_t, void *);
55 /*****************************************************************************
57 *****************************************************************************/
58 int vout_OpenWrapper(vout_thread_t *vout,
59 const char *name, const vout_display_state_t *state)
61 vout_thread_sys_t *sys = vout->p;
62 msg_Dbg(vout, "Opening vout display wrapper");
65 sys->display.title = var_CreateGetNonEmptyString(vout, "video-title");
68 video_format_t source = vout->p->original;
69 source.i_visible_width = source.i_width;
70 source.i_visible_height = source.i_height;
71 source.i_x_offset = 0;
72 source.i_y_offset = 0;
74 const mtime_t double_click_timeout = 300000;
75 const mtime_t hide_timeout = var_CreateGetInteger(vout, "mouse-hide-timeout") * 1000;
77 sys->display.vd = vout_NewDisplay(vout, &source, state, name ? name : "$vout",
78 double_click_timeout, hide_timeout);
79 /* If we need to video filter and it fails, then try a splitter
80 * XXX it is a hack for now FIXME */
81 if (name && !sys->display.vd)
82 sys->display.vd = vout_NewSplitter(vout, &source, state, "$vout", name,
83 double_click_timeout, hide_timeout);
84 if (!sys->display.vd) {
85 free(sys->display.title);
91 var_Create(vout, "direct3d-desktop", VLC_VAR_BOOL|VLC_VAR_DOINHERIT);
92 var_AddCallback(vout, "direct3d-desktop", Forward, NULL);
93 var_Create(vout, "video-wallpaper", VLC_VAR_BOOL|VLC_VAR_DOINHERIT);
94 var_AddCallback(vout, "video-wallpaper", Forward, NULL);
98 sys->decoder_pool = NULL;
103 /*****************************************************************************
105 *****************************************************************************/
106 void vout_CloseWrapper(vout_thread_t *vout, vout_display_state_t *state)
108 vout_thread_sys_t *sys = vout->p;
111 var_DelCallback(vout, "direct3d-desktop", Forward, NULL);
112 var_DelCallback(vout, "video-wallpaper", Forward, NULL);
114 sys->decoder_pool = NULL; /* FIXME remove */
116 vout_DeleteDisplay(sys->display.vd, state);
117 free(sys->display.title);
120 /*****************************************************************************
122 *****************************************************************************/
123 int vout_InitWrapper(vout_thread_t *vout)
125 vout_thread_sys_t *sys = vout->p;
126 vout_display_t *vd = sys->display.vd;
127 video_format_t source = vd->source;
129 /* XXX For non dr case, the current vout implementation force us to
130 * create at most 1 direct picture (otherwise the buffers will be kept
131 * referenced even through the Init/End.
133 sys->display.use_dr = !vout_IsDisplayFiltered(vd);
134 const bool allow_dr = !vd->info.has_pictures_invalid && sys->display.use_dr;
136 picture_pool_t *display_pool = vout_display_Pool(vd, allow_dr ? VOUT_MAX_PICTURES : 3);
137 if (allow_dr && picture_pool_GetSize(display_pool) >= VOUT_MIN_DIRECT_PICTURES) {
138 sys->decoder_pool = display_pool;
139 sys->display_pool = display_pool;
140 sys->is_decoder_pool_slow = vd->info.is_slow;
141 } else if (!sys->decoder_pool) {
142 sys->decoder_pool = picture_pool_NewFromFormat(&source, VOUT_MAX_PICTURES);
143 if (sys->display.use_dr)
144 sys->display_pool = display_pool;
146 sys->display_pool = picture_pool_Reserve(sys->decoder_pool, 1);;
147 sys->is_decoder_pool_slow = false;
149 sys->private_pool = picture_pool_Reserve(sys->decoder_pool, 3); /* XXX 2 for filter, 1 for SPU */
150 sys->display.filtered = NULL;
154 /*****************************************************************************
156 *****************************************************************************/
157 void vout_EndWrapper(vout_thread_t *vout)
159 vout_thread_sys_t *sys = vout->p;
161 assert(!sys->display.filtered);
162 if (sys->private_pool)
163 picture_pool_Delete(sys->private_pool);
165 if (sys->decoder_pool != sys->display_pool) {
166 if (!sys->display.use_dr)
167 picture_pool_Delete(sys->display_pool);
168 picture_pool_Delete(sys->decoder_pool);
172 /*****************************************************************************
174 *****************************************************************************/
175 void vout_ManageWrapper(vout_thread_t *vout)
177 vout_thread_sys_t *sys = vout->p;
178 vout_display_t *vd = sys->display.vd;
180 bool reset_display_pool = sys->display.use_dr && vout_AreDisplayPicturesInvalid(vd);
181 vout_ManageDisplay(vd, !sys->display.use_dr || reset_display_pool);
183 if (reset_display_pool)
184 sys->display_pool = vout_display_Pool(vd, 3);
187 /*****************************************************************************
189 *****************************************************************************/
190 void vout_RenderWrapper(vout_thread_t *vout, picture_t *picture)
192 vout_thread_sys_t *sys = vout->p;
193 vout_display_t *vd = sys->display.vd;
195 assert(vout_IsDisplayFiltered(vd) == !sys->display.use_dr);
197 if (sys->display.use_dr) {
198 vout_display_Prepare(vd, picture);
200 sys->display.filtered = vout_FilterDisplay(vd, picture);
201 if (sys->display.filtered)
202 vout_display_Prepare(vd, sys->display.filtered);
206 /*****************************************************************************
208 *****************************************************************************/
209 void vout_DisplayWrapper(vout_thread_t *vout, picture_t *picture)
211 vout_thread_sys_t *sys = vout->p;
212 vout_display_t *vd = sys->display.vd;
214 vout_display_Display(vd, sys->display.filtered ? sys->display.filtered : picture);
215 sys->display.filtered = NULL;
219 static int Forward(vlc_object_t *object, char const *var,
220 vlc_value_t oldval, vlc_value_t newval, void *data)
222 vout_thread_t *vout = (vout_thread_t*)object;
226 return var_Set(vout->p->display.vd, var, newval);