Mercurial > mplayer.hg
comparison libvo/vo_directfb.c @ 3275:38344371432f
vo DirectFB support by Jiri Svoboda <Jiri.Svoboda@seznam.cz>
author | arpi |
---|---|
date | Mon, 03 Dec 2001 01:09:36 +0000 |
parents | |
children | 7e0eeb649420 |
comparison
equal
deleted
inserted
replaced
3274:ac7ded58b6df | 3275:38344371432f |
---|---|
1 /* | |
2 * Video driver for DirectFramebuffer device | |
3 * | |
4 * vo_directfb.c (C) Jiri Svoboda <Jiri.Svoboda@seznam.cz> 2001 | |
5 * | |
6 * Inspired by vo_fbdev vo_sdl and directfb examples * | |
7 * To get second head working delete line 120 | |
8 * from fbdev.c (from DirectFB sources version 0.9.7) | |
9 * Line contains following: | |
10 * fbdev->fd = open( "/dev/fb0", O_RDWR ); | |
11 */ | |
12 | |
13 | |
14 // directfb includes | |
15 | |
16 #include <directfb.h> | |
17 | |
18 // other things | |
19 | |
20 #include <stdio.h> | |
21 #include <stdlib.h> | |
22 #include <string.h> | |
23 #include <fcntl.h> | |
24 #include <unistd.h> | |
25 #include <errno.h> | |
26 #include <ctype.h> | |
27 #include <assert.h> | |
28 | |
29 #include <sys/mman.h> | |
30 #include <sys/ioctl.h> | |
31 #include <sys/kd.h> | |
32 #include <linux/fb.h> | |
33 | |
34 #include "config.h" | |
35 #include "video_out.h" | |
36 #include "video_out_internal.h" | |
37 #include "fastmemcpy.h" | |
38 #include "sub.h" | |
39 #include "../postproc/rgb2rgb.h" | |
40 | |
41 LIBVO_EXTERN(directfb) | |
42 | |
43 static vo_info_t vo_info = { | |
44 "Direct Framebuffer Device", | |
45 "directfb", | |
46 "Jiri Svoboda Jiri.Svoboda@seznam.cz", | |
47 "" | |
48 }; | |
49 | |
50 extern int verbose; | |
51 | |
52 /****************************** | |
53 * directfb * | |
54 ******************************/ | |
55 | |
56 /* | |
57 * (Globals) | |
58 */ | |
59 static IDirectFB *dfb = NULL; | |
60 static IDirectFBSurface *primary = NULL; | |
61 static IDirectFBInputDevice *keyboard = NULL; | |
62 static IDirectFBDisplayLayer *videolayer = NULL; | |
63 static DFBDisplayLayerConfig dlc; | |
64 static int screen_width = 0; | |
65 static int screen_height = 0; | |
66 static DFBSurfacePixelFormat frame_format; | |
67 static unsigned int frame_pixel_size = 0; | |
68 static unsigned int source_pixel_size = 0; | |
69 static int xoffset=0,yoffset=0; | |
70 #define DFBCHECK(x...) \ | |
71 { \ | |
72 DFBResult err = x; \ | |
73 \ | |
74 if (err != DFB_OK) \ | |
75 { \ | |
76 fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ | |
77 DirectFBErrorFatal( #x, err ); \ | |
78 } \ | |
79 } | |
80 | |
81 /* | |
82 * The frame is to be loaded into a surface that we can blit from. | |
83 */ | |
84 | |
85 static IDirectFBSurface *frame = NULL; | |
86 | |
87 /* | |
88 * A buffer for input events. | |
89 */ | |
90 static IDirectFBInputBuffer *buffer = NULL; | |
91 | |
92 /****************************** | |
93 * vo_directfb * | |
94 ******************************/ | |
95 | |
96 /* command line/config file options */ | |
97 #ifdef HAVE_FBDEV | |
98 extern char *fb_dev_name; | |
99 #else | |
100 char *fb_dev_name; | |
101 #endif | |
102 | |
103 static void (*draw_alpha_p)(int w, int h, unsigned char *src, | |
104 unsigned char *srca, int stride, unsigned char *dst, | |
105 int dstride); | |
106 | |
107 static int in_width; | |
108 static int in_height; | |
109 static int out_width; | |
110 static int out_height; | |
111 static uint32_t pixel_format; | |
112 static int fs; | |
113 static int flip; | |
114 static int stretch=0; | |
115 struct modes_t { | |
116 int valid; | |
117 unsigned int width; | |
118 unsigned int height; | |
119 int overx,overy; | |
120 } modes [4]; | |
121 static unsigned int best_bpp=5; | |
122 static unsigned int preinit_done=0; | |
123 static int no_yuy2=1; | |
124 | |
125 | |
126 DFBEnumerationResult enum_modes_callback( unsigned int width,unsigned int height,unsigned int bpp, void *data) | |
127 { | |
128 int overx=0,overy=0; | |
129 unsigned int index=bpp/8-1; | |
130 int allow_under=0; | |
131 | |
132 //printf("Validator entered %i %i %i\n",width,height,bpp); | |
133 | |
134 overx=width-out_width; | |
135 overy=height-out_height; | |
136 if (!modes[index].valid) { | |
137 modes[index].valid=1; | |
138 modes[index].width=width; | |
139 modes[index].height=height; | |
140 modes[index].overx=overx; | |
141 modes[index].overy=overy; | |
142 } | |
143 if ((modes[index].overy<0)||(modes[index].overx<0)) allow_under=1; | |
144 if (abs(overx*overy)<abs(modes[index].overx * modes[index].overy)) { | |
145 if (((overx>=0)&&(overy>=0)) || allow_under) { | |
146 modes[index].valid=1; | |
147 modes[index].width=width; | |
148 modes[index].height=height; | |
149 modes[index].overx=overx; | |
150 modes[index].overy=overy; | |
151 // printf("Better mode added %i %i %i\n",width,height,bpp); | |
152 }; | |
153 }; | |
154 | |
155 return DFENUM_OK; | |
156 } | |
157 | |
158 | |
159 DFBEnumerationResult enum_layers_callback( unsigned int id, | |
160 DFBDisplayLayerCapabilities caps, | |
161 void *data ) | |
162 { | |
163 IDirectFBDisplayLayer **layer = (IDirectFBDisplayLayer **)data; | |
164 /* | |
165 printf( "\nLayer %d:\n", id ); | |
166 | |
167 if (caps & DLCAPS_SURFACE) | |
168 printf( " - Has a surface.\n" ); | |
169 | |
170 if (caps & DLCAPS_ALPHACHANNEL) | |
171 printf( " - Supports blending based on alpha channel.\n" ); | |
172 | |
173 if (caps & DLCAPS_COLORKEYING) | |
174 printf( " - Supports color keying.\n" ); | |
175 | |
176 if (caps & DLCAPS_FLICKER_FILTERING) | |
177 printf( " - Supports flicker filtering.\n" ); | |
178 | |
179 if (caps & DLCAPS_INTERLACED_VIDEO) | |
180 printf( " - Can natively display interlaced video.\n" ); | |
181 | |
182 if (caps & DLCAPS_OPACITY) | |
183 printf( " - Supports blending based on global alpha factor.\n" ); | |
184 | |
185 if (caps & DLCAPS_SCREEN_LOCATION) | |
186 printf( " - Can be positioned on the screen.\n" ); | |
187 | |
188 if (caps & DLCAPS_BRIGHTNESS) | |
189 printf( " - Brightness can be adjusted.\n" ); | |
190 | |
191 if (caps & DLCAPS_CONTRAST) | |
192 printf( " - Contrast can be adjusted.\n" ); | |
193 | |
194 if (caps & DLCAPS_HUE) | |
195 printf( " - Hue can be adjusted.\n" ); | |
196 | |
197 if (caps & DLCAPS_SATURATION) | |
198 printf( " - Saturation can be adjusted.\n" ); | |
199 | |
200 printf("\n"); | |
201 */ | |
202 /* We take the first layer not being the primary */ | |
203 if (id != DLID_PRIMARY) { | |
204 DFBResult ret; | |
205 | |
206 ret = dfb->GetDisplayLayer( dfb, id, layer ); | |
207 if (ret) | |
208 DirectFBError( "dfb->GetDisplayLayer failed", ret ); | |
209 else | |
210 return DFENUM_CANCEL; | |
211 } | |
212 | |
213 return DFENUM_OK; | |
214 } | |
215 | |
216 static uint32_t preinit() | |
217 { | |
218 DFBSurfaceDescription dsc; | |
219 DFBResult ret; | |
220 DFBDisplayLayerConfigFlags failed; | |
221 | |
222 | |
223 if (preinit_done) return 1; | |
224 | |
225 /* | |
226 * (Initialize) | |
227 */ | |
228 | |
229 // if (!dfb) { | |
230 | |
231 DFBCHECK (DirectFBInit (NULL,NULL)); | |
232 | |
233 if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER"))) fb_dev_name = "/dev/fb0"; | |
234 DFBCHECK (DirectFBSetOption ("fbdev",fb_dev_name)); | |
235 | |
236 DFBCHECK (DirectFBCreate (&dfb)); | |
237 DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN)); | |
238 | |
239 // lets try to get YUY2 layer - borrowed from DirectFb examples | |
240 | |
241 /* Enumerate display layers */ | |
242 DFBCHECK (dfb->EnumDisplayLayers( dfb, enum_layers_callback, &videolayer )); | |
243 | |
244 if (!videolayer) { | |
245 // no yuy2 layer -> fallback to RGB | |
246 // printf( "\nNo additional layers have been found.\n" ); | |
247 no_yuy2 = 1; | |
248 // preinit_done = 1; | |
249 } else { | |
250 | |
251 // there is an additional layer so test it for YUV | |
252 dlc.flags = /*DLCONF_WIDTH | DLCONF_HEIGHT | */DLCONF_PIXELFORMAT; //| DLCONF_OPTIONS; | |
253 /* dlc.width = dsc.width; | |
254 dlc.height = dsc.height;*/ | |
255 dlc.pixelformat = DSPF_YUY2; | |
256 // dlc.options = DLOP_INTERLACED_VIDEO; | |
257 | |
258 /* Test the configuration, getting failed fields */ | |
259 ret = videolayer->TestConfiguration( videolayer, &dlc, &failed ); | |
260 if (ret == DFB_UNSUPPORTED) { | |
261 // printf("Videolayer does not support YUY2"); | |
262 dlc.pixelformat = DSPF_UYVY; | |
263 ret = videolayer->TestConfiguration( videolayer, &dlc, &failed ); | |
264 if (ret != DFB_UNSUPPORTED) { no_yuy2 = 0;} | |
265 } else { no_yuy2 = 0;} | |
266 } | |
267 | |
268 | |
269 // just look at RGB things | |
270 modes[0].valid=0; | |
271 modes[1].valid=0; | |
272 modes[2].valid=0; | |
273 modes[3].valid=0; | |
274 DFBCHECK (dfb->EnumVideoModes(dfb,enum_modes_callback,NULL)); | |
275 // printf("No YUY2 %i\n",no_yuy2); | |
276 // } | |
277 preinit_done=1; | |
278 return 1; | |
279 | |
280 } | |
281 | |
282 | |
283 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, | |
284 uint32_t d_height, uint32_t fullscreen, char *title, | |
285 uint32_t format) | |
286 { | |
287 /* | |
288 * (Locals) | |
289 */ | |
290 DFBSurfaceDescription dsc; | |
291 DFBResult ret; | |
292 | |
293 | |
294 int vm = fullscreen & 0x02; | |
295 int zoom = fullscreen & 0x04; | |
296 | |
297 fs = fullscreen & 0x01; | |
298 flip = fullscreen & 0x08; | |
299 | |
300 pixel_format=format; | |
301 | |
302 in_width = width; | |
303 in_height = height; | |
304 | |
305 if (d_width) { | |
306 out_width = d_width; | |
307 out_height = d_height; | |
308 } else { | |
309 d_width = out_width = width; | |
310 d_height = out_height = height; | |
311 } | |
312 | |
313 | |
314 if (!preinit()) return 1; | |
315 | |
316 | |
317 if (vm) { | |
318 // need better algorithm just hack | |
319 if (modes[source_pixel_size-1].valid) dfb->SetVideoMode(dfb,modes[source_pixel_size-1].width,modes[source_pixel_size-1].height,source_pixel_size); | |
320 } | |
321 | |
322 | |
323 if (!no_yuy2) { | |
324 // try to set proper w a h values matching image size | |
325 dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT;// | DLCONF_OPTIONS; | |
326 dlc.width = in_width; | |
327 dlc.height = in_height; | |
328 | |
329 ret = videolayer->SetConfiguration( videolayer, &dlc ); | |
330 | |
331 /* if (ret) { | |
332 printf("Set layer size failed\n"); | |
333 }; | |
334 */ | |
335 dlc.flags = DLCONF_PIXELFORMAT;// | DLCONF_OPTIONS; | |
336 //dlc.pixelformat = DSPF_YUY2; should be set by preinit | |
337 //dlc.options = (vcaps & DVCAPS_INTERLACED) ? DLOP_INTERLACED_VIDEO : 0; | |
338 no_yuy2=1; | |
339 /* switch (dlc.pixelformat) { | |
340 case DSPF_ARGB: printf("Directfb frame format ARGB\n"); | |
341 frame_pixel_size = 4; | |
342 break; | |
343 case DSPF_RGB32: printf("Directfb frame format RGB32\n"); | |
344 frame_pixel_size = 4; | |
345 break; | |
346 case DSPF_RGB24: printf("Directfb frame format RGB24\n"); | |
347 frame_pixel_size = 3; | |
348 break; | |
349 case DSPF_RGB16: printf("Directfb frame format RGB16\n"); | |
350 frame_pixel_size = 2; | |
351 break; | |
352 case DSPF_RGB15: printf("Directfb frame format RGB15\n"); | |
353 frame_pixel_size = 2; | |
354 break; | |
355 case DSPF_YUY2: printf("Directfb frame format YUY2\n"); | |
356 frame_pixel_size = 2; | |
357 break; | |
358 case DSPF_UYVY: printf("Directfb frame format UYVY\n"); | |
359 frame_pixel_size = 2; | |
360 break; | |
361 default: printf("Directfb - unknown format ->exit\n"); return 1; | |
362 } | |
363 */ ret =videolayer->SetConfiguration( videolayer, &dlc ); | |
364 if (!ret) { | |
365 // printf("SetConfiguration for layer OK\n"); | |
366 ret = videolayer->GetSurface( videolayer, &primary ); | |
367 if (!ret){ | |
368 no_yuy2=0; | |
369 // printf("Get surface for layer OK\n"); | |
370 /* dsc.width=in_width; | |
371 dsc.height=in_height; | |
372 dsc.flags = DSDESC_CAPS | DSDESC_HEIGHT | DSDESC_WIDTH; | |
373 dsc.caps = DSCAPS_VIDEOONLY;//| DSCAPS_FLIPPING; | |
374 primary->SetConfiguration(priamry,&dsc);*/ | |
375 }; | |
376 }; | |
377 | |
378 } | |
379 | |
380 // mam pro flip pouzit tenhle flip nebo bitblt | |
381 dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT; | |
382 dsc.caps = DSCAPS_PRIMARY | DSCAPS_VIDEOONLY;//| DSCAPS_FLIPPING; | |
383 | |
384 switch (format) { | |
385 case IMGFMT_RGB32: dsc.pixelformat = DSPF_ARGB; source_pixel_size= 4; break; | |
386 case IMGFMT_BGR32: dsc.pixelformat = DSPF_ARGB; source_pixel_size= 4; break; | |
387 case IMGFMT_RGB24: dsc.pixelformat = DSPF_RGB24; source_pixel_size= 3; break; | |
388 case IMGFMT_BGR24: dsc.pixelformat = DSPF_RGB24; source_pixel_size= 3; break; | |
389 case IMGFMT_RGB16: dsc.pixelformat = DSPF_RGB16; source_pixel_size= 2; break; | |
390 case IMGFMT_BGR16: dsc.pixelformat = DSPF_RGB16; source_pixel_size= 2; break; | |
391 case IMGFMT_RGB15: dsc.pixelformat = DSPF_RGB15; source_pixel_size= 2; break; | |
392 case IMGFMT_BGR15: dsc.pixelformat = DSPF_RGB15; source_pixel_size= 2; break; | |
393 default: dsc.pixelformat = DSPF_RGB24; source_pixel_size=2; break; //YUV formats | |
394 }; | |
395 | |
396 | |
397 | |
398 if (no_yuy2) { | |
399 DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary )); | |
400 } | |
401 else {// try to set pos for YUY2 layer and proper aspect ratio | |
402 | |
403 // Does not work - needs to be checked - problem of directfb ->disabled | |
404 | |
405 // float h=in_height,w=in_width; | |
406 float h=(float)out_height/(float)in_height,w=(float)out_width/(float)in_width; | |
407 float aspect=h/w; | |
408 printf("in out d: %d %d, %d %d, %d %d\n",in_width,in_height,out_width,out_height,d_width,d_height); | |
409 printf ("Aspect y/x=%f/%f=%f\n",h,w,aspect); | |
410 | |
411 // if (fs) { | |
412 // scale fullscreen | |
413 if (aspect>1) { | |
414 aspect=w/h; | |
415 ret = videolayer->SetScreenLocation(videolayer,(1-aspect)/2,0,aspect,1); | |
416 } else { | |
417 ret = videolayer->SetScreenLocation(videolayer,0,(1-aspect)/2,1,aspect); | |
418 } | |
419 // } else { | |
420 // beacase I can't get real screen size values I can't scale properly in other way then fullscreen | |
421 // }; | |
422 // if (ret) printf("SetScreenLocation failed\n"); | |
423 } | |
424 | |
425 DFBCHECK (primary->GetSize (primary, &screen_width, &screen_height)); | |
426 | |
427 DFBCHECK (primary->GetPixelFormat (primary, &frame_format)); | |
428 | |
429 // temporary buffer buffer | |
430 dsc.flags = DSDESC_CAPS | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_WIDTH; | |
431 dsc.caps = DSCAPS_SYSTEMONLY; | |
432 | |
433 dsc.width = in_width; | |
434 dsc.height = in_height; | |
435 | |
436 // at this time use pixel req format or format of main disp | |
437 /* | |
438 switch (frame_format) { | |
439 case DSPF_ARGB: printf("Directfb frame format ARGB\n"); | |
440 break; | |
441 case DSPF_RGB32: printf("Directfb frame format RGB32\n"); | |
442 break; | |
443 case DSPF_RGB24: printf("Directfb frame format RGB24\n"); | |
444 break; | |
445 case DSPF_RGB16: printf("Directfb frame format RGB16\n"); | |
446 break; | |
447 case DSPF_RGB15: printf("Directfb frame format RGB15\n"); | |
448 break; | |
449 case DSPF_YUY2: printf("Directfb frame format YUY2\n"); | |
450 break; | |
451 default: printf("Directfb - unknown format ->exit\n"); return 1; | |
452 } | |
453 */ | |
454 | |
455 switch (format) { | |
456 case IMGFMT_RGB32: dsc.pixelformat = DSPF_ARGB; break; | |
457 case IMGFMT_BGR32: dsc.pixelformat = DSPF_ARGB; break; | |
458 case IMGFMT_RGB24: dsc.pixelformat = DSPF_RGB24; break; | |
459 case IMGFMT_BGR24: dsc.pixelformat = DSPF_RGB24; break; | |
460 case IMGFMT_RGB16: dsc.pixelformat = DSPF_RGB16; break; | |
461 case IMGFMT_BGR16: dsc.pixelformat = DSPF_RGB16; break; | |
462 case IMGFMT_RGB15: dsc.pixelformat = DSPF_RGB15; break; | |
463 case IMGFMT_BGR15: dsc.pixelformat = DSPF_RGB15; break; | |
464 default: dsc.pixelformat = frame_format; break; // uknown or YUV -> retain layer format eg. RGB or YUY2 | |
465 }; | |
466 | |
467 | |
468 /* | |
469 * Create a surface based on the description of the source frame | |
470 */ | |
471 DFBCHECK (dfb->CreateSurface( dfb, &dsc, &frame)); | |
472 | |
473 DFBCHECK (frame->GetPixelFormat (frame, &frame_format)); | |
474 | |
475 switch (frame_format) { | |
476 case DSPF_ARGB: //printf("Directfb frame format ARGB\n"); | |
477 frame_pixel_size = 4; | |
478 break; | |
479 case DSPF_RGB32: //printf("Directfb frame format RGB32\n"); | |
480 frame_pixel_size = 4; | |
481 break; | |
482 case DSPF_RGB24: //printf("Directfb frame format RGB24\n"); | |
483 frame_pixel_size = 3; | |
484 break; | |
485 case DSPF_RGB16: //printf("Directfb frame format RGB16\n"); | |
486 frame_pixel_size = 2; | |
487 break; | |
488 case DSPF_RGB15: //printf("Directfb frame format RGB15\n"); | |
489 frame_pixel_size = 2; | |
490 break; | |
491 case DSPF_YUY2: //printf("Directfb frame format YUY2\n"); | |
492 frame_pixel_size = 2; | |
493 break; | |
494 case DSPF_UYVY: //printf("Directfb frame format UYVY\n"); | |
495 frame_pixel_size = 2; | |
496 break; | |
497 default: printf("Directfb - unknown format ->exit\n"); return 1; | |
498 } | |
499 | |
500 | |
501 if (zoom) { | |
502 printf("-zoom is not yet supported\n"); | |
503 // return 1; | |
504 } | |
505 /* | |
506 if (fs) { | |
507 printf("-fs can degrade image and performance\n"); | |
508 // return 1; | |
509 } | |
510 */ | |
511 if ((out_width < in_width || out_height < in_height) && (!fs)) { | |
512 printf("Screensize is smaller than video size !\n"); | |
513 // return 1; // doesn't matter we will | |
514 } | |
515 | |
516 if ((fs) && (no_yuy2)) { | |
517 // aspect ratio correction for fullscreen | |
518 out_height=d_height*screen_width/d_width; | |
519 if (out_height <= screen_height) {out_width=screen_width;} else {out_width=screen_width*screen_height/d_height; out_height=screen_height;}; | |
520 // printf("Going fullscreen !\n"); | |
521 } | |
522 | |
523 | |
524 /* | |
525 * (Get keyboard) | |
526 */ | |
527 DFBCHECK (dfb->GetInputDevice (dfb, DIDID_KEYBOARD, &keyboard)); | |
528 | |
529 /* | |
530 * Create an input buffer for the keyboard. | |
531 */ | |
532 DFBCHECK (keyboard->CreateInputBuffer (keyboard, &buffer)); | |
533 | |
534 // clear the screen | |
535 | |
536 /* DFBCHECK (primary->FillRectangle (primary, 0, 0, screen_width, screen_height)); | |
537 printf( | |
538 "Screen cleared\n"); */ | |
539 // yuv2rgb transform init | |
540 | |
541 if (((format == IMGFMT_YV12) || (format == IMGFMT_YUY2)) && no_yuy2){ yuv2rgb_init(frame_pixel_size * 8,MODE_RGB);}; | |
542 | |
543 if (((out_width != in_width) || (out_height != in_height)) && (no_yuy2)) {stretch = 1;} else stretch=0; //yuy doesn't like strech and should not be needed | |
544 | |
545 if (no_yuy2) { | |
546 xoffset = (screen_width - out_width) / 2; | |
547 yoffset = (screen_height - out_height) / 2; | |
548 } else { | |
549 xoffset = 0; | |
550 yoffset = 0; | |
551 } | |
552 // printf("in out d: %d %d, %d %d, %d %d\n",in_width,in_height,out_width,out_height,d_width,d_height); | |
553 | |
554 return 0; | |
555 } | |
556 | |
557 static uint32_t query_format(uint32_t format) | |
558 { | |
559 int ret = 0x4; /* osd/sub is supported on every bpp */ | |
560 | |
561 preinit(); | |
562 | |
563 // printf("Format query: %s\n",vo_format_name(format)); | |
564 switch (format) { | |
565 | |
566 // RGB mode works only if color depth is same as on screen and this driver doesn't know before init | |
567 // so we couldn't report supported formats well | |
568 | |
569 // Just support those detected by preinit | |
570 case IMGFMT_RGB32: | |
571 case IMGFMT_BGR32: if (modes[3].valid) return ret|0x2; | |
572 break; | |
573 case IMGFMT_RGB24: | |
574 case IMGFMT_BGR24: if (modes[2].valid) return ret|0x2; | |
575 break; | |
576 case IMGFMT_RGB16: | |
577 case IMGFMT_BGR16: | |
578 case IMGFMT_RGB15: | |
579 case IMGFMT_BGR15: if (modes[1].valid) return ret|0x2; | |
580 break; | |
581 case IMGFMT_YUY2: if (!no_yuy2) return ret|0x2; | |
582 break; | |
583 case IMGFMT_YV12: if (!no_yuy2) return ret|0x2; else return ret|0x1; | |
584 break; | |
585 // YV12 should work in all cases | |
586 } | |
587 | |
588 return 0; | |
589 } | |
590 | |
591 static const vo_info_t *get_info(void) | |
592 { | |
593 return &vo_info; | |
594 } | |
595 | |
596 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, | |
597 unsigned char *srca, int stride) | |
598 { | |
599 void *dst; | |
600 int pitch; | |
601 int len; | |
602 | |
603 DFBCHECK (frame->Lock(frame,DSLF_WRITE,&dst,&pitch)); | |
604 | |
605 switch(frame_format) { | |
606 case DSPF_RGB32: | |
607 case DSPF_ARGB: | |
608 vo_draw_alpha_rgb32(w,h,src,srca,stride,((uint8_t *) dst)+pitch*y0 + frame_pixel_size*x0,pitch); | |
609 break; | |
610 | |
611 case DSPF_RGB24: | |
612 vo_draw_alpha_rgb24(w,h,src,srca,stride,((uint8_t *) dst)+pitch*y0 + frame_pixel_size*x0,pitch); | |
613 break; | |
614 | |
615 case DSPF_RGB16: | |
616 vo_draw_alpha_rgb16(w,h,src,srca,stride,((uint8_t *) dst)+pitch*y0 + frame_pixel_size*x0,pitch); | |
617 break; | |
618 | |
619 case DSPF_RGB15: | |
620 vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) dst)+pitch*y0 + frame_pixel_size*x0,pitch); | |
621 break; | |
622 | |
623 // hopefully correct - couldn't test | |
624 | |
625 case DSPF_YUY2: | |
626 vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) dst) + pitch*y0 + frame_pixel_size*x0,pitch); | |
627 break; | |
628 case DSPF_UYVY: | |
629 vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) dst) + pitch*y0 + frame_pixel_size*x0 + 1,pitch); | |
630 break; | |
631 } | |
632 DFBCHECK (frame->Unlock(frame)); | |
633 } | |
634 | |
635 static uint32_t draw_frame(uint8_t *src[]) | |
636 { | |
637 void *dst; | |
638 int pitch; | |
639 int len; | |
640 | |
641 DFBCHECK (frame->Lock(frame,DSLF_WRITE,&dst,&pitch)); | |
642 | |
643 switch (frame_format) { | |
644 case DSPF_ARGB: | |
645 case DSPF_RGB32: | |
646 case DSPF_RGB24: | |
647 case DSPF_RGB16: | |
648 case DSPF_RGB15:switch (pixel_format) { | |
649 case IMGFMT_YV12: | |
650 yuv2rgb(dst,src[0],src[1],src[2],in_width,in_height,pitch,in_width,in_width/2); | |
651 break; | |
652 /* how to handle this? need conversion from YUY2 to RGB*/ | |
653 /* case IMGFMT_YUY2: | |
654 yuv2rgb(dst,src[0],src[0]+1,src[0]+3,1,in_height*in_width/2,frame_pixel_size*2,4,4); //odd pixels | |
655 yuv2rgb(dst+1,src[0]+2,src[0]+1,src[0]+3,1,in_height*in_width/2,frame_pixel_size*2,4,4); //even pixels | |
656 break;*/ | |
657 // RGB - just copy | |
658 default: if (source_pixel_size==frame_pixel_size) {memcpy(dst,src[0],in_width * in_height * frame_pixel_size);}; | |
659 | |
660 } | |
661 break; | |
662 case DSPF_YUY2: | |
663 switch (pixel_format) { | |
664 case IMGFMT_YV12: yv12toyuy2(src[0],src[1],src[2],dst,in_width,in_height,in_width,in_width >>1,pitch); | |
665 break; | |
666 case IMGFMT_YUY2: { | |
667 int i; | |
668 for (i=0;i<in_height;i++) { | |
669 memcpy(dst+i*pitch,src[0]+i*in_width*2,in_width*2); | |
670 } | |
671 } | |
672 /*len = in_width * in_height * pitch; | |
673 memcpy(dst,src[0],len);*/ | |
674 break; | |
675 // hopefully there will be no RGB in this case otherwise convert - not implemented | |
676 } | |
677 break; | |
678 } | |
679 DFBCHECK (frame->Unlock(frame)); | |
680 return 0; | |
681 } | |
682 | |
683 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y) | |
684 { | |
685 | |
686 int err; | |
687 void *dst; | |
688 uint8_t *s; | |
689 int pitch; | |
690 int i; | |
691 | |
692 err = frame->Lock(frame,DSLF_WRITE,&dst,&pitch); | |
693 | |
694 // printf("Drawslice\n"); | |
695 | |
696 switch (frame_format) { | |
697 case DSPF_ARGB: | |
698 case DSPF_RGB32: | |
699 case DSPF_RGB24: | |
700 case DSPF_RGB16: | |
701 case DSPF_RGB15: | |
702 switch (pixel_format) { | |
703 case IMGFMT_YV12: | |
704 yuv2rgb(dst+ y * pitch + frame_pixel_size*x ,src[0],src[1],src[2],w,h,pitch,stride[0],stride[1]); | |
705 break; | |
706 // how to handle this? need conversion | |
707 /* case IMGFMT_YUY2: { | |
708 int i; | |
709 for (i=0;i<=h;i++) { | |
710 yuv2rgb(dst+ (i+y) * pitch + frame_pixel_size*x,src[0]+i*stride[0],src[0]+1+i*stride[0],src[0]+3+i*stride[0],1,(w+1)/2,frame_pixel_size*2,4,4); //odd pixels | |
711 yuv2rgb(dst+ (i+y) * pitch + frame_pixel_size*x +1,src[0]+i*stride[0]+2,src[0]+1+i*stride[0],src[0]+3+i*stride[0],1,(w)/2,frame_pixel_size*2,4,4); //odd pixels | |
712 }; | |
713 }; | |
714 break; | |
715 */ | |
716 default: if (source_pixel_size==frame_pixel_size) { | |
717 dst += x * frame_pixel_size; | |
718 s = src[0]; | |
719 for (i=y;i<=(y+h);i++) { | |
720 memcpy(dst,s,w); | |
721 dst += (pitch); | |
722 s += stride[0]; | |
723 }; | |
724 } | |
725 break; | |
726 | |
727 } | |
728 break; | |
729 case DSPF_YUY2: | |
730 switch (pixel_format) { | |
731 case IMGFMT_YV12: yv12toyuy2(src[0],src[1],src[2],dst + pitch*y + frame_pixel_size*x ,w,h,stride[0],stride[1],pitch); | |
732 break; | |
733 case IMGFMT_YUY2: { | |
734 dst += x * frame_pixel_size; | |
735 s = src[0]; | |
736 for (i=y;i<=(y+h);i++) { | |
737 memcpy(dst,s,w); | |
738 dst += (pitch); | |
739 s += stride[0]; | |
740 }; | |
741 }; | |
742 break; | |
743 // hopefully there will be no RGB in this case otherwise convert - not implemented | |
744 } | |
745 break; | |
746 }; | |
747 | |
748 frame->Unlock(frame); | |
749 | |
750 return 0; | |
751 } | |
752 | |
753 extern void mplayer_put_key(int code); | |
754 | |
755 #include "../linux/keycodes.h" | |
756 | |
757 static void check_events(void) | |
758 { | |
759 | |
760 DFBInputEvent event; | |
761 | |
762 if (buffer->GetEvent (buffer, &event) == DFB_OK) { | |
763 if (event.type == DIET_KEYPRESS) { switch (event.keycode) { | |
764 case DIKC_ESCAPE: | |
765 mplayer_put_key('q'); | |
766 break; | |
767 case DIKC_KP_PLUS: mplayer_put_key('+');break; | |
768 case DIKC_KP_MINUS: mplayer_put_key('-');break; | |
769 case DIKC_TAB: mplayer_put_key('\t');break; | |
770 case DIKC_PAGEUP: mplayer_put_key(KEY_PAGE_UP);break; | |
771 case DIKC_PAGEDOWN: mplayer_put_key(KEY_PAGE_DOWN);break; | |
772 case DIKC_UP: mplayer_put_key(KEY_UP);break; | |
773 case DIKC_DOWN: mplayer_put_key(KEY_DOWN);break; | |
774 case DIKC_LEFT: mplayer_put_key(KEY_LEFT);break; | |
775 case DIKC_RIGHT: mplayer_put_key(KEY_RIGHT);break; | |
776 case DIKC_ASTERISK: | |
777 case DIKC_KP_MULT:mplayer_put_key('*');break; | |
778 case DIKC_KP_DIV: mplayer_put_key('/');break; | |
779 | |
780 default:mplayer_put_key(event.key_ascii); | |
781 }; | |
782 }; | |
783 }; | |
784 // empty buffer, because of repeating (keyboard repeat is faster than key handling | |
785 // and this causes problems during seek) | |
786 // temporary workabout should be solved in the future | |
787 | |
788 buffer->Reset(buffer); | |
789 | |
790 } | |
791 | |
792 static void draw_osd(void) | |
793 { | |
794 vo_draw_text(in_width, in_height, draw_alpha); | |
795 } | |
796 | |
797 static void flip_page(void) | |
798 { | |
799 DFBSurfaceBlittingFlags flags=DSBLIT_NOFX; | |
800 | |
801 DFBCHECK (primary->SetBlittingFlags(primary,flags)); | |
802 | |
803 if (stretch) { | |
804 DFBRectangle rect; | |
805 rect.x=xoffset; | |
806 rect.y=yoffset; | |
807 rect.w=out_width; | |
808 rect.h=out_height; | |
809 | |
810 DFBCHECK (primary->StretchBlit(primary,frame,NULL,&rect)); | |
811 } | |
812 else { | |
813 DFBCHECK (primary->Blit(primary,frame,NULL,xoffset,yoffset)); | |
814 }; | |
815 // DFBCHECK (primary->Flip (primary, NULL, DSFLIP_WAITFORSYNC)); | |
816 } | |
817 | |
818 static void uninit(void) | |
819 { | |
820 if (verbose > 0) | |
821 printf("uninit\n"); | |
822 | |
823 /* | |
824 * (Release) | |
825 */ | |
826 // printf("Release buffer\n"); | |
827 buffer->Release (buffer); | |
828 // printf("Release keyb\n"); | |
829 keyboard->Release (keyboard); | |
830 // printf("Release frame\n"); | |
831 frame->Release (frame); | |
832 | |
833 // we will not release dfb and layer because there could be a new film | |
834 | |
835 // printf("Release primary\n"); | |
836 // primary->Release (primary); | |
837 // printf("Release videolayer\n"); | |
838 // if (videolayer) videolayer->Release(videolayer); | |
839 // printf("Release dfb\n"); | |
840 // dfb->Release (dfb); | |
841 // preinit_done=0; | |
842 | |
843 } | |
844 |