Mercurial > mplayer.hg
comparison libvo/vo_ggi.c @ 4828:0ae597cc28e6
totally reworked, working fine on fbdev too, applied Andres Beck's patches, quad-buffering support
author | alex |
---|---|
date | Sat, 23 Feb 2002 23:31:08 +0000 |
parents | 32e1f5042f65 |
children | 2c1dd0b15622 |
comparison
equal
deleted
inserted
replaced
4827:8570abfc6feb | 4828:0ae597cc28e6 |
---|---|
3 | 3 |
4 (C) Alex Beregszaszi <alex@naxine.org> | 4 (C) Alex Beregszaszi <alex@naxine.org> |
5 | 5 |
6 Uses libGGI - http://www.ggi-project.org/ | 6 Uses libGGI - http://www.ggi-project.org/ |
7 | 7 |
8 Thanks to Andreas Beck for his patches. | |
8 Many thanks to Atmosfear, he hacked this driver to working with Planar | 9 Many thanks to Atmosfear, he hacked this driver to working with Planar |
9 formats, and he fixed the RGB handling. | 10 formats, and he fixed the RGB handling. |
10 */ | 11 */ |
11 | 12 |
12 #include <stdio.h> | 13 #include <stdio.h> |
13 #include <stdlib.h> | 14 #include <stdlib.h> |
14 #include <string.h> | 15 #include <string.h> |
15 #include <errno.h> | 16 #include <errno.h> |
16 | 17 |
18 #include "mp_msg.h" | |
19 | |
17 #include "../config.h" | 20 #include "../config.h" |
18 #include "video_out.h" | 21 #include "video_out.h" |
19 #include "video_out_internal.h" | 22 #include "video_out_internal.h" |
20 | 23 |
21 #include "fastmemcpy.h" | 24 #include "fastmemcpy.h" |
22 | 25 |
23 #include <ggi/ggi.h> | 26 #include <ggi/ggi.h> |
24 | 27 |
25 #undef GGI_OST | 28 #undef GET_DB_INFO |
26 #undef GII_BUGGY_KEYCODES | 29 |
27 #define GGI_OSD | 30 #define GGI_FRAMES 4 |
28 | |
29 #undef get_db_info | |
30 | 31 |
31 /* do not make conversions from planar formats */ | 32 /* do not make conversions from planar formats */ |
32 #undef GGI_PLANAR_NOCONV | 33 #undef GGI_YUV_SUPPORT |
33 | 34 |
34 #ifndef GGI_PLANAR_NOCONV | 35 #ifndef GGI_YUV_SUPPORT |
35 #include "../postproc/rgb2rgb.h" | 36 #include "../postproc/rgb2rgb.h" |
36 #endif | 37 #endif |
37 | 38 |
38 LIBVO_EXTERN (ggi) | 39 LIBVO_EXTERN (ggi) |
39 | 40 |
43 "ggi", | 44 "ggi", |
44 "Alex Beregszaszi <alex@naxine.org>", | 45 "Alex Beregszaszi <alex@naxine.org>", |
45 "under developement" | 46 "under developement" |
46 }; | 47 }; |
47 | 48 |
48 extern int verbose; | |
49 | |
50 /* idea stolen from vo_sdl.c :) */ | |
51 static struct ggi_conf_s { | 49 static struct ggi_conf_s { |
52 char *driver; | 50 char *driver; |
53 | 51 |
54 ggi_visual_t vis; | 52 ggi_visual_t vis; |
55 ggi_directbuffer *buffer; | 53 ggi_directbuffer *buffer[GGI_FRAMES]; |
54 ggi_mode gmode; | |
55 | |
56 int frames; | |
57 int currframe; | |
56 | 58 |
57 uint8_t bpp; | 59 uint8_t bpp; |
58 uint8_t bppmul; | 60 uint8_t bppmul; |
59 | 61 |
60 uint8_t mode; | 62 uint8_t mode; |
69 /* RGB */ | 71 /* RGB */ |
70 int framePlaneRGB; | 72 int framePlaneRGB; |
71 int stridePlaneRGB; | 73 int stridePlaneRGB; |
72 | 74 |
73 /* original */ | 75 /* original */ |
74 int width, height; | 76 int srcwidth, srcheight; |
77 int srcformat; | |
78 int srcdepth; | |
79 int srctype; | |
75 | 80 |
76 /* destination */ | 81 /* destination */ |
77 int dstwidth, dstheight; | 82 int dstwidth, dstheight; |
78 | 83 |
79 /* source image format */ | 84 /* source image format */ |
80 int format; | 85 int format; |
81 | |
82 /* direct buffer */ | |
83 uint8_t *dbuff; | |
84 | |
85 /* i.e. need lock */ | |
86 int need_acquire; | |
87 | |
88 #ifdef GGI_OST | |
89 ggi_pixel white; | |
90 ggi_pixel black; | |
91 #endif | |
92 } ggi_conf; | 86 } ggi_conf; |
93 | 87 |
94 static int ggi_setmode(uint32_t d_width, uint32_t d_height, int d_depth) | 88 static int ggi_setmode(uint32_t d_width, uint32_t d_height, int d_depth) |
95 { | 89 { |
96 ggi_mode mode = | 90 ggi_mode mode = |
97 { | 91 { |
98 1, /* frames */ | 92 GGI_FRAMES, /* frames */ |
99 { GGI_AUTO, GGI_AUTO }, /* visible */ | 93 { GGI_AUTO, GGI_AUTO }, /* visible */ |
100 { GGI_AUTO, GGI_AUTO }, /* virt */ | 94 { GGI_AUTO, GGI_AUTO }, /* virt */ |
101 { GGI_AUTO, GGI_AUTO }, /* size */ | 95 { GGI_AUTO, GGI_AUTO }, /* size */ |
102 GT_AUTO, /* graphtype */ | 96 GT_AUTO, /* graphtype */ |
103 { GGI_AUTO, GGI_AUTO } /* dots per pixel */ | 97 { GGI_AUTO, GGI_AUTO } /* dots per pixel */ |
104 }; | 98 }; |
105 ggi_color pal[256]; | 99 ggi_color pal[256]; |
106 | 100 |
107 if (verbose) | 101 mp_msg(MSGT_VO, MSGL_V, "[ggi] mode requested: %dx%d (%d depth)\n", |
108 printf("ggi-setmode: requested: %dx%d (%d depth)\n", | 102 d_width, d_height, d_depth); |
109 d_width, d_height, d_depth); | 103 |
110 | 104 // mode.size.x = vo_screenwidth; |
111 mode.size.x = vo_screenwidth; | 105 // mode.size.y = vo_screenheight; |
112 mode.size.y = vo_screenheight; | 106 mode.visible.x = d_width; |
113 mode.visible.x = mode.virt.x = d_width; | 107 mode.visible.y = d_height; |
114 mode.visible.y = mode.virt.y = d_height; | |
115 | 108 |
116 switch(d_depth) | 109 switch(d_depth) |
117 { | 110 { |
118 case 1: | 111 case 1: |
119 mode.graphtype = GT_1BIT; | 112 mode.graphtype = GT_1BIT; |
138 break; | 131 break; |
139 case 32: | 132 case 32: |
140 mode.graphtype = GT_32BIT; | 133 mode.graphtype = GT_32BIT; |
141 break; | 134 break; |
142 default: | 135 default: |
143 printf("ggi-setmode: unknown bit depth - using auto\n"); | 136 mp_msg(MSGT_VO, MSGL_ERR, "[ggi] unknown bit depth - using auto\n"); |
144 mode.graphtype = GT_AUTO; | 137 mode.graphtype = GT_AUTO; |
145 } | 138 } |
146 | 139 |
140 /* FIXME */ | |
147 ggiCheckMode(ggi_conf.vis, &mode); | 141 ggiCheckMode(ggi_conf.vis, &mode); |
148 | 142 |
149 if (ggiSetMode(ggi_conf.vis, &mode) != 0) | 143 if (ggiSetMode(ggi_conf.vis, &mode) != 0) |
150 { | 144 { |
151 printf("ggi-setmode: unable to set mode\n"); | 145 mp_msg(MSGT_VO, MSGL_ERR, "[ggi] unable to set mode\n"); |
152 ggiClose(ggi_conf.vis); | 146 uninit(); |
153 ggiExit(); | |
154 return(-1); | 147 return(-1); |
155 } | 148 } |
156 | 149 |
157 if (ggiGetMode(ggi_conf.vis, &mode) != 0) | 150 if (ggiGetMode(ggi_conf.vis, &mode) != 0) |
158 { | 151 { |
159 printf("ggi-setmode: unable to get mode\n"); | 152 mp_msg(MSGT_VO, MSGL_ERR, "[ggi] unable to get mode\n"); |
160 ggiClose(ggi_conf.vis); | 153 uninit(); |
161 ggiExit(); | |
162 return(-1); | 154 return(-1); |
163 } | 155 } |
164 | 156 |
165 ggi_conf.width = mode.virt.x; | 157 ggi_conf.gmode = mode; |
166 ggi_conf.height = mode.virt.y; | 158 |
167 vo_screenwidth = mode.visible.x; | 159 vo_screenwidth = mode.visible.x; |
168 vo_screenheight = mode.visible.y; | 160 vo_screenheight = mode.visible.y; |
169 vo_depthonscreen = d_depth; | 161 vo_depthonscreen = d_depth; |
170 // vo_depthonscreen = GT_DEPTH(mode.graphtype); | 162 // vo_depthonscreen = GT_DEPTH(mode.graphtype); |
171 // ggi_bpp = GT_SIZE(mode.graphtype); | 163 // ggi_bpp = GT_SIZE(mode.graphtype); |
172 ggi_conf.bpp = vo_depthonscreen; | 164 ggi_conf.bpp = vo_depthonscreen; |
173 | 165 |
174 #ifdef get_db_info | 166 #ifdef GET_DB_INFO |
175 { | 167 { |
176 const ggi_directbuffer *db = ggiDBGetBuffer(ggi_conf.vis, 0); | 168 const ggi_directbuffer *db = ggiDBGetBuffer(ggi_conf.vis, 0); |
177 | 169 |
178 if (db) | 170 if (db) |
179 { | 171 { |
187 { | 179 { |
188 ggiSetColorfulPalette(ggi_conf.vis); | 180 ggiSetColorfulPalette(ggi_conf.vis); |
189 ggiGetPalette(ggi_conf.vis, 0, 1 << ggi_conf.bpp, pal); | 181 ggiGetPalette(ggi_conf.vis, 0, 1 << ggi_conf.bpp, pal); |
190 } | 182 } |
191 | 183 |
192 if (verbose) | 184 #if 0 |
193 printf("ggi-setmode: %dx%d (virt: %dx%d) (size: %dx%d) screen depth: %d, bpp: %d\n", | 185 printf("[ggi] mode: "); |
194 vo_screenwidth, vo_screenheight, ggi_conf.width, ggi_conf.height, | 186 ggiPrintMode(&ggi_conf.gmode); |
195 mode.size.x, mode.size.y, | 187 printf("\n"); |
196 vo_depthonscreen, ggi_conf.bpp); | 188 #endif |
189 | |
190 mp_msg(MSGT_VO, MSGL_INFO, "[ggi] screen: %dx%dx%d frames: %d\n", | |
191 vo_screenwidth, vo_screenheight, vo_depthonscreen, ggi_conf.gmode.frames); | |
197 | 192 |
198 ggi_conf.bppmul = (ggi_conf.bpp+7)/8; | 193 ggi_conf.bppmul = (ggi_conf.bpp+7)/8; |
199 | 194 |
200 return(0); | 195 return(0); |
201 } | 196 } |
202 | 197 |
203 typedef struct ggi_aspect_ret_s { int w, h, x, y; } ggi_aspect_ret; | |
204 | |
205 /* stolen from vo_sdl.c */ | |
206 #define MONITOR_ASPECT 4.0/3.0 | |
207 static ggi_aspect_ret aspect_size(int srcw, int srch, int dstw, int dsth) | |
208 { | |
209 ggi_aspect_ret ret; | |
210 float float_h; | |
211 | |
212 if (verbose) | |
213 printf("ggi-aspectsize: src: %dx%d dst: %dx%d\n", | |
214 srcw, srch, dstw, dsth); | |
215 | |
216 float_h = ((float)dsth / (float)srcw * (float)srch) * ((float)dsth / | |
217 ((float)dstw / (MONITOR_ASPECT))); | |
218 | |
219 if (float_h > dsth) | |
220 { | |
221 ret.w = (int)((float)dsth / (float)float_h) * dstw; | |
222 ret.h = dsth; | |
223 ret.x = (dstw - ret.w) / 2; | |
224 ret.y = 0; | |
225 } | |
226 else | |
227 { | |
228 ret.h = (int)float_h; | |
229 ret.w = dstw; | |
230 ret.x = 0; | |
231 ret.y = (dsth - ret.h) / 2; | |
232 } | |
233 | |
234 printf("ggi-aspectsize: %dx%d (x: %d, y: %d)\n", ret.w, ret.h, ret.x, ret.y); | |
235 return(ret); | |
236 } | |
237 | 198 |
238 static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, | 199 static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, |
239 uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format,const vo_tune_info_t *info) | 200 uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format,const vo_tune_info_t *info) |
240 { | 201 { |
202 int i; | |
203 | |
241 vo_depthonscreen = 32; | 204 vo_depthonscreen = 32; |
242 printf("ggi-init: This driver has got bugs, if you can, fix them.\n"); | 205 mp_msg(MSGT_VO, MSGL_INFO, "[ggi] This driver has got bugs, if you can, fix them.\n"); |
243 | 206 |
244 if (ggiInit() != 0) | 207 /* source image parameters */ |
245 { | 208 ggi_conf.srcwidth = width; |
246 printf("ggi-init: unable to initialize GGI\n"); | 209 ggi_conf.srcheight = height; |
247 return(-1); | 210 ggi_conf.srcformat = format; |
248 } | 211 if (IMGFMT_IS_RGB(ggi_conf.srcformat)) |
249 | 212 { |
250 ggi_conf.driver = NULL; | 213 ggi_conf.srcdepth = IMGFMT_RGB_DEPTH(ggi_conf.srcformat); |
251 | 214 ggi_conf.srctype = RGB; |
252 if ((ggi_conf.vis = ggiOpen(ggi_conf.driver)) == NULL) | 215 } |
253 { | 216 else |
254 printf("ggi-init: unable to open GGI for %s output\n", | 217 if (IMGFMT_IS_BGR(ggi_conf.srcformat)) |
255 (ggi_conf.driver == NULL) ? "default" : ggi_conf.driver); | 218 { |
256 ggiExit(); | 219 ggi_conf.srcdepth = IMGFMT_BGR_DEPTH(ggi_conf.srcformat); |
257 return(-1); | 220 ggi_conf.srctype = BGR; |
258 } | 221 } |
259 | 222 else |
260 printf("ggi-init: using %s GGI output\n", | 223 switch(ggi_conf.srcformat) |
261 (ggi_conf.driver == NULL) ? "default" : ggi_conf.driver); | 224 { |
262 | 225 case IMGFMT_IYUV: |
263 switch(format) | 226 case IMGFMT_I420: |
264 { | 227 case IMGFMT_YV12: |
265 case IMGFMT_RGB8: | 228 #ifdef GGI_YUV_SUPPORT |
266 ggi_conf.bpp = 8; | 229 ggi_conf.srcdepth = 12; |
230 ggi_conf.srctype = YUV; | |
231 #else | |
232 ggi_conf.bpp = vo_depthonscreen; | |
267 ggi_conf.mode = RGB; | 233 ggi_conf.mode = RGB; |
268 break; | 234 yuv2rgb_init(vo_depthonscreen, MODE_RGB); |
269 case IMGFMT_RGB15: | 235 #endif |
270 ggi_conf.bpp = 15; | 236 break; |
237 case IMGFMT_UYVY: | |
238 case IMGFMT_YUY2: | |
239 #ifdef GGI_YUV_SUPPORT | |
240 ggi_conf.srcdepth = 16; | |
241 ggi_conf.srctype = YUV; | |
242 #else | |
243 ggi_conf.bpp = vo_depthonscreen; | |
271 ggi_conf.mode = RGB; | 244 ggi_conf.mode = RGB; |
272 break; | 245 yuv2rgb_init(vo_depthonscreen, MODE_RGB); |
273 case IMGFMT_RGB16: | |
274 ggi_conf.bpp = 16; | |
275 ggi_conf.mode = RGB; | |
276 break; | |
277 case IMGFMT_RGB24: | |
278 ggi_conf.bpp = 24; | |
279 ggi_conf.mode = RGB; | |
280 break; | |
281 case IMGFMT_RGB32: | |
282 ggi_conf.bpp = 32; | |
283 ggi_conf.mode = RGB; | |
284 break; | |
285 case IMGFMT_BGR8: | |
286 ggi_conf.bpp = 8; | |
287 ggi_conf.mode = BGR; | |
288 break; | |
289 case IMGFMT_BGR15: | |
290 ggi_conf.bpp = 15; | |
291 ggi_conf.mode = BGR; | |
292 break; | |
293 case IMGFMT_BGR16: | |
294 ggi_conf.bpp = 16; | |
295 ggi_conf.mode = BGR; | |
296 break; | |
297 case IMGFMT_BGR24: | |
298 ggi_conf.bpp = 24; | |
299 ggi_conf.mode = BGR; | |
300 break; | |
301 case IMGFMT_BGR32: | |
302 ggi_conf.bpp = 32; | |
303 ggi_conf.mode = BGR; | |
304 break; | |
305 case IMGFMT_YV12: /* rgb, 24bit */ | |
306 case IMGFMT_I420: | |
307 case IMGFMT_IYUV: | |
308 ggi_conf.bpp = 16; | |
309 ggi_conf.mode = YUV; | |
310 #ifndef GGI_PLANAR_NOCONV | |
311 yuv2rgb_init(32/*vo_depthonscreen*/, MODE_RGB); | |
312 #endif | |
313 break; | |
314 case IMGFMT_YUY2: | |
315 ggi_conf.bpp = 24; | |
316 ggi_conf.mode = YUV; | |
317 #ifndef GGI_PLANAR_NOCONV | |
318 yuv2rgb_init(32, MODE_RGB); | |
319 #endif | 246 #endif |
320 break; | 247 break; |
321 default: | 248 default: |
322 printf("ggi-init: no suitable image format found (requested: %s)\n", | 249 mp_msg(MSGT_VO, MSGL_FATAL, "[ggi] Unknown image format: %s\n", |
323 vo_format_name(format)); | 250 vo_format_name(ggi_conf.srcformat)); |
251 uninit(); | |
324 return(-1); | 252 return(-1); |
325 } | 253 } |
326 | 254 |
327 ggi_conf.format = format; | 255 ggi_conf.format = format; |
328 | 256 |
329 ggi_conf.framePlaneRGB = width * height * ((ggi_conf.bpp+7)/8); /* fix it! */ | 257 ggi_conf.framePlaneRGB = width * height * ((ggi_conf.bpp+7)/8); /* fix it! */ |
330 ggi_conf.stridePlaneRGB = width * ((ggi_conf.bpp+7)/8); | 258 ggi_conf.stridePlaneRGB = width * ((ggi_conf.bpp+7)/8); |
331 #ifdef GGI_PLANAR_NOCONV | 259 #ifdef GGI_YUV_SUPPORT |
332 ggi_conf.framePlaneY = width * height; | 260 ggi_conf.framePlaneY = width * height; |
333 ggi_conf.framePlaneUV = (width * height) >> 2; | 261 ggi_conf.framePlaneUV = (width * height) >> 2; |
334 ggi_conf.framePlaneYUY = width * height * 2; | 262 ggi_conf.framePlaneYUY = width * height * 2; |
335 ggi_conf.stridePlaneY = width; | 263 ggi_conf.stridePlaneY = width; |
336 ggi_conf.stridePlaneUV = width/2; | 264 ggi_conf.stridePlaneUV = width/2; |
337 ggi_conf.stridePlaneYUY = width * 2; | 265 ggi_conf.stridePlaneYUY = width * 2; |
338 #endif | 266 #endif |
339 ggi_conf.width = width; | 267 // ggi_conf.width = width; |
340 ggi_conf.height = height; | 268 // ggi_conf.height = height; |
341 ggi_conf.dstwidth = d_width ? d_width : width; | 269 ggi_conf.dstwidth = d_width ? d_width : width; |
342 ggi_conf.dstheight = d_height ? d_height : height; | 270 ggi_conf.dstheight = d_height ? d_height : height; |
343 | 271 |
344 { | 272 { |
273 #if 0 | |
345 ggi_aspect_ret asp; | 274 ggi_aspect_ret asp; |
346 | 275 |
347 if (width != d_width || height != d_height) | 276 if (width != d_width || height != d_height) |
348 asp = aspect_size(width, height, d_width, d_height); | 277 asp = aspect_size(width, height, d_width, d_height); |
349 else | 278 else |
350 { | 279 { |
351 asp.w = width; | 280 asp.w = width; |
352 asp.h = height; | 281 asp.h = height; |
353 } | 282 } |
283 #endif | |
354 | 284 |
355 if (ggi_setmode(asp.w, asp.h, vo_depthonscreen) != 0) | 285 if (ggi_setmode(width, height, vo_depthonscreen) != 0) |
356 { | 286 { |
357 printf("ggi-init: setmode returned with error\n"); | 287 printf("ggi-init: setmode returned with error\n"); |
358 return(-1); | 288 return(-1); |
359 } | 289 } |
360 } | 290 } |
361 | 291 |
362 printf("ggi-init: input: %d bpp %s - screen depth: %d\n", ggi_conf.bpp, | 292 mp_msg(MSGT_VO, MSGL_INFO, "[ggi] input: %d bpp %s - screen depth: %d\n", |
363 vo_format_name(ggi_conf.format), vo_depthonscreen); | 293 ggi_conf.bpp, vo_format_name(ggi_conf.format), vo_depthonscreen); |
364 | 294 |
365 ggiSetFlags(ggi_conf.vis, GGIFLAG_ASYNC); | 295 // ggiSetFlags(ggi_conf.vis, GGIFLAG_ASYNC); |
366 | 296 |
367 ggi_conf.buffer = (ggi_directbuffer *)ggiDBGetBuffer(ggi_conf.vis, 0); | 297 { |
368 | 298 ggi_directbuffer *DB; |
369 if (ggi_conf.buffer == NULL) | 299 |
370 { | 300 for (i = 0; i < GGI_FRAMES; i++) |
371 printf("ggi-init: double buffering is not available\n"); | 301 ggi_conf.buffer[i] = NULL; |
372 ggiClose(ggi_conf.vis); | 302 |
373 ggiExit(); | 303 ggi_conf.frames = ggi_conf.currframe = 0; |
304 | |
305 for (i = 0; DB = ggiDBGetBuffer(ggi_conf.vis, i); i++) | |
306 { | |
307 if (!(DB->type & GGI_DB_SIMPLE_PLB) || | |
308 (DB->page_size != 0) || | |
309 (DB->write == NULL) || | |
310 (DB->noaccess != 0) || | |
311 (DB->align != 0) || | |
312 (DB->layout != blPixelLinearBuffer)) | |
313 continue; | |
314 | |
315 ggi_conf.buffer[DB->frame] = DB; | |
316 ggi_conf.frames++; | |
317 } | |
318 } | |
319 | |
320 | |
321 if (ggi_conf.buffer[0] == NULL) | |
322 { | |
323 mp_msg(MSGT_VO, MSGL_ERR, "[ggi] direct buffer is not available\n"); | |
324 uninit(); | |
374 return(-1); | 325 return(-1); |
375 } | 326 } |
376 | 327 |
377 if (!(ggi_conf.buffer->type & GGI_DB_SIMPLE_PLB) || | 328 for (i = 0; i < ggi_conf.frames; i++) |
378 (ggi_conf.buffer->page_size != 0) || | 329 { |
379 (ggi_conf.buffer->write == NULL) || | 330 if (ggi_conf.buffer[i] == NULL) |
380 (ggi_conf.buffer->noaccess != 0) || | 331 { |
381 (ggi_conf.buffer->align != 0) || | 332 mp_msg(MSGT_VO, MSGL_ERR, "[ggi] direct buffer for doublbuffering is not available\n"); |
382 (ggi_conf.buffer->layout != blPixelLinearBuffer)) | 333 uninit(); |
383 { | 334 return(-1); |
384 printf("ggi-init: incorrect video memory type\n"); | 335 } |
385 ggiClose(ggi_conf.vis); | 336 } |
386 ggiExit(); | 337 |
387 return(-1); | 338 ggiSetDisplayFrame(ggi_conf.vis, ggi_conf.currframe); |
388 } | 339 ggiSetWriteFrame(ggi_conf.vis, ggi_conf.currframe); |
389 | |
390 if (ggi_conf.buffer->resource != NULL) | |
391 ggi_conf.need_acquire = 1; | |
392 | |
393 if (verbose && ggi_conf.need_acquire) | |
394 printf("ggi-init: ggi needs acquire\n"); | |
395 | |
396 ggi_conf.dbuff = ggi_conf.buffer->write; | |
397 | |
398 #ifdef GGI_OST | |
399 /* just for fun */ | |
400 { | |
401 ggi_color col; | |
402 | |
403 /* set black */ | |
404 col.r = col.g = col.b = 0x0000; | |
405 ggi_conf.black = ggiMapColor(ggi_conf.vis, &col); | |
406 | |
407 /* set white */ | |
408 col.r = col.g = col.b = 0xffff; | |
409 ggi_conf.white = ggiMapColor(ggi_conf.vis, &col); | |
410 | |
411 ggiSetGCForeground(ggi_conf.vis, ggi_conf.white); | |
412 ggiSetGCBackground(ggi_conf.vis, ggi_conf.black); | |
413 } | |
414 #endif | |
415 | 340 |
416 return(0); | 341 return(0); |
417 } | 342 } |
418 | 343 |
419 static const vo_info_t *get_info(void) | 344 static const vo_info_t *get_info(void) |
421 return &vo_info; | 346 return &vo_info; |
422 } | 347 } |
423 | 348 |
424 static uint32_t draw_frame(uint8_t *src[]) | 349 static uint32_t draw_frame(uint8_t *src[]) |
425 { | 350 { |
426 if (ggi_conf.need_acquire) | 351 int x, y, size; |
427 ggiResourceAcquire(ggi_conf.buffer->resource, GGI_ACTYPE_WRITE); | 352 unsigned char *ptr, *ptr2, *spt; |
428 | 353 |
429 // ggiSetDisplayFrame(ggi_conf.vis, ggi_conf.buffer->frame); | 354 ggiResourceAcquire(ggi_conf.buffer[ggi_conf.currframe]->resource, |
430 // ggiSetWriteFrame(ggi_conf.vis, ggi_conf.buffer->frame); | 355 GGI_ACTYPE_WRITE); |
431 | 356 |
432 #ifdef GGI_PLANAR_NOCONV | 357 ggiSetWriteFrame(ggi_conf.vis, ggi_conf.currframe); |
358 | |
359 #if 1 | |
360 ptr = ggi_conf.buffer[ggi_conf.currframe]->write; | |
361 spt = src[0]; | |
362 size = ggi_conf.buffer[ggi_conf.currframe]->buffer.plb.pixelformat->size/8; | |
363 | |
364 for (y = 0; y < ggi_conf.srcheight; y++) | |
365 { | |
366 ptr2 = ptr; | |
367 for (x = 0; x < ggi_conf.srcwidth; x++) | |
368 { | |
369 ptr2[0] = *spt++; | |
370 ptr2[1] = *spt++; | |
371 ptr2[2] = *spt++; | |
372 switch(ggi_conf.format) | |
373 { | |
374 case IMGFMT_BGR32: | |
375 case IMGFMT_RGB32: | |
376 spt++; | |
377 break; | |
378 } | |
379 ptr2 += size; | |
380 } | |
381 ptr += ggi_conf.buffer[ggi_conf.currframe]->buffer.plb.stride; | |
382 } | |
383 #else | |
384 memcpy(ggi_conf.buffer[ggi_conf.currframe]->write, src[0], ggi_conf.framePlaneRGB); | |
385 #endif | |
386 | |
387 ggiResourceRelease(ggi_conf.buffer[ggi_conf.currframe]->resource); | |
388 return(0); | |
389 } | |
390 | |
391 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, | |
392 unsigned char *srca, int stride) | |
393 { | |
433 switch(ggi_conf.format) | 394 switch(ggi_conf.format) |
434 { | 395 { |
435 case IMGFMT_YV12: | 396 case IMGFMT_YV12: |
436 case IMGFMT_I420: | 397 case IMGFMT_I420: |
437 case IMGFMT_IYUV: | 398 case IMGFMT_IYUV: |
438 memcpy(ggi_conf.dbuff, src[0], ggi_conf.framePlaneY); | 399 #ifdef GGI_YUV_SUPPORT |
439 ggi_conf.dbuff += ggi_conf.framePlaneY; | |
440 memcpy(ggi_conf.dbuff, src[2], ggi_conf.framePlaneUV); | |
441 ggi_conf.dbuff += ggi_conf.framePlaneUV; | |
442 memcpy(ggi_conf.dbuff, src[1], ggi_conf.framePlaneUV); | |
443 printf("yv12 img written"); | |
444 break; | |
445 default: | |
446 memcpy(ggi_conf.dbuff, src[0], ggi_conf.framePlaneRGB); | |
447 } | |
448 #else | |
449 memcpy(ggi_conf.dbuff, src[0], ggi_conf.framePlaneRGB); | |
450 #endif | |
451 | |
452 if (ggi_conf.need_acquire) | |
453 ggiResourceRelease(ggi_conf.buffer->resource); | |
454 return(0); | |
455 } | |
456 | |
457 #ifdef GGI_OSD | |
458 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, | |
459 unsigned char *srca, int stride) | |
460 { | |
461 switch(ggi_conf.format) | |
462 { | |
463 case IMGFMT_YV12: | |
464 case IMGFMT_I420: | |
465 case IMGFMT_IYUV: | |
466 #ifdef GGI_PLANAR_NOCONV | |
467 vo_draw_alpha_yv12(w, h, src, srca, stride, | 400 vo_draw_alpha_yv12(w, h, src, srca, stride, |
468 ggi_conf.dbuff+(ggi_conf.width*y0+x0), | 401 ggi_conf.buffer[ggi_conf.currframe]->write+(ggi_conf.srcwidth*y0+x0), |
469 ggi_conf.width); | 402 ggi_conf.srcwidth); |
470 #else | 403 #else |
471 switch (vo_depthonscreen) | 404 switch (vo_depthonscreen) |
472 { | 405 { |
473 case 32: | 406 case 32: |
474 vo_draw_alpha_rgb32(w, h, src, srca, stride, | 407 vo_draw_alpha_rgb32(w, h, src, srca, stride, |
475 ggi_conf.dbuff+4*(ggi_conf.width*y0+x0), 4*ggi_conf.width); | 408 ggi_conf.buffer[ggi_conf.currframe]->write+4*(ggi_conf.srcwidth*y0+x0), 4*ggi_conf.srcwidth); |
476 break; | 409 break; |
477 case 24: | 410 case 24: |
478 vo_draw_alpha_rgb24(w, h, src, srca, stride, | 411 vo_draw_alpha_rgb24(w, h, src, srca, stride, |
479 ggi_conf.dbuff+3*(ggi_conf.width*y0+x0), 3*ggi_conf.width); | 412 ggi_conf.buffer[ggi_conf.currframe]->write+3*(ggi_conf.srcwidth*y0+x0), 3*ggi_conf.srcwidth); |
480 break; | 413 break; |
481 case 16: | 414 case 16: |
482 vo_draw_alpha_rgb16(w, h, src, srca, stride, | 415 vo_draw_alpha_rgb16(w, h, src, srca, stride, |
483 ggi_conf.dbuff+2*(ggi_conf.width*y0+x0), 2*ggi_conf.width); | 416 ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0), 2*ggi_conf.srcwidth); |
484 break; | 417 break; |
485 case 15: | 418 case 15: |
486 vo_draw_alpha_rgb15(w, h, src, srca, stride, | 419 vo_draw_alpha_rgb15(w, h, src, srca, stride, |
487 ggi_conf.dbuff+2*(ggi_conf.width*y0+x0), 2*ggi_conf.width); | 420 ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0), 2*ggi_conf.srcwidth); |
488 break; | 421 break; |
489 } | 422 } |
490 #endif | 423 #endif |
491 break; | 424 break; |
492 case IMGFMT_YUY2: | 425 case IMGFMT_YUY2: |
493 case IMGFMT_YVYU: | 426 case IMGFMT_YVYU: |
494 vo_draw_alpha_yuy2(w, h, src, srca, stride, | 427 vo_draw_alpha_yuy2(w, h, src, srca, stride, |
495 ggi_conf.dbuff+2*(ggi_conf.width*y0+x0), | 428 ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0), |
496 2*ggi_conf.width); | 429 2*ggi_conf.srcwidth); |
497 break; | 430 break; |
498 case IMGFMT_UYVY: | 431 case IMGFMT_UYVY: |
499 vo_draw_alpha_yuy2(w, h, src, srca, stride, | 432 vo_draw_alpha_yuy2(w, h, src, srca, stride, |
500 ggi_conf.dbuff+2*(ggi_conf.width*y0+x0)+1, | 433 ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0)+1, |
501 2*ggi_conf.width); | 434 2*ggi_conf.srcwidth); |
502 break; | 435 break; |
503 case IMGFMT_RGB15: | 436 case IMGFMT_RGB15: |
504 case IMGFMT_BGR15: | 437 case IMGFMT_BGR15: |
505 vo_draw_alpha_rgb15(w, h, src, srca, stride, | 438 vo_draw_alpha_rgb15(w, h, src, srca, stride, |
506 ggi_conf.dbuff+2*(ggi_conf.width*y0+x0), 2*ggi_conf.width); | 439 ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0), 2*ggi_conf.srcwidth); |
507 break; | 440 break; |
508 case IMGFMT_RGB16: | 441 case IMGFMT_RGB16: |
509 case IMGFMT_BGR16: | 442 case IMGFMT_BGR16: |
510 vo_draw_alpha_rgb16(w, h, src, srca, stride, | 443 vo_draw_alpha_rgb16(w, h, src, srca, stride, |
511 ggi_conf.dbuff+2*(ggi_conf.width*y0+x0), 2*ggi_conf.width); | 444 ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0), 2*ggi_conf.srcwidth); |
512 break; | 445 break; |
513 case IMGFMT_RGB24: | 446 case IMGFMT_RGB24: |
514 case IMGFMT_BGR24: | 447 case IMGFMT_BGR24: |
515 vo_draw_alpha_rgb24(w, h, src, srca, stride, | 448 vo_draw_alpha_rgb24(w, h, src, srca, stride, |
516 ggi_conf.dbuff+3*(ggi_conf.width*y0+x0), 3*ggi_conf.width); | 449 ggi_conf.buffer[ggi_conf.currframe]->write+3*(ggi_conf.srcwidth*y0+x0), 3*ggi_conf.srcwidth); |
517 break; | 450 break; |
518 case IMGFMT_RGB32: | 451 case IMGFMT_RGB32: |
519 case IMGFMT_BGR32: | 452 case IMGFMT_BGR32: |
520 vo_draw_alpha_rgb32(w, h, src, srca, stride, | 453 vo_draw_alpha_rgb32(w, h, src, srca, stride, |
521 ggi_conf.dbuff+4*(ggi_conf.width*y0+x0), 4*ggi_conf.width); | 454 ggi_conf.buffer[ggi_conf.currframe]->write+4*(ggi_conf.srcwidth*y0+x0), 4*ggi_conf.srcwidth); |
522 break; | 455 break; |
523 } | 456 } |
524 } | 457 } |
525 #endif | |
526 | 458 |
527 static void draw_osd(void) | 459 static void draw_osd(void) |
528 { | 460 { |
529 #ifdef GGI_OSD | 461 vo_draw_text(ggi_conf.srcwidth, ggi_conf.srcheight, draw_alpha); |
530 vo_draw_text(ggi_conf.width, ggi_conf.height, draw_alpha); | |
531 #endif | |
532 } | 462 } |
533 | 463 |
534 static void flip_page(void) | 464 static void flip_page(void) |
535 { | 465 { |
536 ggiFlush(ggi_conf.vis); | 466 ggiSetDisplayFrame(ggi_conf.vis, ggi_conf.currframe); |
467 mp_dbg(MSGT_VO, MSGL_DBG2, "flip_page: current write frame: %d, display frame: %d\n", | |
468 ggiGetWriteFrame(ggi_conf.vis), ggiGetDisplayFrame(ggi_conf.vis)); | |
469 | |
470 ggi_conf.currframe = (ggi_conf.currframe+1) % ggi_conf.frames; | |
537 } | 471 } |
538 | 472 |
539 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, | 473 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, |
540 int x, int y) | 474 int x, int y) |
541 { | 475 { |
542 if (ggi_conf.need_acquire) | 476 ggiResourceAcquire(ggi_conf.buffer[ggi_conf.currframe]->resource, |
543 ggiResourceAcquire(ggi_conf.buffer->resource, GGI_ACTYPE_WRITE); | 477 GGI_ACTYPE_WRITE); |
544 #ifndef GGI_PLANAR_NOCONV | 478 |
545 yuv2rgb(((uint8_t *) ggi_conf.dbuff)+(ggi_conf.width*y+x)*ggi_conf.bppmul, | 479 ggiSetWriteFrame(ggi_conf.vis, ggi_conf.currframe); |
546 src[0], src[1], src[2], w, h, ggi_conf.width*ggi_conf.bppmul, stride[0], | 480 |
547 stride[1]); | 481 #ifndef GGI_YUV_SUPPORT |
482 yuv2rgb(((uint8_t *) ggi_conf.buffer[ggi_conf.currframe]->write)+ | |
483 ggi_conf.buffer[ggi_conf.currframe]->buffer.plb.stride*y+ | |
484 x*(ggi_conf.buffer[ggi_conf.currframe]->buffer.plb.pixelformat->size/8), | |
485 src[0], src[1], src[2], w, h, ggi_conf.buffer[ggi_conf.currframe]->buffer.plb.stride, | |
486 stride[0], stride[1]); | |
548 #else | 487 #else |
549 int i; | 488 int i; |
550 | 489 |
551 ggi_conf.dbuff += (ggi_conf.stridePlaneY * y + x); | 490 ggi_conf.buffer[ggi_conf.currframe]->write += (ggi_conf.stridePlaneY * y + x); |
552 for (i = 0; i < h; i++) | 491 for (i = 0; i < h; i++) |
553 { | 492 { |
554 memcpy(ggi_conf.dbuff, src[0], w); | 493 memcpy(ggi_conf.buffer[ggi_conf.currframe]->write, src[0], w); |
555 src[0] += stride[0]; | 494 src[0] += stride[0]; |
556 ggi_conf.dbuff += ggi_conf.stridePlaneY; | 495 ggi_conf.buffer[ggi_conf.currframe]->write += ggi_conf.stridePlaneY; |
557 } | 496 } |
558 | 497 |
559 x /= 2; | 498 x /= 2; |
560 y /= 2; | 499 y /= 2; |
561 w /= 2; | 500 w /= 2; |
562 h /= 2; | 501 h /= 2; |
563 | 502 |
564 ggi_conf.dbuff += ggi_conf.stridePlaneY + (ggi_conf.stridePlaneUV * y + x); | 503 ggi_conf.buffer[ggi_conf.currframe]->write += ggi_conf.stridePlaneY + (ggi_conf.stridePlaneUV * y + x); |
565 for (i = 0; i < h; i++) | 504 for (i = 0; i < h; i++) |
566 { | 505 { |
567 memcpy(ggi_conf.dbuff, src[1], w); | 506 memcpy(ggi_conf.buffer[ggi_conf.currframe]->write, src[1], w); |
568 src[1] += stride[1]; | 507 src[1] += stride[1]; |
569 ggi_conf.dbuff += ggi_conf.stridePlaneUV; | 508 ggi_conf.buffer[ggi_conf.currframe]->write += ggi_conf.stridePlaneUV; |
570 } | 509 } |
571 #endif | 510 #endif |
572 if (ggi_conf.need_acquire) | 511 |
573 ggiResourceRelease(ggi_conf.buffer->resource); | 512 ggiResourceRelease(ggi_conf.buffer[ggi_conf.currframe]->resource); |
574 return(0); | 513 return(0); |
575 } | 514 } |
576 | 515 |
577 static uint32_t query_format(uint32_t format) | 516 static uint32_t query_format(uint32_t format) |
578 { | 517 { |
598 return(0x5); | 537 return(0x5); |
599 } | 538 } |
600 return(0); | 539 return(0); |
601 } | 540 } |
602 | 541 |
542 static uint32_t preinit(const char *arg) | |
543 { | |
544 if (ggiInit() != 0) | |
545 { | |
546 mp_msg(MSGT_VO, MSGL_FATAL, "[ggi] unable to initialize GGI\n"); | |
547 return(-1); | |
548 } | |
549 | |
550 if (arg) | |
551 ggi_conf.driver = arg; | |
552 else | |
553 ggi_conf.driver = NULL; | |
554 | |
555 if ((ggi_conf.vis = ggiOpen(ggi_conf.driver)) == NULL) | |
556 { | |
557 mp_msg(MSGT_VO, MSGL_FATAL, "[ggi] unable to open '%s' output\n", | |
558 (ggi_conf.driver == NULL) ? "default" : ggi_conf.driver); | |
559 ggiExit(); | |
560 return(-1); | |
561 } | |
562 | |
563 mp_msg(MSGT_VO, MSGL_V, "[ggi] using '%s' output\n", | |
564 (ggi_conf.driver == NULL) ? "default" : ggi_conf.driver); | |
565 | |
566 return 0; | |
567 } | |
568 | |
603 static void uninit(void) | 569 static void uninit(void) |
604 { | 570 { |
605 ggiResourceRelease(ggi_conf.buffer->resource); | |
606 ggiClose(ggi_conf.vis); | 571 ggiClose(ggi_conf.vis); |
607 ggiExit(); | 572 ggiExit(); |
573 } | |
574 | |
575 static uint32_t control(uint32_t request, void *data, ...) | |
576 { | |
577 switch (request) { | |
578 case VOCTRL_QUERY_FORMAT: | |
579 return query_format(*((uint32_t*)data)); | |
580 } | |
581 return VO_NOTIMPL; | |
608 } | 582 } |
609 | 583 |
610 #include "../linux/keycodes.h" | 584 #include "../linux/keycodes.h" |
611 extern void mplayer_put_key(int code); | 585 extern void mplayer_put_key(int code); |
612 | 586 |
617 ggi_event_mask mask; | 591 ggi_event_mask mask; |
618 | 592 |
619 if ((mask = ggiEventPoll(ggi_conf.vis, emAll, &tv))) | 593 if ((mask = ggiEventPoll(ggi_conf.vis, emAll, &tv))) |
620 if (ggiEventRead(ggi_conf.vis, &event, emAll) != 0) | 594 if (ggiEventRead(ggi_conf.vis, &event, emAll) != 0) |
621 { | 595 { |
622 #if 0 /* debug ;) */ | 596 mp_dbg(MSGT_VO, MSGL_DBG3, "type: %4x, origin: %4x, sym: %4x, label: %4x, button=%4x\n", |
623 printf("type: %4x, origin: %4x, sym: %4x, label: %4x, button=%4x\n", | |
624 event.any.origin, event.any.type, event.key.sym, event.key.label, event.key.button); | 597 event.any.origin, event.any.type, event.key.sym, event.key.label, event.key.button); |
625 #endif | |
626 | 598 |
627 if (event.key.type == evKeyPress) | 599 if (event.key.type == evKeyPress) |
628 { | 600 { |
629 #ifdef GII_BUGGY_KEYCODES | |
630 switch(event.key.button) | |
631 { | |
632 case 0x37: | |
633 mplayer_put_key('*'); | |
634 break; | |
635 case 0x68: | |
636 mplayer_put_key('/'); | |
637 break; | |
638 case 0x4e: | |
639 mplayer_put_key('+'); | |
640 break; | |
641 case 0x4a: | |
642 mplayer_put_key('-'); | |
643 break; | |
644 case 0x18: /* o */ | |
645 mplayer_put_key('o'); | |
646 break; | |
647 case 0x22: /* g */ | |
648 mplayer_put_key('g'); | |
649 break; | |
650 case 0x15: /* z */ | |
651 mplayer_put_key('z'); | |
652 break; | |
653 case 0x2d: /* x */ | |
654 mplayer_put_key('x'); | |
655 break; | |
656 case 0x32: /* m */ | |
657 mplayer_put_key('m'); | |
658 break; | |
659 case 0x20: /* d */ | |
660 mplayer_put_key('d'); | |
661 break; | |
662 case 0x10: /* q */ | |
663 mplayer_put_key('q'); | |
664 break; | |
665 case 0x39: /* space */ | |
666 case 0x19: /* p */ | |
667 mplayer_put_key('p'); | |
668 break; | |
669 case 0x5a: | |
670 mplayer_put_key(KEY_UP); | |
671 break; | |
672 case 0x60: | |
673 mplayer_put_key(KEY_DOWN); | |
674 break; | |
675 case 0x5c: | |
676 mplayer_put_key(KEY_LEFT); | |
677 break; | |
678 case 0x5e: | |
679 mplayer_put_key(KEY_RIGHT); | |
680 break; | |
681 case 0x5b: | |
682 mplayer_put_key(KEY_PAGE_UP); | |
683 break; | |
684 case 0x61: | |
685 mplayer_put_key(KEY_PAGE_DOWN); | |
686 break; | |
687 default: | |
688 break; | |
689 } | |
690 #else | |
691 switch(event.key.sym) | 601 switch(event.key.sym) |
692 { | 602 { |
693 case GIIK_PAsterisk: /* PStar */ | 603 case GIIK_PAsterisk: /* PStar */ |
694 case GIIUC_Asterisk: | 604 case GIIUC_Asterisk: |
695 mplayer_put_key('*'); | 605 mplayer_put_key('*'); |
732 break; | 642 break; |
733 case GIIUC_q: | 643 case GIIUC_q: |
734 case GIIUC_Q: | 644 case GIIUC_Q: |
735 mplayer_put_key('q'); | 645 mplayer_put_key('q'); |
736 break; | 646 break; |
647 case GIIUC_h: | |
648 case GIIUC_H: | |
649 mplayer_put_key('h'); | |
650 break; | |
651 case GIIUC_l: | |
652 case GIIUC_L: | |
653 mplayer_put_key('l'); | |
654 break; | |
737 case GIIUC_Space: | 655 case GIIUC_Space: |
738 case GIIUC_p: | 656 case GIIUC_p: |
739 case GIIUC_P: | 657 case GIIUC_P: |
740 mplayer_put_key('p'); | 658 mplayer_put_key('p'); |
741 break; | 659 break; |
758 mplayer_put_key(KEY_PAGE_DOWN); | 676 mplayer_put_key(KEY_PAGE_DOWN); |
759 break; | 677 break; |
760 default: | 678 default: |
761 break; | 679 break; |
762 } | 680 } |
763 #endif | |
764 } | 681 } |
765 } | 682 } |
766 return; | 683 return; |
767 } | 684 } |
768 | |
769 static uint32_t preinit(const char *arg) | |
770 { | |
771 if(arg) | |
772 { | |
773 printf("vo_ggi: Unknown subdevice: %s\n",arg); | |
774 return ENOSYS; | |
775 } | |
776 return 0; | |
777 } | |
778 | |
779 static uint32_t control(uint32_t request, void *data, ...) | |
780 { | |
781 switch (request) { | |
782 case VOCTRL_QUERY_FORMAT: | |
783 return query_format(*((uint32_t*)data)); | |
784 } | |
785 return VO_NOTIMPL; | |
786 } |