access: srt: add support stream encryption
[vlc.git] / modules / video_output / win32 / wingdi.c
blobc0b12b333a55bc075a69e8a4c41f57b256d6cb92
1 /*****************************************************************************
2 * wingdi.c : Win32 / WinCE GDI video output plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2002-2009 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Gildas Bazin <gbazin@videolan.org>
8 * Samuel Hocevar <sam@zoy.org>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 #include <assert.h>
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_vout_display.h>
38 #include <windows.h>
40 #include "common.h"
42 /*****************************************************************************
43 * Module descriptor
44 *****************************************************************************/
45 static int Open (vlc_object_t *);
46 static void Close(vlc_object_t *);
48 vlc_module_begin ()
49 set_category(CAT_VIDEO)
50 set_subcategory(SUBCAT_VIDEO_VOUT)
51 set_shortname("GDI")
52 set_description(N_("Windows GDI video output"))
53 set_capability("vout display", 110)
54 set_callbacks(Open, Close)
55 vlc_module_end ()
58 /*****************************************************************************
59 * Local prototypes
60 *****************************************************************************/
61 struct vout_display_sys_t
63 vout_display_sys_win32_t sys;
65 int i_depth;
67 /* Our offscreen bitmap and its framebuffer */
68 HDC off_dc;
69 HBITMAP off_bitmap;
71 struct
73 BITMAPINFO bitmapinfo;
74 RGBQUAD red;
75 RGBQUAD green;
76 RGBQUAD blue;
80 static picture_pool_t *Pool (vout_display_t *, unsigned);
81 static void Display(vout_display_t *, picture_t *, subpicture_t *subpicture);
82 static int Control(vout_display_t *, int, va_list);
83 static void Manage (vout_display_t *);
85 static int Init(vout_display_t *, video_format_t *, int, int);
86 static void Clean(vout_display_t *);
88 /* */
89 static int Open(vlc_object_t *object)
91 vout_display_t *vd = (vout_display_t *)object;
92 vout_display_sys_t *sys;
94 if ( !vd->obj.force && vd->source.projection_mode != PROJECTION_MODE_RECTANGULAR)
95 return VLC_EGENERIC; /* let a module who can handle it do it */
97 vd->sys = sys = calloc(1, sizeof(*sys));
98 if (!sys)
99 return VLC_ENOMEM;
101 if (CommonInit(vd))
102 goto error;
104 /* */
105 video_format_t fmt = vd->fmt;
106 if (Init(vd, &fmt, fmt.i_width, fmt.i_height))
107 goto error;
109 vout_display_info_t info = vd->info;
110 info.is_slow = false;
111 info.has_double_click = true;
112 info.has_pictures_invalid = true;
114 /* */
115 vd->fmt = fmt;
116 vd->info = info;
118 vd->pool = Pool;
119 vd->prepare = NULL;
120 vd->display = Display;
121 vd->manage = Manage;
122 vd->control = Control;
123 return VLC_SUCCESS;
125 error:
126 Close(VLC_OBJECT(vd));
127 return VLC_EGENERIC;
130 /* */
131 static void Close(vlc_object_t *object)
133 vout_display_t *vd = (vout_display_t *)object;
135 Clean(vd);
137 CommonClean(vd);
139 free(vd->sys);
142 /* */
143 static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
145 VLC_UNUSED(count);
146 return vd->sys->sys.pool;
149 static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
151 vout_display_sys_t *sys = vd->sys;
153 #define rect_src vd->sys->rect_src
154 #define rect_src_clipped vd->sys->sys.rect_src_clipped
155 #define rect_dest vd->sys->sys.rect_dest
156 #define rect_dest_clipped vd->sys->sys.rect_dest_clipped
157 RECT rect_dst = rect_dest_clipped;
158 HDC hdc = GetDC(sys->sys.hvideownd);
160 OffsetRect(&rect_dst, -rect_dest.left, -rect_dest.top);
161 SelectObject(sys->off_dc, sys->off_bitmap);
163 if (rect_dest_clipped.right - rect_dest_clipped.left !=
164 rect_src_clipped.right - rect_src_clipped.left ||
165 rect_dest_clipped.bottom - rect_dest_clipped.top !=
166 rect_src_clipped.bottom - rect_src_clipped.top) {
167 StretchBlt(hdc, rect_dst.left, rect_dst.top,
168 rect_dst.right, rect_dst.bottom,
169 sys->off_dc,
170 rect_src_clipped.left, rect_src_clipped.top,
171 rect_src_clipped.right, rect_src_clipped.bottom,
172 SRCCOPY);
173 } else {
174 BitBlt(hdc, rect_dst.left, rect_dst.top,
175 rect_dst.right, rect_dst.bottom,
176 sys->off_dc,
177 rect_src_clipped.left, rect_src_clipped.top,
178 SRCCOPY);
181 ReleaseDC(sys->sys.hvideownd, hdc);
182 #undef rect_src
183 #undef rect_src_clipped
184 #undef rect_dest
185 #undef rect_dest_clipped
186 /* TODO */
187 picture_Release(picture);
188 VLC_UNUSED(subpicture);
190 CommonDisplay(vd);
193 static int Control(vout_display_t *vd, int query, va_list args)
195 switch (query) {
196 case VOUT_DISPLAY_RESET_PICTURES:
197 vlc_assert_unreachable();
198 return VLC_EGENERIC;
199 default:
200 return CommonControl(vd, query, args);
205 static void Manage(vout_display_t *vd)
207 CommonManage(vd);
210 static int Init(vout_display_t *vd,
211 video_format_t *fmt, int width, int height)
213 vout_display_sys_t *sys = vd->sys;
215 /* */
216 RECT *display = &sys->sys.rect_display;
217 display->left = 0;
218 display->top = 0;
219 display->right = GetSystemMetrics(SM_CXSCREEN);;
220 display->bottom = GetSystemMetrics(SM_CYSCREEN);;
222 /* Initialize an offscreen bitmap for direct buffer operations. */
224 /* */
225 HDC window_dc = GetDC(sys->sys.hvideownd);
227 /* */
228 sys->i_depth = GetDeviceCaps(window_dc, PLANES) *
229 GetDeviceCaps(window_dc, BITSPIXEL);
231 /* */
232 msg_Dbg(vd, "GDI depth is %i", sys->i_depth);
233 switch (sys->i_depth) {
234 case 8:
235 fmt->i_chroma = VLC_CODEC_RGB8;
236 break;
237 case 15:
238 fmt->i_chroma = VLC_CODEC_RGB15;
239 fmt->i_rmask = 0x7c00;
240 fmt->i_gmask = 0x03e0;
241 fmt->i_bmask = 0x001f;
242 break;
243 case 16:
244 fmt->i_chroma = VLC_CODEC_RGB16;
245 fmt->i_rmask = 0xf800;
246 fmt->i_gmask = 0x07e0;
247 fmt->i_bmask = 0x001f;
248 break;
249 case 24:
250 fmt->i_chroma = VLC_CODEC_RGB24;
251 fmt->i_rmask = 0x00ff0000;
252 fmt->i_gmask = 0x0000ff00;
253 fmt->i_bmask = 0x000000ff;
254 break;
255 case 32:
256 fmt->i_chroma = VLC_CODEC_RGB32;
257 fmt->i_rmask = 0x00ff0000;
258 fmt->i_gmask = 0x0000ff00;
259 fmt->i_bmask = 0x000000ff;
260 break;
261 default:
262 msg_Err(vd, "screen depth %i not supported", sys->i_depth);
263 return VLC_EGENERIC;
265 fmt->i_width = width;
266 fmt->i_height = height;
268 void *p_pic_buffer;
269 int i_pic_pitch;
270 /* Initialize offscreen bitmap */
271 BITMAPINFO *bi = &sys->bitmapinfo;
272 memset(bi, 0, sizeof(BITMAPINFO) + 3 * sizeof(RGBQUAD));
273 if (sys->i_depth > 8) {
274 ((DWORD*)bi->bmiColors)[0] = fmt->i_rmask;
275 ((DWORD*)bi->bmiColors)[1] = fmt->i_gmask;
276 ((DWORD*)bi->bmiColors)[2] = fmt->i_bmask;;
279 BITMAPINFOHEADER *bih = &sys->bitmapinfo.bmiHeader;
280 bih->biSize = sizeof(BITMAPINFOHEADER);
281 bih->biSizeImage = 0;
282 bih->biPlanes = 1;
283 bih->biCompression = (sys->i_depth == 15 ||
284 sys->i_depth == 16) ? BI_BITFIELDS : BI_RGB;
285 bih->biBitCount = sys->i_depth;
286 bih->biWidth = fmt->i_width;
287 bih->biHeight = -fmt->i_height;
288 bih->biClrImportant = 0;
289 bih->biClrUsed = 0;
290 bih->biXPelsPerMeter = 0;
291 bih->biYPelsPerMeter = 0;
293 i_pic_pitch = bih->biBitCount * bih->biWidth / 8;
294 sys->off_bitmap = CreateDIBSection(window_dc,
295 (BITMAPINFO *)bih,
296 DIB_RGB_COLORS,
297 &p_pic_buffer, NULL, 0);
299 sys->off_dc = CreateCompatibleDC(window_dc);
301 SelectObject(sys->off_dc, sys->off_bitmap);
302 ReleaseDC(sys->sys.hvideownd, window_dc);
304 EventThreadUpdateTitle(sys->sys.event, VOUT_TITLE " (WinGDI output)");
306 /* */
307 picture_resource_t rsc;
308 memset(&rsc, 0, sizeof(rsc));
309 rsc.p[0].p_pixels = p_pic_buffer;
310 rsc.p[0].i_lines = fmt->i_height;
311 rsc.p[0].i_pitch = i_pic_pitch;;
313 picture_t *picture = picture_NewFromResource(fmt, &rsc);
314 if (picture != NULL)
315 sys->sys.pool = picture_pool_New(1, &picture);
316 else
317 sys->sys.pool = NULL;
319 UpdateRects(vd, NULL, true);
321 return VLC_SUCCESS;
324 static void Clean(vout_display_t *vd)
326 vout_display_sys_t *sys = vd->sys;
328 if (sys->sys.pool)
329 picture_pool_Release(sys->sys.pool);
330 sys->sys.pool = NULL;
332 if (sys->off_dc)
333 DeleteDC(sys->off_dc);
334 if (sys->off_bitmap)
335 DeleteObject(sys->off_bitmap);