10979
|
1 /*
|
|
2 VIDIX accelerated overlay in a WIN32 window
|
|
3
|
|
4 (C) Sascha Sommer
|
|
5
|
|
6
|
|
7 */
|
|
8
|
|
9 #include <stdio.h>
|
|
10 #include <stdlib.h>
|
|
11 #include <string.h>
|
|
12 #include <math.h>
|
|
13 #include <errno.h>
|
|
14
|
|
15 #include "config.h"
|
|
16 #include "video_out.h"
|
|
17 #include "video_out_internal.h"
|
|
18
|
|
19 #include <windows.h>
|
|
20 #include "../osdep/keycodes.h"
|
|
21 #include "../input/input.h"
|
|
22
|
|
23 #include "aspect.h"
|
|
24 #include "mp_msg.h"
|
|
25
|
|
26 #include "vosub_vidix.h"
|
|
27 #include "../vidix/vidixlib.h"
|
|
28
|
|
29 extern void mplayer_put_key(int code);
|
|
30
|
|
31 static vo_info_t info =
|
|
32 {
|
|
33 "WIN32 (VIDIX)",
|
|
34 "winvidix",
|
|
35 "Sascha Sommer",
|
|
36 ""
|
|
37 };
|
|
38
|
|
39 LIBVO_EXTERN(winvidix)
|
|
40
|
|
41 #define UNUSED(x) ((void)(x)) /* Removes warning about unused arguments */
|
|
42
|
|
43 /* VIDIX related */
|
|
44 static char *vidix_name;
|
|
45
|
|
46 /* Image parameters */
|
|
47 static uint32_t image_width;
|
|
48 static uint32_t image_height;
|
|
49 static uint32_t image_format;
|
|
50 static HWND hWnd;
|
|
51 /* Window parameters */
|
|
52 static HWND hWnd=NULL,hWndFS=NULL;
|
|
53
|
|
54 static vidix_grkey_t gr_key;
|
|
55
|
|
56
|
|
57 extern void set_video_eq( int cap );
|
|
58 extern int vo_config_count;
|
|
59
|
|
60
|
|
61 static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
62 {
|
|
63 switch (message){
|
|
64 case WM_DESTROY:
|
|
65 mp_input_queue_cmd(mp_input_parse_cmd("quit"));
|
|
66 break;
|
|
67 case WM_WINDOWPOSCHANGED:
|
|
68 {
|
|
69 /*calculate new window rect*/
|
|
70 if(!vo_fs){
|
|
71 RECT rd;
|
|
72 POINT point_window;
|
|
73 if(!hWnd)hWnd=hwnd;
|
|
74 ShowCursor(TRUE);
|
|
75 point_window.x = 0;
|
|
76 point_window.y = 0;
|
|
77 ClientToScreen(hWnd,&point_window);
|
|
78 GetClientRect(hWnd,&rd);
|
|
79
|
|
80 vo_dwidth=rd.right - rd.left;
|
|
81 vo_dheight=rd.bottom - rd.top;
|
|
82 vo_dx =point_window.x;
|
|
83 vo_dy =point_window.y;
|
|
84 // aspect(&vo_dwidth, &vo_dheight, A_NOZOOM);
|
|
85 }
|
|
86 else {
|
|
87 if(ShowCursor(FALSE)>=0)while(ShowCursor(FALSE)>=0){}
|
|
88 aspect(&vo_dwidth, &vo_dheight, A_ZOOM);
|
|
89 vo_dx = (vo_screenwidth - vo_dwidth)/2;
|
|
90 vo_dy = (vo_screenheight - vo_dheight)/2;
|
|
91 }
|
|
92 /*update vidix*/
|
|
93 /* FIXME: implement runtime resize/move if possible, this way is very ugly! */
|
|
94 vidix_stop();
|
|
95 if(vidix_init(image_width, image_height, vo_dx, vo_dy, vo_dwidth, vo_dheight, image_format, vo_depthonscreen, vo_screenwidth, vo_screenheight) != 0)
|
|
96 mp_msg(MSGT_VO, MSGL_FATAL, "Can't initialize VIDIX driver: %s\n", strerror(errno));
|
|
97 /*set colorkey*/
|
|
98 vidix_start();
|
|
99 mp_msg(MSGT_VO, MSGL_V, "[winvidix] window properties: pos: %dx%d, size: %dx%d\n",vo_dx, vo_dy, vo_dwidth, vo_dheight);
|
|
100 if(vidix_grkey_support()){
|
|
101 vidix_grkey_get(&gr_key);
|
|
102 gr_key.key_op = KEYS_PUT;
|
|
103 gr_key.ckey.op = CKEY_TRUE;
|
|
104 if(vo_fs)gr_key.ckey.red = gr_key.ckey.green = gr_key.ckey.blue = 0;
|
|
105 else {
|
|
106 gr_key.ckey.red = gr_key.ckey.blue = 255;
|
|
107 gr_key.ckey.green = 0;
|
|
108 }
|
|
109 vidix_grkey_set(&gr_key);
|
|
110 }
|
|
111
|
|
112 }
|
|
113 break;
|
|
114 case WM_SYSCOMMAND:
|
|
115 switch (wParam){
|
|
116 case SC_SCREENSAVE:
|
|
117 case SC_MONITORPOWER:
|
|
118 return 0;
|
|
119 }
|
|
120 break;
|
|
121 case WM_KEYDOWN:
|
|
122 switch (wParam){
|
|
123 case VK_LEFT:
|
|
124 {mplayer_put_key(KEY_LEFT);break;}
|
|
125 case VK_UP:
|
|
126 {mplayer_put_key(KEY_UP);break;}
|
|
127 case VK_RIGHT:
|
|
128 {mplayer_put_key(KEY_RIGHT);break;}
|
|
129 case VK_DOWN:
|
|
130 {mplayer_put_key(KEY_DOWN);break;}
|
|
131 case VK_TAB:
|
|
132 {mplayer_put_key(KEY_TAB);break;}
|
|
133 case VK_CONTROL:
|
|
134 {mplayer_put_key(KEY_CTRL);break;}
|
|
135 case VK_DELETE:
|
|
136 {mplayer_put_key(KEY_DELETE);break;}
|
|
137 case VK_INSERT:
|
|
138 {mplayer_put_key(KEY_INSERT);break;}
|
|
139 case VK_HOME:
|
|
140 {mplayer_put_key(KEY_HOME);break;}
|
|
141 case VK_END:
|
|
142 {mplayer_put_key(KEY_END);break;}
|
|
143 case VK_PRIOR:
|
|
144 {mplayer_put_key(KEY_PAGE_UP);break;}
|
|
145 case VK_NEXT:
|
|
146 {mplayer_put_key(KEY_PAGE_DOWN);break;}
|
|
147 case VK_ESCAPE:
|
|
148 {mplayer_put_key(KEY_ESC);break;}
|
|
149 }
|
|
150 break;
|
|
151 case WM_CHAR:
|
|
152 mplayer_put_key(wParam);
|
|
153 break;
|
|
154 }
|
|
155 return DefWindowProc(hwnd, message, wParam, lParam);
|
|
156 }
|
|
157
|
|
158
|
|
159 static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width,uint32_t d_height, uint32_t flags, char *title, uint32_t format){
|
|
160 title = "MPlayer VIDIX WIN32 Overlay";
|
|
161
|
|
162 panscan_init();
|
|
163
|
|
164 image_height = height;
|
|
165 image_width = width;
|
|
166 image_format = format;
|
|
167 vo_screenwidth = GetSystemMetrics(SM_CXSCREEN);
|
|
168 vo_screenheight = GetSystemMetrics(SM_CYSCREEN);
|
|
169 vo_depthonscreen = GetDeviceCaps(GetDC(GetDesktopWindow()),BITSPIXEL);
|
|
170
|
|
171
|
|
172 aspect_save_orig(width, height);
|
|
173 aspect_save_prescale(d_width, d_height);
|
|
174 aspect_save_screenres(vo_screenwidth, vo_screenheight);
|
|
175
|
|
176 vo_dx = 0;
|
|
177 vo_dy = 0;
|
|
178
|
|
179 vo_dx=( vo_screenwidth - d_width ) / 2; vo_dy=( vo_screenheight - d_height ) / 2;
|
|
180 geometry(&vo_dx, &vo_dy, &d_width, &d_height, vo_screenwidth, vo_screenheight);
|
|
181
|
|
182 vo_fs = flags&0x01;
|
|
183
|
|
184
|
|
185 aspect(&d_width, &d_height, A_NOZOOM);
|
|
186 vo_dwidth=d_width; vo_dheight=d_height;
|
|
187
|
|
188
|
|
189
|
|
190 if(!vo_config_count){
|
|
191 HINSTANCE hInstance = GetModuleHandle(NULL);
|
|
192 WNDCLASS wc;
|
|
193 RECT rd;
|
|
194 rd.left = vo_dx;
|
|
195 rd.top = vo_dy;
|
|
196 rd.right = rd.left + vo_dwidth;
|
|
197 rd.bottom = rd.top + vo_dheight;
|
|
198 AdjustWindowRect(&rd,WS_OVERLAPPEDWINDOW| WS_SIZEBOX,0);
|
|
199 wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
200 wc.lpfnWndProc = WndProc;
|
|
201 wc.cbClsExtra = 0;
|
|
202 wc.cbWndExtra = 0;
|
|
203 wc.hInstance = hInstance;
|
|
204 wc.hCursor = LoadCursor(NULL,IDC_ARROW);
|
|
205 wc.hIcon =ExtractIcon(hInstance,"mplayer.exe",0);
|
|
206 //LoadIcon(NULL,IDI_APPLICATION);
|
|
207 wc.hbrBackground = CreateSolidBrush(RGB(255,0,255));
|
12858
|
208 wc.lpszClassName = "MPlayer - The Movie Player";
|
10979
|
209 wc.lpszMenuName = NULL;
|
|
210 RegisterClass(&wc);
|
12861
|
211 hWnd = CreateWindow("MPlayer - The Movie Player",
|
10979
|
212 title,
|
|
213 WS_OVERLAPPEDWINDOW| WS_SIZEBOX,
|
|
214 rd.left,
|
|
215 rd.top,
|
|
216 rd.right - rd.left,
|
|
217 rd.bottom - rd.top,
|
|
218 NULL,
|
|
219 NULL,
|
|
220 hInstance,
|
|
221 NULL);
|
|
222 wc.hbrBackground = CreateSolidBrush(RGB(0,0,0));
|
|
223 wc.lpszClassName = "MPlayer - Fullscreen";
|
|
224 RegisterClass(&wc);
|
|
225 hWndFS = CreateWindow("MPlayer - Fullscreen","MPlayer VIDIX Fullscreen",WS_POPUP,0,0,vo_screenwidth,vo_screenheight,hWnd,NULL,hInstance,NULL);
|
|
226
|
|
227
|
|
228
|
|
229
|
|
230
|
|
231 }
|
|
232 ShowWindow(hWnd,SW_SHOW);
|
|
233 if(vo_fs)ShowWindow(hWndFS,SW_SHOW);
|
|
234
|
|
235 return(0);
|
|
236 }
|
|
237
|
|
238 static void check_events(void){
|
|
239 MSG msg;
|
|
240 while (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
|
|
241 {
|
|
242 TranslateMessage(&msg);
|
|
243 DispatchMessage(&msg);
|
|
244 }
|
|
245 }
|
|
246
|
|
247 /* draw_osd, flip_page, draw_slice, draw_frame should be
|
|
248 overwritten with vidix functions (vosub_vidix.c) */
|
|
249 static void draw_osd(void){
|
|
250 mp_msg(MSGT_VO, MSGL_FATAL, "[winvidix] error: didn't use vidix draw_osd!\n");
|
|
251 return;
|
|
252 }
|
|
253
|
|
254 static void flip_page(void){
|
|
255 mp_msg(MSGT_VO, MSGL_FATAL, "[winvidix] error: didn't use vidix flip_page!\n");
|
|
256 return;
|
|
257 }
|
|
258
|
|
259 static uint32_t draw_slice(uint8_t *src[], int stride[],int w, int h, int x, int y){
|
|
260 UNUSED(src);
|
|
261 UNUSED(stride);
|
|
262 UNUSED(w);
|
|
263 UNUSED(h);
|
|
264 UNUSED(x);
|
|
265 UNUSED(y);
|
|
266 mp_msg(MSGT_VO, MSGL_FATAL, "[winvidix] error: didn't use vidix draw_slice!\n");
|
|
267 return(-1);
|
|
268 }
|
|
269
|
|
270 static uint32_t draw_frame(uint8_t *src[]){
|
|
271 UNUSED(src);
|
|
272 mp_msg(MSGT_VO, MSGL_FATAL, "[winvidix] error: didn't use vidix draw_frame!\n");
|
|
273 return(-1);
|
|
274 }
|
|
275
|
|
276 static uint32_t query_format(uint32_t format){
|
|
277 return(vidix_query_fourcc(format));
|
|
278 }
|
|
279
|
|
280 static void uninit(void){
|
|
281 DestroyWindow(hWndFS);
|
|
282 DestroyWindow(hWnd);
|
|
283 if ( !vo_config_count ) return;
|
|
284 vidix_term();
|
|
285
|
|
286 if (vidix_name){
|
|
287 free(vidix_name);
|
|
288 vidix_name = NULL;
|
|
289 }
|
|
290 //
|
|
291 }
|
|
292
|
|
293 static uint32_t preinit(const char *arg){
|
|
294 if (arg)
|
|
295 vidix_name = strdup(arg);
|
|
296 else
|
|
297 {
|
11462
|
298 mp_msg(MSGT_VO, MSGL_INFO, "No vidix driver name provided, probing available ones (-v option for details)!\n");
|
10979
|
299 vidix_name = NULL;
|
|
300 }
|
|
301
|
|
302 if (vidix_preinit(vidix_name, &video_out_winvidix) != 0)
|
|
303 return(1);
|
|
304
|
|
305 return(0);
|
|
306 }
|
|
307
|
|
308 static uint32_t control(uint32_t request, void *data, ...){
|
|
309 switch (request) {
|
|
310 case VOCTRL_FULLSCREEN:
|
|
311 if(!vo_fs){vo_fs=1;ShowWindow(hWndFS,SW_SHOW);}
|
|
312 else {vo_fs=0; ShowWindow(hWndFS,SW_HIDE);}
|
|
313 break;
|
|
314 case VOCTRL_QUERY_FORMAT:
|
|
315 return query_format(*((uint32_t*)data));
|
|
316 case VOCTRL_SET_EQUALIZER:
|
|
317 {
|
|
318 va_list ap;
|
|
319 int value;
|
|
320
|
|
321 va_start(ap, data);
|
|
322 value = va_arg(ap, int);
|
|
323 va_end(ap);
|
|
324
|
|
325 return vidix_control(request, data, (int *)value);
|
|
326 }
|
|
327 case VOCTRL_GET_EQUALIZER:
|
|
328 {
|
|
329 va_list ap;
|
|
330 int *value;
|
|
331
|
|
332 va_start(ap, data);
|
|
333 value = va_arg(ap, int*);
|
|
334 va_end(ap);
|
|
335
|
|
336 return vidix_control(request, data, value);
|
|
337 }
|
|
338 }
|
|
339 return vidix_control(request, data);
|
|
340 // return VO_NOTIMPL;
|
|
341 }
|