comparison libvo/vo_directfb2.c @ 6952:fc505cbab7ce

new directfb driver for 0.9.13+ by jiri.svoboda@seznam.cz
author arpi
date Fri, 09 Aug 2002 17:20:46 +0000
parents
children 6074119e09a0
comparison
equal deleted inserted replaced
6951:0504c8beccba 6952:fc505cbab7ce
1 /*
2 MPlayer video driver for DirectFramebuffer device
3
4 (C) 2002
5
6 Written by Jiri Svoboda <Jiri.Svoboda@seznam.cz>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the
20 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22 */
23
24 // directfb includes
25
26 #include <directfb.h>
27
28 // other things
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <errno.h>
36 #include <ctype.h>
37 #include <assert.h>
38
39 #include <sys/mman.h>
40 #include <sys/ioctl.h>
41 #include <sys/kd.h>
42
43 #include "config.h"
44 #include "video_out.h"
45 #include "video_out_internal.h"
46 #include "fastmemcpy.h"
47 #include "sub.h"
48
49 #include "aspect.h"
50
51 #ifndef min
52 #define min(x,y) (((x)<(y))?(x):(y))
53 #endif
54
55
56 LIBVO_EXTERN(directfb)
57
58 static vo_info_t vo_info = {
59 "Direct Framebuffer Device",
60 "directfb",
61 "Jiri Svoboda Jiri.Svoboda@seznam.cz",
62 "version 2.0beta"
63 };
64
65 extern int verbose;
66
67 /******************************
68 * vo_directfb globals *
69 ******************************/
70
71 #define DFBCHECK(x...) \
72 { \
73 DFBResult err = x; \
74 \
75 if (err != DFB_OK) \
76 { \
77 fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
78 DirectFBErrorFatal( #x, err ); \
79 } \
80 }
81
82 /*
83 * filled by preinit
84 */
85
86 // main DirectFB handle
87 static IDirectFB *dfb = NULL;
88 // keyboard handle
89 static IDirectFBInputDevice *keyboard = NULL;
90 // A buffer for input events.
91 static IDirectFBEventBuffer *buffer = NULL;
92
93 /*
94 * filled during config
95 */
96
97 // handle of used layer
98 static IDirectFBDisplayLayer *layer = NULL;
99 // surface of used layer
100 static IDirectFBSurface *primary = NULL;
101 static int primarylocked = 0;
102 // handle of temporary surface (if used)
103 static IDirectFBSurface *frame = NULL;
104 static int framelocked = 0;
105 // flipping mode flag (layer/surface)
106 static int flipping = 0;
107 // scaling flag
108 static int stretch = 0;
109 // pictrure position
110 static int xoffset=0,yoffset=0;
111 // picture size
112 static int out_width=0,out_height=0;
113 // frame/primary size
114 static int width=0,height=0;
115 // frame primary format
116 DFBSurfacePixelFormat pixel_format;
117 /*
118 static void (*draw_alpha_p)(int w, int h, unsigned char *src,
119 unsigned char *srca, int stride, unsigned char *dst,
120 int dstride);
121 */
122
123 /******************************
124 * cmd line parameteres *
125 ******************************/
126
127 /* command line/config file options */
128 #ifdef HAVE_FBDEV
129 extern char *fb_dev_name;
130 #else
131 char *fb_dev_name;
132 #endif
133
134 /******************************
135 * implementation *
136 ******************************/
137
138 void unlock() {
139 if (frame && framelocked) frame->Unlock(frame);
140 if (primary && primarylocked) primary->Unlock(primary);
141 }
142
143
144 static uint32_t preinit(const char *arg)
145 {
146
147 DFBResult ret;
148
149 if (verbose) printf("DirectFB: Preinit entered\n");
150
151 DFBCHECK (DirectFBInit (NULL,NULL));
152
153 if (((directfb_major_version <= 0) &&
154 (directfb_minor_version <= 9) &&
155 (directfb_micro_version < 13)))
156 {
157 printf("DirectFB: Unsupported DirectFB version\n");
158 return 1;
159 }
160
161 /*
162 * (set options)
163 */
164
165 if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER"))) fb_dev_name = "/dev/fb0";
166 DFBCHECK (DirectFBSetOption ("fbdev",fb_dev_name));
167
168 // uncomment this if you do not wish to create a new vt for DirectFB
169 // DFBCHECK (DirectFBSetOption ("no-vt-switch",""));
170
171 // uncomment this if you want to allow vt switching
172 // DFBCHECK (DirectFBSetOption ("vt-switching",""));
173
174 // uncomment this if you want to hide gfx cursor (req dfb >=0.9.9)
175 DFBCHECK (DirectFBSetOption ("no-cursor",""));
176
177 // bg color fix
178 DFBCHECK (DirectFBSetOption ("bg-color","00000000"));
179
180 /*
181 * (Initialize)
182 */
183
184 DFBCHECK (DirectFBCreate (&dfb));
185 DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
186
187 /*
188 * (Get keyboard)
189 */
190
191 ret = dfb->GetInputDevice (dfb, DIDID_KEYBOARD, &keyboard);
192
193 if (ret==DFB_OK) {
194 if (verbose) {
195 printf("DirectFB: Keyboard init OK\n");
196 }
197 } else {
198 keyboard = NULL;
199 printf("DirectFB: Keyboard init FAILED\n");
200 }
201
202 /*
203 * Create an input buffer for the keyboard.
204 */
205 if (keyboard) DFBCHECK (keyboard->CreateEventBuffer (keyboard, &buffer));
206
207 // just to start with clean ...
208 if (buffer) buffer->Reset(buffer);
209
210 if (verbose) {
211 printf("DirectFB: Preinit OK\n");
212 }
213
214 return 0;
215
216 }
217
218 DFBSurfacePixelFormat convformat(uint32_t format)
219 {
220 // add more formats !!!
221 switch (format) {
222 case IMGFMT_RGB32: return DSPF_RGB32; break;
223 case IMGFMT_BGR32: return DSPF_RGB32; break;
224 case IMGFMT_RGB24: return DSPF_RGB24; break;
225 case IMGFMT_BGR24: return DSPF_RGB24; break;
226 case IMGFMT_RGB16: return DSPF_RGB16; break;
227 case IMGFMT_BGR16: return DSPF_RGB16; break;
228 case IMGFMT_RGB15: return DSPF_RGB15; break;
229 case IMGFMT_BGR15: return DSPF_RGB15; break;
230 case IMGFMT_YUY2: return DSPF_YUY2; break;
231 case IMGFMT_UYVY: return DSPF_UYVY; break;
232 case IMGFMT_YV12: return DSPF_YV12; break;
233 case IMGFMT_I420: return DSPF_I420; break;
234 // case IMGFMT_IYUV: return DSPF_IYUV; break;
235 default: return 0;
236 }
237 return 0;
238 }
239
240 typedef struct enum1_s {
241 uint32_t format;
242 int scale;
243 int result;
244 unsigned int id;
245 unsigned int width;
246 unsigned int height;
247 int setsize;
248 } enum1_t;
249
250 DFBEnumerationResult test_format_callback( unsigned int id,
251 DFBDisplayLayerDescription desc,
252 void *data)
253 {
254 enum1_t *params =(enum1_t *)data;
255 IDirectFBDisplayLayer *layer;
256 DFBResult ret;
257
258 ret = dfb->GetDisplayLayer( dfb, id, &layer);
259 if (ret) {
260 DirectFBError( "dfb->GetDisplayLayer failed", ret );
261 return DFENUM_OK;
262 } else {
263 DFBDisplayLayerConfig dlc;
264
265 if (params->setsize) {
266 dlc.flags = DLCONF_WIDTH |DLCONF_HEIGHT;
267 dlc.width = params->width;
268 dlc.height = params->height;
269 layer->SetConfiguration(layer,&dlc);
270 }
271
272
273 dlc.flags = DLCONF_PIXELFORMAT;
274 dlc.pixelformat = convformat(params->format);
275
276 layer->SetOpacity(layer,0);
277 ret = layer->TestConfiguration(layer,&dlc,NULL);
278
279 layer->Release(layer);
280
281 if (verbose) printf("DirectFB: Test format - layer %i scale/pos %i\n",id,(desc.caps & DLCAPS_SCREEN_LOCATION));
282
283 if (!ret) {
284 // printf("Test OK\n");
285 if (params->result) {
286 if ((!params->scale) && (desc.caps & DLCAPS_SCREEN_LOCATION)) {
287 params->scale=1;
288 params->id=id;
289 if (verbose) printf("DirectFB: Test format - added layer %i scale/pos %i\n",id,(desc.caps & DLCAPS_SCREEN_LOCATION));
290
291 }
292 } else {
293 params->result=1;
294 params->id=id;
295 if (desc.caps & DLCAPS_SCREEN_LOCATION) params->scale=1;
296 if (verbose) printf("DirectFB: Test format - added layer %i scale/pos %i\n",id,(desc.caps & DLCAPS_SCREEN_LOCATION));
297 };
298 };
299 };
300
301 return DFENUM_OK;
302 }
303
304 static uint32_t query_format(uint32_t format)
305 {
306 int ret = VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_OSD; // osd should be removed in future -> will be handled outside...
307 enum1_t params;
308
309
310 if (!convformat(format)) return 0;
311 // temporary disable YV12
312 // if (format == IMGFMT_YV12) return 0;
313 // if (format == IMGFMT_I420) return 0;
314 if (format == IMGFMT_IYUV) return 0;
315
316 if (verbose) printf("DirectFB: Format query: %s\n",vo_format_name(format));
317
318 params.format=format;
319 params.scale=0;
320 params.result=0;
321 params.setsize=0;
322
323 DFBCHECK (dfb->EnumDisplayLayers(dfb,test_format_callback,&params));
324
325 if (params.result) {
326 if (params.scale) ret |=VFCAP_HWSCALE_UP|VFCAP_HWSCALE_DOWN;
327 return ret;
328 }
329
330 return 0;
331 }
332
333 typedef struct videomode_s {
334 int width;
335 int height;
336 int out_width;
337 int out_height;
338 int overx;
339 int overy;
340 int bpp;
341 } videomode_t;
342
343
344 DFBEnumerationResult video_modes_callback( unsigned int width,unsigned int height,unsigned int bpp, void *data)
345 {
346 videomode_t *params =(videomode_t *)data;
347
348 int overx=0,overy=0,closer=0,over=0;
349 int we_are_under=0;
350
351 if (verbose) printf("DirectFB: Validator entered %i %i %i\n",width,height,bpp);
352
353 overx=width-params->out_width;
354 overy=height-params->out_height;
355
356 if (!params->width) {
357 params->width=width;
358 params->height=height;
359 params->overx=overx;
360 params->overy=overy;
361 if (verbose) printf("DirectFB: Mode added %i %i %i\n",width,height,bpp);
362 }
363
364 if ((params->overy<0)||(params->overx<0)) we_are_under=1; // stored mode is smaller than req mode
365 if (abs(overx*overy)<abs(params->overx * params->overy)) closer=1; // current mode is closer to desired res
366 if ((overx>=0)&&(overy>=0)) over=1; // current mode is bigger or equaul to desired res
367 if ((closer && (over || we_are_under)) || (we_are_under && over)) {
368 params->width=width;
369 params->height=height;
370 params->overx=overx;
371 params->overy=overy;
372 if (verbose) printf("DirectFB: Better mode added %i %i %i\n",width,height,bpp);
373 };
374
375 return DFENUM_OK;
376 }
377
378 #define CONFIG_ERROR -1
379
380 static uint32_t config(uint32_t s_width, uint32_t s_height, uint32_t d_width,
381 uint32_t d_height, uint32_t fullscreen, char *title,
382 uint32_t format,const vo_tune_info_t *info)
383 {
384
385 /*
386 1) pokud je vm zmen videomode
387 - HOTOVO
388
389 2) nejprve najit nejvhodnejsi vrstvu - tj. podporujici dany format a zmenu polohy/velikosti
390 ->enum vyplni strukturu: - pokud neni nic tak tam placne prvni co alespon podporuje format
391 - jinak posledni podporujici vse (prepise klidne strukturu nekolikrat)
392 struktura - format + layer + caps
393 - HOTOVO
394
395 3) nakonfigurovat vrstvu (postupne po jedne vlastnosti: - format HOTOVO
396 - velikost obrazu HOTOVO
397 - buffermode HOTOVO
398 - pozici/velikost HOTOVO
399 3) ziskat surface na vrstve - HOTOVO
400 4) pokud je zoom vytvori pomocny buffer
401 5) v pripade potreby zapnout a otestovat flip nebo vytvorit pomocny buffer (pokud jeste neni)
402
403 */
404 /*
405 * (Locals)
406 */
407
408 // decode flags
409
410 int fs = fullscreen & 0x01;
411 int vm = fullscreen & 0x02;
412 int zoom = fullscreen & 0x04;
413 int flip = fullscreen & 0x08;
414
415 DFBSurfaceDescription dsc;
416 DFBResult ret;
417 DFBDisplayLayerConfig dlc;
418 DFBSurfaceCapabilities caps;
419
420 enum1_t params;
421
422 if (verbose) {
423 printf("DirectFB: Config entered [%ix%i]\n",s_width,s_height);
424 printf("DirectFB: With requested format: %s\n",vo_format_name(format));
425 }
426 // initial clean-up
427 if (frame) {
428 frame->Release(frame);
429 frame=NULL;
430 }
431
432 if (primary) {
433 primary->Release(primary);
434 primary=NULL;
435 }
436
437 if (layer) {
438 layer->Release(layer);
439 layer=NULL;
440 }
441
442
443 // vm things
444
445 if (vm) {
446 videomode_t params;
447 params.out_width=d_width;
448 params.out_height=d_height;
449 params.width=0;
450 params.height=0;
451 switch (format) {
452 case IMGFMT_RGB32:
453 case IMGFMT_BGR32:
454 params.bpp=32;
455 break;
456 case IMGFMT_RGB24:
457 case IMGFMT_BGR24:
458 params.bpp=24;
459 break;
460 case IMGFMT_RGB16:
461 case IMGFMT_BGR16:
462 case IMGFMT_RGB15:
463 case IMGFMT_BGR15:
464 params.bpp=16;
465 break;
466 default: params.bpp=0;
467
468 }
469 if (verbose) printf("DirectFB: Config - videomode change\n");
470 DFBCHECK (dfb->EnumVideoModes(dfb,video_modes_callback,&params));
471 ret=dfb->SetVideoMode(dfb,params.width,params.height,params.bpp);
472 if (ret) {
473 ret=dfb->SetVideoMode(dfb,params.width,params.height,24);
474 if (ret) {
475 ret=dfb->SetVideoMode(dfb,params.width,params.height,32);
476 if (ret) {
477 ret=dfb->SetVideoMode(dfb,params.width,params.height,16);
478 if (ret) {
479 ret=dfb->SetVideoMode(dfb,params.width,params.height,8);
480 }
481 }
482 }
483 }
484 } // vm end
485
486 // find best layer
487
488 if (verbose) printf("DirectFB: Config - find suitable layer\n");
489 params.format=format;
490 params.scale=0;
491 params.result=0;
492 params.width=s_width;
493 params.height=s_height;
494 params.setsize=1;
495
496 DFBCHECK (dfb->EnumDisplayLayers(dfb,test_format_callback,&params));
497
498 if (!params.result) {
499 printf("DirectFB: ConfigError - no suitable layer found\n");
500 params.id = DLID_PRIMARY;
501 }
502
503 if (verbose) printf("DirectFB: Config - layer %i\n",params.id);
504
505
506 // try to setp-up proper configuration
507
508
509 DFBCHECK (dfb->GetDisplayLayer( dfb, params.id, &layer));
510
511 if (params.scale) {
512 if (verbose) printf("DirectFB: Config - set layer config (size)\n");
513 dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT;
514 dlc.width = s_width;
515 dlc.height = s_height;
516
517 ret = layer->SetConfiguration(layer,&dlc);
518
519 if (ret && (params.scale || verbose)) printf("DirectFB: ConfigError in layer configuration (size)\n");
520
521 }
522
523 dlc.flags = DLCONF_PIXELFORMAT;
524 dlc.pixelformat = convformat(params.format);
525
526 // printf("DirectFB: Format [%x]\n",dlc.pixelformat);
527
528 if (verbose) printf("DirectFB: Config - set layer config (format)\n");
529 ret = layer->SetConfiguration(layer,&dlc);
530
531 if (ret) {
532 printf("DirectFB: ConfigError in layer configuration (format)\n");
533 return CONFIG_ERROR;
534 };
535
536
537 // flipping of layer
538
539 dlc.flags = DLCONF_BUFFERMODE;
540 dlc.buffermode = DLBM_BACKVIDEO;
541 ret = layer->SetConfiguration( layer, &dlc );
542 if (ret!=DFB_OK) {
543 dlc.buffermode = DLBM_BACKSYSTEM;
544 ret = layer->SetConfiguration( layer, &dlc );
545 /* if (ret==DFB_OK) {
546 // nastav vse pro flip
547 flipping = 1;
548 }
549 } else {
550 // nastav vse pro flip
551 flipping = 1;
552 */ }
553
554 // get layer surface
555
556 ret = layer->GetSurface(layer,&primary);
557
558 if (ret) {
559 printf("DirectFB: ConfigError in obtaining surface\n");
560 return CONFIG_ERROR; // what shall we report on fail?
561 }
562
563 // test surface for flipping
564 DFBCHECK(primary->GetCapabilities(primary,&caps));
565
566 flipping = 0;
567 if (caps & DSCAPS_FLIPPING) {
568 ret = primary->Flip(primary,NULL,0);
569 if (ret==DFB_OK) {
570 flipping = 1;
571 }
572 };
573
574 if (verbose) printf("DirectFB: Config - flipping = %i\n",flipping);
575
576 // is scale needed ? Aspect ratio and layer pos/size
577
578
579 // get surface size
580 DFBCHECK(primary->GetSize(primary,&width,&height));
581
582 if (verbose) printf("DirectFB: Config - surface size = %ix%i\n",width,height);
583
584 aspect_save_orig(s_width,s_height);
585 aspect_save_prescale(d_width,d_height);
586 if (params.scale) {
587 aspect_save_screenres(10000,10000);
588 aspect(&out_width,&out_height,A_ZOOM);
589
590 ret = layer->SetScreenLocation(layer,(1-(float)out_width/10000)/2,(1-(float)out_height/10000)/2,((float)out_width/10000),((float)out_height/10000));
591
592 if (ret) printf("DirectFB: ConfigError in layer configuration (position)\n");
593
594 xoffset = 0;
595 yoffset = 0;
596
597 } else {
598
599 aspect_save_screenres(width,height);
600
601 if(fs) /* -fs */
602 aspect(&out_width,&out_height,A_ZOOM);
603 else
604 aspect(&out_width,&out_height,A_NOZOOM);
605
606
607 xoffset = (width - out_width) / 2;
608 yoffset = (height - out_height) / 2;
609 }
610
611 if (((s_width==out_width)&&(s_height==out_height)) || (params.scale)) {
612 stretch = 0;
613 } else {
614 stretch = 1;
615 }
616
617
618 // temporary buffer in case of not flipping or scaling
619 if ((!flipping) || stretch) {
620
621 DFBCHECK (primary->GetPixelFormat (primary, &dsc.pixelformat));
622
623 dsc.flags = DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_WIDTH;
624
625 dsc.width = s_width;
626 dsc.height = s_height;
627
628 DFBCHECK (dfb->CreateSurface( dfb, &dsc, &frame));
629 DFBCHECK(frame->GetSize(frame,&width,&height));
630
631 }
632
633 // get format for draw_alpha - should be removed soon - osd will be rendered outside vo driver
634 if (frame) {
635 DFBCHECK (frame->GetPixelFormat(frame,&pixel_format));
636 } else {
637 DFBCHECK (primary->GetPixelFormat(primary,&pixel_format));
638 };
639
640 // finally turn on layer
641 layer->SetOpacity(layer,255);
642
643 if (verbose) printf("DirectFB: Config finished [%ix%i] - [%ix%i]\n",out_width,out_height,width,height);
644
645 return 0;
646 }
647
648 static const vo_info_t *get_info(void)
649 {
650 return &vo_info;
651 }
652
653 extern void mplayer_put_key(int code);
654
655 #include "../linux/keycodes.h"
656
657 static void check_events(void)
658 {
659
660 if (buffer) {
661
662 DFBInputEvent event;
663
664 //if (verbose) printf ("DirectFB: Check events entered\n");
665 if (buffer->GetEvent(buffer, DFB_EVENT (&event)) == DFB_OK) {
666
667 if (event.type == DIET_KEYPRESS) {
668 switch (event.key_symbol) {
669 case DIKS_ESCAPE:
670 mplayer_put_key('q');
671 break;
672 case DIKS_PAGE_UP: mplayer_put_key(KEY_PAGE_UP);break;
673 case DIKS_PAGE_DOWN: mplayer_put_key(KEY_PAGE_DOWN);break;
674 case DIKS_CURSOR_UP: mplayer_put_key(KEY_UP);break;
675 case DIKS_CURSOR_DOWN: mplayer_put_key(KEY_DOWN);break;
676 case DIKS_CURSOR_LEFT: mplayer_put_key(KEY_LEFT);break;
677 case DIKS_CURSOR_RIGHT: mplayer_put_key(KEY_RIGHT);break;
678 case DIKS_INSERT: mplayer_put_key(KEY_INSERT);break;
679 case DIKS_DELETE: mplayer_put_key(KEY_DELETE);break;
680 case DIKS_HOME: mplayer_put_key(KEY_HOME);break;
681 case DIKS_END: mplayer_put_key(KEY_END);break;
682
683 default:mplayer_put_key(event.key_symbol);
684 };
685 };
686 };
687 // empty buffer, because of repeating (keyboard repeat is faster than key handling
688 // and this causes problems during seek)
689 // temporary workabout should be solved in the future
690 buffer->Reset(buffer);
691
692 }
693 //if (verbose) printf ("DirectFB: Check events finished\n");
694 }
695
696 static void flip_page(void)
697 {
698 DFBSurfaceBlittingFlags flags=DSBLIT_NOFX;
699
700 unlock(); // unlock frame & primary
701
702 // if (verbose) printf("DirectFB: Flip page entered");
703
704 DFBCHECK (primary->SetBlittingFlags(primary,flags));
705
706 // tady jsete pridat odemknuti frame a primary v pripade potreby
707
708 if (frame) {
709 if (stretch) {
710 DFBRectangle rect;
711 rect.x=xoffset;
712 rect.y=yoffset;
713 rect.w=out_width;
714 rect.h=out_height;
715
716 DFBCHECK (primary->StretchBlit(primary,frame,NULL,&rect));
717
718 } else {
719
720 DFBCHECK (primary->Blit(primary,frame,NULL,xoffset,yoffset));
721
722 };
723 };
724
725
726 if (flipping) {
727 DFBCHECK (primary->Flip (primary, NULL, DSFLIP_WAITFORSYNC));
728 }
729
730 }
731
732
733
734 static void uninit(void)
735 {
736
737 if (verbose ) printf("DirectFB: Uninit entered\n");
738
739 unlock();
740
741 /*
742 * (Release)
743 */
744 if (verbose ) printf("DirectFB: Release buffer\n");
745 if (buffer) buffer->Release (buffer);
746 if (verbose ) printf("DirectFB: Release keyboard\n");
747 if (keyboard) keyboard->Release (keyboard);
748 if (frame) {
749 if (verbose ) printf("DirectFB: Release frame\n");
750 frame->Release (frame);
751 };
752
753 if (verbose ) printf("DirectFB: Release primary\n");
754 if (primary) primary->Release (primary);
755
756 // switch off BES
757 // if (layer) layer->SetOpacity(layer,0);
758
759 if (layer) layer->Release(layer);
760
761 if (verbose ) printf("DirectFB: Release DirectFB library\n");
762
763 dfb->Release (dfb);
764
765 if (verbose ) printf("DirectFB: Uninit done.\n");
766 }
767
768
769 static uint32_t directfb_set_video_eq(char *data, int value) //data==name
770 {
771
772 DFBColorAdjustment ca;
773 float factor = (float)0xffff / 200.0;
774
775 DFBDisplayLayerDescription desc;
776
777 unlock();
778
779 if (layer) {
780
781 layer->GetDescription(layer,&desc);
782
783 ca.flags=DCAF_NONE;
784
785 if (! strcmp( data,"brightness" )) {
786 if (desc.caps & DLCAPS_BRIGHTNESS) {
787 ca.brightness = value * factor +0x8000;
788 ca.flags |= DCAF_BRIGHTNESS;
789 if (verbose) printf("DirectFB: SetVEq Brightness 0x%X %i\n",ca.brightness,value);
790 } else return VO_FALSE;
791 }
792
793 if (! strcmp( data,"contrast" )) {
794 if ((desc.caps & DLCAPS_CONTRAST)) {
795 ca.contrast = value * factor + 0x8000;
796 ca.flags |= DCAF_CONTRAST;
797 if (verbose) printf("DirectFB: SetVEq Contrast 0x%X %i\n",ca.contrast,value);
798 } else return VO_FALSE;
799 }
800
801 if (! strcmp( data,"hue" )) {
802 if ((desc.caps & DLCAPS_HUE)) {
803 ca.hue = value * factor + 0x8000;
804 ca.flags |= DCAF_HUE;
805 if (verbose) printf("DirectFB: SetVEq Hue 0x%X %i\n",ca.hue,value);
806 } else return VO_FALSE;
807 }
808
809 if (! strcmp( data,"saturation" )) {
810 if ((desc.caps & DLCAPS_SATURATION)) {
811 ca.saturation = value * factor + 0x8000;
812 ca.flags |= DCAF_SATURATION;
813 if (verbose) printf("DirectFB: SetVEq Saturation 0x%X %i\n",ca.saturation,value);
814 } else return VO_FALSE;
815 }
816
817 if (ca.flags != DCAF_NONE) {
818 layer->SetColorAdjustment(layer,&ca);
819 return VO_TRUE;
820 }
821 }
822
823 return VO_FALSE;
824
825 }
826
827 static uint32_t directfb_get_video_eq(char *data, int *value) // data==name
828 {
829
830 DFBColorAdjustment ca;
831 float factor = 200.0 / (float)0xffff;
832
833 DFBDisplayLayerDescription desc;
834
835 if (layer) {
836
837 unlock();
838
839 layer->GetDescription(layer,&desc);
840
841 layer->GetColorAdjustment(layer,&ca);
842
843 if (! strcmp( data,"brightness" )) {
844 if (desc.caps & DLCAPS_BRIGHTNESS) {
845 *value = (int) ((ca.brightness-0x8000) * factor);
846 if (verbose) printf("DirectFB: GetVEq Brightness 0x%X %i\n",ca.brightness,*value);
847 return VO_TRUE;
848 } else return VO_FALSE;
849 }
850
851 if (! strcmp( data,"contrast" )) {
852 if ((desc.caps & DLCAPS_CONTRAST)) {
853 *value = (int) ((ca.contrast-0x8000) * factor);
854 if (verbose) printf("DirectFB: GetVEq Contrast 0x%X %i\n",ca.contrast,*value);
855 return VO_TRUE;
856 } else return VO_FALSE;
857 }
858
859 if (! strcmp( data,"hue" )) {
860 if ((desc.caps & DLCAPS_HUE)) {
861 *value = (int) ((ca.hue-0x8000) * factor);
862 if (verbose) printf("DirectFB: GetVEq Hue 0x%X %i\n",ca.hue,*value);
863 return VO_TRUE;
864 } else return VO_FALSE;
865 }
866
867 if (! strcmp( data,"saturation" )) {
868 if ((desc.caps & DLCAPS_SATURATION)) {
869 *value = (int) ((ca.saturation-0x8000) * factor);
870 if (verbose) printf("DirectFB: GetVEq Saturation 0x%X %i\n",ca.saturation,*value);
871 return VO_TRUE;
872 } else return VO_FALSE;
873 }
874 }
875 return VO_FALSE;
876 }
877
878 static uint32_t get_image(mp_image_t *mpi)
879 {
880
881 int err;
882 void *dst;
883 int pitch;
884
885 // if (verbose) printf("DirectFB: get_image() called\n");
886
887 // tohle overit - mozna pokud mam frame pak by to nemuselo byt
888 if(mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE; // slow video ram
889 if(mpi->type==MP_IMGTYPE_STATIC) return VO_FALSE; // it is not static
890
891 // printf("width=%d vs. pitch=%d, flags=0x%X \n",mpi->width,pitch,mpi->flags);
892
893 if((mpi->width==width) ||
894 (mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH))){
895 // we're lucky or codec accepts stride => ok, let's go!
896
897 if (frame) {
898 err = frame->Lock(frame,DSLF_WRITE,&dst,&pitch);
899 framelocked=1;
900 } else {
901 err = primary->Lock(primary,DSLF_WRITE,&dst,&pitch);
902 primarylocked=1;
903 }
904
905 if (err) {
906 if (verbose) printf("DirectFB: DR lock failed!");
907 return VO_FALSE;
908 };
909
910 if(mpi->flags&MP_IMGFLAG_PLANAR){
911 //YV12 format
912 mpi->planes[0]=dst;
913 if(mpi->flags&MP_IMGFLAG_SWAPPED){
914 mpi->planes[1]=dst + pitch*height;
915 mpi->planes[2]=mpi->planes[1] + pitch*height/4;
916 } else {
917 mpi->planes[2]=dst + pitch*height;
918 mpi->planes[1]=mpi->planes[2] + pitch*height/4;
919 }
920 mpi->width= mpi->stride[0]=pitch;
921 mpi->stride[1]=mpi->stride[2]=pitch/2;
922 } else {
923 //YUY2 and RGB formats
924 mpi->planes[0]=dst;
925 mpi->width=width;
926 mpi->stride[0]=pitch;
927 }
928 mpi->flags|=MP_IMGFLAG_DIRECT;
929 // if (verbose) printf("DirectFB: get_image() SUCCESS -> Direct Rendering ENABLED\n");
930 return VO_TRUE;
931
932 }
933 return VO_FALSE;
934 }
935
936 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
937 {
938 int i;
939 unsigned int pitch;
940 void *dst;
941 void *dst2;
942 void *srcp;
943 unsigned int p;
944
945 unlock();
946
947 if (frame) {
948 DFBCHECK (frame->Lock(frame,DSLF_WRITE,&dst,&pitch));
949 framelocked = 1;
950 } else {
951 DFBCHECK (primary->Lock(primary,DSLF_WRITE,&dst,&pitch));
952 primarylocked = 1;
953 };
954
955 p=min(w,pitch);
956
957 dst += y*pitch + x;
958 dst2 = dst + pitch*height - y*pitch + y*pitch/4 - x/2;
959 srcp = src[0];
960
961 for (i=0;i<h;i++) {
962 memcpy(dst,srcp,p);
963 dst += pitch;
964 srcp += stride[0];
965 }
966
967 if (pixel_format == DSPF_YV12) {
968
969 dst = dst2;
970 srcp = src[2];
971 p = p/2;
972
973 for (i=0;i<h/2;i++) {
974 memcpy(dst,srcp,p);
975 dst += pitch/2;
976 srcp += stride[2];
977 }
978
979 dst = dst2 + pitch*height/4;
980 srcp = src[1];
981
982 for (i=0;i<h/2;i++) {
983 memcpy(dst,srcp,p);
984 dst += pitch/2;
985 srcp += stride[1];
986 }
987
988 } else {
989
990 dst = dst2;
991 srcp = src[1];
992 p = p/2;
993
994 for (i=0;i<h/2;i++) {
995 memcpy(dst,srcp,p);
996 dst += pitch/2;
997 srcp += stride[1];
998 }
999
1000 dst = dst2 + pitch*height/4;
1001 srcp = src[2];
1002
1003 for (i=0;i<h/2;i++) {
1004 memcpy(dst,srcp,p);
1005 dst += pitch/2;
1006 srcp += stride[2];
1007 }
1008
1009 }
1010
1011 unlock();
1012
1013 return 0;
1014 }
1015
1016
1017 static uint32_t put_image(mp_image_t *mpi){
1018
1019
1020 static IDirectFBSurface *tmp = NULL;
1021 DFBSurfaceDescription dsc;
1022 DFBRectangle rect;
1023
1024 // if (verbose) printf("DirectFB: Put_image entered %i %i %i %i %i %i\n",mpi->x,mpi->y,mpi->w,mpi->h,mpi->width,mpi->height);
1025
1026 unlock();
1027
1028 // already out?
1029 if((mpi->flags&(MP_IMGFLAG_DIRECT))) {
1030 // if (verbose) printf("DirectFB: Put_image - nothing todo\n");
1031 return VO_TRUE;
1032 }
1033
1034 //|MP_IMGFLAG_DRAW_CALLBACK
1035
1036 if (mpi->flags&MP_IMGFLAG_PLANAR) {
1037 // memcpy all planes - sad but necessary
1038 int i;
1039 unsigned int pitch;
1040 void *dst;
1041 void *src;
1042 unsigned int p;
1043
1044 // if (verbose) printf("DirectFB: Put_image - planar branch\n");
1045 if (frame) {
1046 DFBCHECK (frame->Lock(frame,DSLF_WRITE,&dst,&pitch));
1047 framelocked = 1;
1048 } else {
1049 DFBCHECK (primary->Lock(primary,DSLF_WRITE,&dst,&pitch));
1050 primarylocked = 1;
1051 };
1052
1053 p=min(mpi->w,pitch);
1054
1055 src = mpi->planes[0]+mpi->y*mpi->stride[0]+mpi->x;
1056
1057 for (i=0;i<mpi->h;i++) {
1058 memcpy(dst+i*pitch,src+i*mpi->stride[0],p);
1059 }
1060
1061 if (pixel_format == DSPF_YV12) {
1062
1063 dst += pitch*height;
1064 p = p/2;
1065 src = mpi->planes[2]+mpi->y*mpi->stride[2]+mpi->x/2;
1066
1067 for (i=0;i<mpi->h/2;i++) {
1068 memcpy(dst+i*pitch/2,src+i*mpi->stride[2],p);
1069 }
1070
1071 dst += pitch*height/4;
1072 src = mpi->planes[1]+mpi->y*mpi->stride[1]+mpi->x/2;
1073
1074 for (i=0;i<mpi->h/2;i++) {
1075 memcpy(dst+i*pitch/2,src+i*mpi->stride[1],p);
1076 }
1077
1078 } else {
1079
1080 dst += pitch*height;
1081 p = p/2;
1082 src = mpi->planes[1]+mpi->y*mpi->stride[1]+mpi->x/2;
1083
1084 for (i=0;i<mpi->h/2;i++) {
1085 memcpy(dst+i*pitch/2,src+i*mpi->stride[1],p);
1086 }
1087
1088 dst += pitch*height/4;
1089 src = mpi->planes[2]+mpi->y*mpi->stride[2]+mpi->x/2;
1090
1091 for (i=0;i<mpi->h/2;i++) {
1092 memcpy(dst+i*pitch/2,src+i*mpi->stride[2],p);
1093 }
1094
1095 }
1096 unlock();
1097
1098 } else {
1099
1100 dsc.flags = DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_WIDTH | DSDESC_PREALLOCATED;
1101 dsc.preallocated[0].data = mpi->planes[0];
1102 dsc.preallocated[0].pitch = mpi->stride[0];
1103 dsc.width = mpi->width;
1104 dsc.height = mpi->height;
1105 dsc.pixelformat = convformat(mpi->imgfmt);
1106
1107 DFBCHECK (dfb->CreateSurface( dfb, &dsc, &tmp));
1108
1109 rect.x=mpi->x;
1110 rect.y=mpi->y;
1111 rect.w=mpi->w;
1112 rect.h=mpi->h;
1113
1114 if (frame) {
1115 DFBCHECK (tmp->Blit(tmp,frame,&rect,0,0));
1116 } else {
1117 DFBCHECK (tmp->Blit(tmp,primary,&rect,xoffset,yoffset));
1118 };
1119 tmp->Release(tmp);
1120 }
1121 return VO_TRUE;
1122 }
1123
1124
1125
1126 static uint32_t control(uint32_t request, void *data, ...)
1127 {
1128 switch (request) {
1129 case VOCTRL_QUERY_FORMAT:
1130 return query_format(*((uint32_t*)data));
1131 case VOCTRL_GET_IMAGE:
1132 return get_image(data);
1133 case VOCTRL_DRAW_IMAGE:
1134 return put_image(data);
1135 case VOCTRL_SET_EQUALIZER:
1136 {
1137 va_list ap;
1138 int value;
1139
1140 va_start(ap, data);
1141 value = va_arg(ap, int);
1142 va_end(ap);
1143
1144 return(directfb_set_video_eq(data, value));
1145 }
1146 case VOCTRL_GET_EQUALIZER:
1147 {
1148 va_list ap;
1149 int *value;
1150
1151 va_start(ap, data);
1152 value = va_arg(ap, int*);
1153 va_end(ap);
1154
1155 return(directfb_get_video_eq(data, value));
1156 }
1157 };
1158 return VO_NOTIMPL;
1159 }
1160
1161 // unused function
1162
1163 static uint32_t draw_frame(uint8_t *src[])
1164 {
1165 return -1;
1166 }
1167
1168 // hopefully will be removed soon
1169
1170 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
1171 unsigned char *srca, int stride)
1172 {
1173 void *dst;
1174 int pitch;
1175
1176 unlock(); // isnt it silly I have to unlock surface and than lock again :-)
1177
1178 if (frame) {
1179 DFBCHECK (frame->Lock(frame,DSLF_WRITE,&dst,&pitch));
1180 framelocked = 1;
1181 } else {
1182 DFBCHECK (primary->Lock(primary,DSLF_WRITE,&dst,&pitch));
1183 primarylocked = 1;
1184 };
1185
1186 switch(pixel_format) {
1187 case DSPF_RGB32:
1188 case DSPF_ARGB:
1189 vo_draw_alpha_rgb32(w,h,src,srca,stride,((uint8_t *) dst)+pitch*y0 + 4*x0,pitch);
1190 break;
1191
1192 case DSPF_RGB24:
1193 vo_draw_alpha_rgb24(w,h,src,srca,stride,((uint8_t *) dst)+pitch*y0 + 3*x0,pitch);
1194 break;
1195
1196 case DSPF_RGB16:
1197 vo_draw_alpha_rgb16(w,h,src,srca,stride,((uint8_t *) dst)+pitch*y0 + 2*x0,pitch);
1198 break;
1199
1200 case DSPF_RGB15:
1201 vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) dst)+pitch*y0 + 2*x0,pitch);
1202 break;
1203
1204 case DSPF_YUY2:
1205 vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) dst) + pitch*y0 + 2*x0,pitch);
1206 break;
1207
1208 case DSPF_UYVY:
1209 vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) dst) + pitch*y0 + 2*x0 + 1,pitch);
1210 break;
1211
1212 case DSPF_I420:
1213 case DSPF_YV12:
1214 vo_draw_alpha_yv12(w,h,src,srca,stride,((uint8_t *) dst) + pitch*y0 + 1*x0,pitch);
1215 break;
1216 }
1217
1218 unlock();
1219 }
1220
1221 static void draw_osd(void)
1222 {
1223 vo_draw_text(width,height,draw_alpha);
1224 }