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 /*****************************************************************************
41 *****************************************************************************/
43 static int Forward(vlc_object_t
*, char const *,
44 vlc_value_t
, vlc_value_t
, void *);
47 /*****************************************************************************
49 *****************************************************************************/
50 int vout_OpenWrapper(vout_thread_t
*vout
,
51 const char *name
, const vout_display_state_t
*state
)
53 vout_thread_sys_t
*sys
= vout
->p
;
54 msg_Dbg(vout
, "Opening vout display wrapper");
57 sys
->display
.title
= var_CreateGetNonEmptyString(vout
, "video-title");
60 video_format_t source
= vout
->p
->original
;
61 source
.i_visible_width
= source
.i_width
;
62 source
.i_visible_height
= source
.i_height
;
63 source
.i_x_offset
= 0;
64 source
.i_y_offset
= 0;
66 const mtime_t double_click_timeout
= 300000;
67 const mtime_t hide_timeout
= var_CreateGetInteger(vout
, "mouse-hide-timeout") * 1000;
69 sys
->display
.vd
= vout_NewDisplay(vout
, &source
, state
, name
? name
: "$vout",
70 double_click_timeout
, hide_timeout
);
71 /* If we need to video filter and it fails, then try a splitter
72 * XXX it is a hack for now FIXME */
73 if (name
&& !sys
->display
.vd
)
74 sys
->display
.vd
= vout_NewSplitter(vout
, &source
, state
, "$vout", name
,
75 double_click_timeout
, hide_timeout
);
76 if (!sys
->display
.vd
) {
77 free(sys
->display
.title
);
83 var_Create(vout
, "direct3d-desktop", VLC_VAR_BOOL
|VLC_VAR_DOINHERIT
);
84 var_AddCallback(vout
, "direct3d-desktop", Forward
, NULL
);
85 var_Create(vout
, "video-wallpaper", VLC_VAR_BOOL
|VLC_VAR_DOINHERIT
);
86 var_AddCallback(vout
, "video-wallpaper", Forward
, NULL
);
90 sys
->decoder_pool
= NULL
;
95 /*****************************************************************************
97 *****************************************************************************/
98 void vout_CloseWrapper(vout_thread_t
*vout
, vout_display_state_t
*state
)
100 vout_thread_sys_t
*sys
= vout
->p
;
103 var_DelCallback(vout
, "direct3d-desktop", Forward
, NULL
);
104 var_DelCallback(vout
, "video-wallpaper", Forward
, NULL
);
106 sys
->decoder_pool
= NULL
; /* FIXME remove */
108 vout_DeleteDisplay(sys
->display
.vd
, state
);
109 free(sys
->display
.title
);
112 /*****************************************************************************
114 *****************************************************************************/
115 int vout_InitWrapper(vout_thread_t
*vout
)
117 vout_thread_sys_t
*sys
= vout
->p
;
118 vout_display_t
*vd
= sys
->display
.vd
;
119 video_format_t source
= vd
->source
;
121 sys
->display
.use_dr
= !vout_IsDisplayFiltered(vd
);
122 const bool allow_dr
= !vd
->info
.has_pictures_invalid
&& sys
->display
.use_dr
;
123 const unsigned private_picture
= 3; /* XXX 2 for filter, 1 for SPU */
124 const unsigned display_picture
= 1; /* Minimum number of display picture */
125 const unsigned decoder_picture
= 1 + sys
->dpb_size
;
126 const unsigned kept_picture
= 1; /* last displayed picture */
127 const unsigned reserved_picture
= display_picture
+
130 picture_pool_t
*display_pool
=
131 vout_display_Pool(vd
, allow_dr
? __MAX(VOUT_MAX_PICTURES
,
132 reserved_picture
+ decoder_picture
) : 3);
134 picture_pool_GetSize(display_pool
) >= reserved_picture
+ decoder_picture
) {
135 sys
->dpb_size
= picture_pool_GetSize(display_pool
) - reserved_picture
;
136 sys
->decoder_pool
= display_pool
;
137 sys
->display_pool
= display_pool
;
138 sys
->is_decoder_pool_slow
= vd
->info
.is_slow
;
139 } else if (!sys
->decoder_pool
) {
141 picture_pool_NewFromFormat(&source
,
142 __MAX(VOUT_MAX_PICTURES
,
143 reserved_picture
+ decoder_picture
));
145 msg_Warn(vout
, "Not enough direct buffers, using system memory");
148 sys
->dpb_size
= picture_pool_GetSize(sys
->decoder_pool
) - reserved_picture
;
150 if (sys
->display
.use_dr
)
151 sys
->display_pool
= display_pool
;
153 sys
->display_pool
= picture_pool_Reserve(sys
->decoder_pool
, display_picture
);
154 sys
->is_decoder_pool_slow
= false;
156 sys
->private_pool
= picture_pool_Reserve(sys
->decoder_pool
, private_picture
);
157 sys
->display
.filtered
= NULL
;
161 /*****************************************************************************
163 *****************************************************************************/
164 void vout_EndWrapper(vout_thread_t
*vout
)
166 vout_thread_sys_t
*sys
= vout
->p
;
168 assert(!sys
->display
.filtered
);
169 if (sys
->private_pool
)
170 picture_pool_Delete(sys
->private_pool
);
172 if (sys
->decoder_pool
!= sys
->display_pool
) {
173 if (!sys
->display
.use_dr
)
174 picture_pool_Delete(sys
->display_pool
);
175 picture_pool_Delete(sys
->decoder_pool
);
179 /*****************************************************************************
181 *****************************************************************************/
182 void vout_ManageWrapper(vout_thread_t
*vout
)
184 vout_thread_sys_t
*sys
= vout
->p
;
185 vout_display_t
*vd
= sys
->display
.vd
;
187 bool reset_display_pool
= sys
->display
.use_dr
&& vout_AreDisplayPicturesInvalid(vd
);
188 vout_ManageDisplay(vd
, !sys
->display
.use_dr
|| reset_display_pool
);
190 if (reset_display_pool
)
191 sys
->display_pool
= vout_display_Pool(vd
, 3);
194 /*****************************************************************************
196 *****************************************************************************/
197 void vout_RenderWrapper(vout_thread_t
*vout
, picture_t
*picture
)
199 vout_thread_sys_t
*sys
= vout
->p
;
200 vout_display_t
*vd
= sys
->display
.vd
;
202 assert(vout_IsDisplayFiltered(vd
) == !sys
->display
.use_dr
);
204 if (sys
->display
.use_dr
) {
205 vout_display_Prepare(vd
, picture
);
207 sys
->display
.filtered
= vout_FilterDisplay(vd
, picture
);
208 if (sys
->display
.filtered
)
209 vout_display_Prepare(vd
, sys
->display
.filtered
);
213 /*****************************************************************************
215 *****************************************************************************/
216 void vout_DisplayWrapper(vout_thread_t
*vout
, picture_t
*picture
)
218 vout_thread_sys_t
*sys
= vout
->p
;
219 vout_display_t
*vd
= sys
->display
.vd
;
221 vout_display_Display(vd
, sys
->display
.filtered
? sys
->display
.filtered
: picture
);
222 sys
->display
.filtered
= NULL
;
226 static int Forward(vlc_object_t
*object
, char const *var
,
227 vlc_value_t oldval
, vlc_value_t newval
, void *data
)
229 vout_thread_t
*vout
= (vout_thread_t
*)object
;
233 return var_Set(vout
->p
->display
.vd
, var
, newval
);