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 }