]> git.sesse.net Git - vlc/blob - src/video_output/vout_wrapper.c
Reused vout window in vout_Request().
[vlc] / src / video_output / vout_wrapper.c
1 /*****************************************************************************
2  * vout_display.c: "vout display" -> "video output" wrapper
3  *****************************************************************************
4  * Copyright (C) 2009 Laurent Aimar
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_vout_wrapper.h>
34 #include <vlc_vout.h>
35 #include <assert.h>
36 #include "vout_internal.h"
37 #include "display.h"
38
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)
43 #else
44 #   define VOUT_MIN_DIRECT_PICTURES        (3*VOUT_MAX_PICTURES/4)
45 #endif
46
47 /*****************************************************************************
48  * Local prototypes
49  *****************************************************************************/
50 #ifdef WIN32
51 static int  Forward(vlc_object_t *, char const *,
52                     vlc_value_t, vlc_value_t, void *);
53 #endif
54
55 /*****************************************************************************
56  *
57  *****************************************************************************/
58 int vout_OpenWrapper(vout_thread_t *vout,
59                      const char *name, const vout_display_state_t *state)
60 {
61     vout_thread_sys_t *sys = vout->p;
62     msg_Dbg(vout, "Opening vout display wrapper");
63
64     /* */
65     sys->display.title = var_CreateGetNonEmptyString(vout, "video-title");
66
67     /* */
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;
73
74     const mtime_t double_click_timeout = 300000;
75     const mtime_t hide_timeout = var_CreateGetInteger(vout, "mouse-hide-timeout") * 1000;
76
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);
86         return VLC_EGENERIC;
87     }
88
89     /* */
90 #ifdef WIN32
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);
95 #endif
96
97     /* */
98     sys->decoder_pool = NULL;
99
100     return VLC_SUCCESS;
101 }
102
103 /*****************************************************************************
104  *
105  *****************************************************************************/
106 void vout_CloseWrapper(vout_thread_t *vout, vout_display_state_t *state)
107 {
108     vout_thread_sys_t *sys = vout->p;
109
110 #ifdef WIN32
111     var_DelCallback(vout, "direct3d-desktop", Forward, NULL);
112     var_DelCallback(vout, "video-wallpaper", Forward, NULL);
113 #endif
114     sys->decoder_pool = NULL; /* FIXME remove */
115
116     vout_DeleteDisplay(sys->display.vd, state);
117     free(sys->display.title);
118 }
119
120 /*****************************************************************************
121  *
122  *****************************************************************************/
123 int vout_InitWrapper(vout_thread_t *vout)
124 {
125     vout_thread_sys_t *sys = vout->p;
126     vout_display_t *vd = sys->display.vd;
127     video_format_t source = vd->source;
128
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.
132      */
133     sys->display.use_dr = !vout_IsDisplayFiltered(vd);
134     const bool allow_dr = !vd->info.has_pictures_invalid && sys->display.use_dr;
135
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;
145         else
146             sys->display_pool = picture_pool_Reserve(sys->decoder_pool, 1);;
147         sys->is_decoder_pool_slow = false;
148     }
149     sys->private_pool = picture_pool_Reserve(sys->decoder_pool, 3); /* XXX 2 for filter, 1 for SPU */
150     sys->display.filtered = NULL;
151     return VLC_SUCCESS;
152 }
153
154 /*****************************************************************************
155  *
156  *****************************************************************************/
157 void vout_EndWrapper(vout_thread_t *vout)
158 {
159     vout_thread_sys_t *sys = vout->p;
160
161     assert(!sys->display.filtered);
162     if (sys->private_pool)
163         picture_pool_Delete(sys->private_pool);
164
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);
169     }
170 }
171
172 /*****************************************************************************
173  *
174  *****************************************************************************/
175 void vout_ManageWrapper(vout_thread_t *vout)
176 {
177     vout_thread_sys_t *sys = vout->p;
178     vout_display_t *vd = sys->display.vd;
179
180     bool reset_display_pool = sys->display.use_dr && vout_AreDisplayPicturesInvalid(vd);
181     vout_ManageDisplay(vd, !sys->display.use_dr || reset_display_pool);
182
183     if (reset_display_pool)
184         sys->display_pool = vout_display_Pool(vd, 3);
185 }
186
187 /*****************************************************************************
188  * Render
189  *****************************************************************************/
190 void vout_RenderWrapper(vout_thread_t *vout, picture_t *picture)
191 {
192     vout_thread_sys_t *sys = vout->p;
193     vout_display_t *vd = sys->display.vd;
194
195     assert(vout_IsDisplayFiltered(vd) == !sys->display.use_dr);
196
197     if (sys->display.use_dr) {
198         vout_display_Prepare(vd, picture);
199     } else {
200         sys->display.filtered = vout_FilterDisplay(vd, picture);
201         if (sys->display.filtered)
202             vout_display_Prepare(vd, sys->display.filtered);
203     }
204 }
205
206 /*****************************************************************************
207  *
208  *****************************************************************************/
209 void vout_DisplayWrapper(vout_thread_t *vout, picture_t *picture)
210 {
211     vout_thread_sys_t *sys = vout->p;
212     vout_display_t *vd = sys->display.vd;
213
214      vout_display_Display(vd, sys->display.filtered ? sys->display.filtered : picture);
215      sys->display.filtered = NULL;
216 }
217
218 #ifdef WIN32
219 static int Forward(vlc_object_t *object, char const *var,
220                    vlc_value_t oldval, vlc_value_t newval, void *data)
221 {
222     vout_thread_t *vout = (vout_thread_t*)object;
223
224     VLC_UNUSED(oldval);
225     VLC_UNUSED(data);
226     return var_Set(vout->p->display.vd, var, newval);
227 }
228 #endif
229