comparison libvo/vo_dfbmga.c @ 9979:a4ea0311ade2

spring update patch by Ville Syrjala <syrjala@sci.fi>
author alex
date Thu, 24 Apr 2003 18:52:16 +0000
parents 17cf28e5846a
children 59e7beccdee0
comparison
equal deleted inserted replaced
9978:11cee15b1a8f 9979:a4ea0311ade2
66 static int current_buf; 66 static int current_buf;
67 static int current_ip_buf; 67 static int current_ip_buf;
68 static IDirectFBSurface *bufs[3]; 68 static IDirectFBSurface *bufs[3];
69 69
70 static IDirectFBSurface *frame; 70 static IDirectFBSurface *frame;
71 static IDirectFBSurface *besframe;
71 static IDirectFBSurface *c2frame; 72 static IDirectFBSurface *c2frame;
72 static IDirectFBSurface *subframe; 73 static IDirectFBSurface *subframe;
73 74
74 static DFBSurfacePixelFormat frame_format; 75 static DFBSurfacePixelFormat frame_format;
75 static DFBSurfacePixelFormat subframe_format; 76 static DFBSurfacePixelFormat subframe_format;
76 77
77 static DFBRectangle drect; 78 static DFBRectangle drect;
78 79
79 static IDirectFBInputDevice *keyboard; 80 static IDirectFBInputDevice *keyboard;
80 static IDirectFBEventBuffer *buffer; 81 static IDirectFBEventBuffer *buffer;
81
82 static unsigned int frame_pixel_size;
83 static unsigned int subframe_pixel_size;
84 82
85 static int inited = 0; 83 static int inited = 0;
86 84
87 static int blit_done; 85 static int blit_done;
88 static int stretch; 86 static int stretch;
90 static int use_bes; 88 static int use_bes;
91 static int use_crtc2; 89 static int use_crtc2;
92 static int use_spic; 90 static int use_spic;
93 static int use_input; 91 static int use_input;
94 static int field_parity; 92 static int field_parity;
93 static int flipping;
94 static DFBDisplayLayerBufferMode buffermode;
95 95
96 static int osd_changed; 96 static int osd_changed;
97 static int osd_dirty; 97 static int osd_dirty;
98 static int osd_current; 98 static int osd_current;
99 static int osd_max;
99 100
100 /****************************** 101 /******************************
101 * vo_directfb * 102 * vo_dfbmga *
102 ******************************/ 103 ******************************/
104
105 #if DIRECTFBVERSION < 918
106 #define DSPF_ALUT44 DSPF_LUT8
107 #define DLBM_TRIPLE ~0
108 #define DSFLIP_ONSYNC 0
109 #endif
110
111 #if DIRECTFBVERSION < 916
112 #define DSPF_ARGB1555 DSPF_RGB15
113 #endif
103 114
104 /* command line/config file options */ 115 /* command line/config file options */
105 #ifdef HAVE_FBDEV 116 #ifdef HAVE_FBDEV
106 extern char *fb_dev_name; 117 extern char *fb_dev_name;
107 #else 118 #else
125 return "RGB32"; 136 return "RGB32";
126 case DSPF_RGB24: 137 case DSPF_RGB24:
127 return "RGB24"; 138 return "RGB24";
128 case DSPF_RGB16: 139 case DSPF_RGB16:
129 return "RGB16"; 140 return "RGB16";
130 #if DIRECTFBVERSION > 915
131 case DSPF_ARGB1555: 141 case DSPF_ARGB1555:
132 return "ARGB1555"; 142 return "ARGB1555";
133 #else
134 case DSPF_RGB15:
135 return "RGB15";
136 #endif
137 case DSPF_YUY2: 143 case DSPF_YUY2:
138 return "YUY2"; 144 return "YUY2";
139 case DSPF_UYVY: 145 case DSPF_UYVY:
140 return "UYVY"; 146 return "UYVY";
141 case DSPF_YV12: 147 case DSPF_YV12:
142 return "YV12"; 148 return "YV12";
143 case DSPF_I420: 149 case DSPF_I420:
144 return "I420"; 150 return "I420";
145 case DSPF_LUT8: 151 case DSPF_ALUT44:
146 return "LUT8"; 152 return "ALUT44";
147 default: 153 default:
148 return "Unknown pixel format"; 154 return "Unknown pixel format";
149 } 155 }
150 } 156 }
151 157
162 case IMGFMT_RGB16: 168 case IMGFMT_RGB16:
163 case IMGFMT_BGR16: 169 case IMGFMT_BGR16:
164 return DSPF_RGB16; 170 return DSPF_RGB16;
165 case IMGFMT_RGB15: 171 case IMGFMT_RGB15:
166 case IMGFMT_BGR15: 172 case IMGFMT_BGR15:
167 #if DIRECTFBVERSION > 915
168 return DSPF_ARGB1555; 173 return DSPF_ARGB1555;
169 #else
170 return DSPF_RGB15;
171 #endif
172 case IMGFMT_YUY2: 174 case IMGFMT_YUY2:
173 return DSPF_YUY2; 175 return DSPF_YUY2;
174 case IMGFMT_UYVY: 176 case IMGFMT_UYVY:
175 return DSPF_UYVY; 177 return DSPF_UYVY;
176 case IMGFMT_YV12: 178 case IMGFMT_YV12:
217 static uint32_t 219 static uint32_t
218 preinit( const char *arg ) 220 preinit( const char *arg )
219 { 221 {
220 DFBResult res; 222 DFBResult res;
221 223
224 bes = NULL;
225 crtc2 = NULL;
226 keyboard = NULL;
227 buffer = NULL;
228
222 /* Some defaults */ 229 /* Some defaults */
223 use_bes = 0; 230 use_bes = 0;
224 use_crtc2 = 1; 231 use_crtc2 = 1;
225 use_spic = 1; 232 use_spic = 1;
226 use_input = 1;
227 field_parity = -1; 233 field_parity = -1;
234 #if DIRECTFBVERSION > 917
235 buffermode = DLBM_TRIPLE;
236 osd_max = 4;
237 #else
238 buffermode = DLBM_BACKVIDEO;
239 osd_max = 2;
240 #endif
241 flipping = 1;
242
243 use_input = !getenv( "DISPLAY" );
228 244
229 if (vo_subdevice) { 245 if (vo_subdevice) {
246 int show_help = 0;
230 int opt_no = 0; 247 int opt_no = 0;
231 while (*vo_subdevice != '\0') { 248 while (*vo_subdevice != '\0') {
232 if (!strncmp(vo_subdevice, "bes", 3)) { 249 if (!strncmp(vo_subdevice, "bes", 3)) {
233 use_bes = !opt_no; 250 use_bes = !opt_no;
234 vo_subdevice += 3; 251 vo_subdevice += 3;
240 } else if (!strncmp(vo_subdevice, "spic", 4)) { 257 } else if (!strncmp(vo_subdevice, "spic", 4)) {
241 use_spic = !opt_no; 258 use_spic = !opt_no;
242 vo_subdevice += 4; 259 vo_subdevice += 4;
243 opt_no = 0; 260 opt_no = 0;
244 } else if (!strncmp(vo_subdevice, "input", 5)) { 261 } else if (!strncmp(vo_subdevice, "input", 5)) {
245 use_spic = !opt_no; 262 use_input = !opt_no;
246 vo_subdevice += 5; 263 vo_subdevice += 5;
247 opt_no = 0; 264 opt_no = 0;
265 } else if (!strncmp(vo_subdevice, "buffermode=", 11)) {
266 if (opt_no) {
267 show_help = 1;
268 break;
269 }
270 vo_subdevice += 11;
271 if (!strncmp(vo_subdevice, "single", 6)) {
272 buffermode = DLBM_FRONTONLY;
273 osd_max = 1;
274 flipping = 0;
275 vo_subdevice += 6;
276 } else if (!strncmp(vo_subdevice, "double", 6)) {
277 buffermode = DLBM_BACKVIDEO;
278 osd_max = 2;
279 flipping = 1;
280 vo_subdevice += 6;
281 } else if (!strncmp(vo_subdevice, "triple", 6)) {
282 buffermode = DLBM_TRIPLE;
283 osd_max = 4;
284 flipping = 1;
285 vo_subdevice += 6;
286 } else {
287 show_help = 1;
288 break;
289 }
290 opt_no = 0;
248 } else if (!strncmp(vo_subdevice, "fieldparity=", 12)) { 291 } else if (!strncmp(vo_subdevice, "fieldparity=", 12)) {
292 if (opt_no) {
293 show_help = 1;
294 break;
295 }
249 vo_subdevice += 12; 296 vo_subdevice += 12;
250 if (*vo_subdevice == '0' || 297 if (!strncmp(vo_subdevice, "top", 3)) {
251 *vo_subdevice == '1') { 298 field_parity = 0;
252 field_parity = *vo_subdevice - '0'; 299 vo_subdevice += 3;
253 vo_subdevice++; 300 } else if (!strncmp(vo_subdevice, "bottom", 6)) {
301 field_parity = 1;
302 vo_subdevice += 6;
303 } else {
304 show_help = 1;
305 break;
254 } 306 }
255 opt_no = 0; 307 opt_no = 0;
256 } else if (!strncmp(vo_subdevice, "no", 2)) { 308 } else if (!strncmp(vo_subdevice, "no", 2)) {
309 if (opt_no) {
310 show_help = 1;
311 break;
312 }
257 vo_subdevice += 2; 313 vo_subdevice += 2;
258 opt_no = 1; 314 opt_no = 1;
259 } else { 315 } else if (*vo_subdevice == ':') {
316 if (opt_no) {
317 show_help = 1;
318 break;
319 }
260 vo_subdevice++; 320 vo_subdevice++;
261 opt_no = 0; 321 opt_no = 0;
322 } else {
323 show_help = 1;
324 break;
262 } 325 }
326 }
327 if (show_help) {
328 mp_msg( MSGT_VO, MSGL_ERR,
329 "\nvo_dfbmga command line help:\n"
330 "Example: mplayer -vo dfbmga:nocrtc2:bes:buffermode=single\n"
331 "\nOptions (use 'no' prefix to disable):\n"
332 " bes Use Backend Scaler\n"
333 " crtc2 Use CRTC2\n"
334 " spic Use hardware sub-picture for OSD\n"
335 " input Use DirectFB for keyboard input\n"
336 "\nOther options:\n"
337 " buffermode=(single|double|triple)\n"
338 " single Use single buffering\n"
339 " double Use double buffering\n"
340 " triple Use triple buffering\n"
341 " fieldparity=(top|bottom)\n"
342 " top Top field first\n"
343 " bottom Bottom field first\n"
344 "\n" );
345 return -1;
263 } 346 }
264 } 347 }
265 if (!use_bes && !use_crtc2) { 348 if (!use_bes && !use_crtc2) {
266 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: No output selected\n" ); 349 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: No output selected\n" );
267 return -1; 350 return -1;
302 if (l.res != DFB_OK) { 385 if (l.res != DFB_OK) {
303 mp_msg( MSGT_VO, MSGL_ERR, "Can't get BES layer - %s\n", 386 mp_msg( MSGT_VO, MSGL_ERR, "Can't get BES layer - %s\n",
304 DirectFBErrorString( l.res ) ); 387 DirectFBErrorString( l.res ) );
305 return -1; 388 return -1;
306 } 389 }
307 bes->SetCooperativeLevel( bes, DLSCL_EXCLUSIVE ); 390 if ((res = bes->SetCooperativeLevel( bes, DLSCL_EXCLUSIVE )) != DFB_OK) {
391 mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to BES - %s\n",
392 DirectFBErrorString( res ) );
393 return -1;
394 }
308 bes->SetOpacity( bes, 0 ); 395 bes->SetOpacity( bes, 0 );
309 } 396 }
310 397
311 if (use_crtc2) { 398 if (use_crtc2) {
312 struct layer_enum l = { 399 struct layer_enum l = {
319 if (l.res != DFB_OK) { 406 if (l.res != DFB_OK) {
320 mp_msg( MSGT_VO, MSGL_ERR, "Can't get CRTC2 layer - %s\n", 407 mp_msg( MSGT_VO, MSGL_ERR, "Can't get CRTC2 layer - %s\n",
321 DirectFBErrorString( l.res ) ); 408 DirectFBErrorString( l.res ) );
322 return -1; 409 return -1;
323 } 410 }
324 crtc2->SetCooperativeLevel( crtc2, DLSCL_EXCLUSIVE ); 411 if ((res = crtc2->SetCooperativeLevel( crtc2, DLSCL_EXCLUSIVE )) != DFB_OK) {
412 mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to CRTC2 - %s\n",
413 DirectFBErrorString( res ) );
414 return -1;
415 }
325 crtc2->SetOpacity( crtc2, 0 ); 416 crtc2->SetOpacity( crtc2, 0 );
326 } 417 }
327 418
328 if (use_input) { 419 if (use_input) {
329 if ((res = dfb->GetInputDevice( dfb, DIDID_KEYBOARD, &keyboard )) != DFB_OK) { 420 if ((res = dfb->GetInputDevice( dfb, DIDID_KEYBOARD, &keyboard )) != DFB_OK) {
352 DFBDisplayLayerConfigFlags failed; 443 DFBDisplayLayerConfigFlags failed;
353 444
354 uint32_t out_width; 445 uint32_t out_width;
355 uint32_t out_height; 446 uint32_t out_height;
356 447
448 besframe = NULL;
357 c2frame = NULL; 449 c2frame = NULL;
358 spic = NULL; 450 spic = NULL;
359 subframe = NULL; 451 subframe = NULL;
360 bufs[0] = bufs[1] = bufs[2] = NULL; 452 bufs[0] = bufs[1] = bufs[2] = NULL;
361 453
365 aspect_save_orig(width, height); 457 aspect_save_orig(width, height);
366 aspect_save_prescale(d_width, d_height); 458 aspect_save_prescale(d_width, d_height);
367 459
368 dlc.pixelformat = imgfmt_to_pixelformat( format ); 460 dlc.pixelformat = imgfmt_to_pixelformat( format );
369 461
370 if (use_bes) { 462 {
371 /* Draw to BES surface */
372 dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
373 dlc.width = in_width;
374 dlc.height = in_height;
375 dlc.buffermode = DLBM_BACKVIDEO;
376
377 if (bes->TestConfiguration( bes, &dlc, &failed ) != DFB_OK) {
378 mp_msg( MSGT_VO, MSGL_ERR,
379 "vo_dfbmga: Invalid BES configuration!\n" );
380 return -1;
381 }
382 bes->SetConfiguration( bes, &dlc );
383 bes->GetSurface( bes, &frame );
384
385 aspect_save_screenres( 10000, 10000 );
386 aspect( &out_width, &out_height, A_ZOOM );
387 bes->SetScreenLocation( bes,
388 (1.0f - (float) out_width / 10000.0f) / 2.0f,
389 (1.0f - (float) out_height / 10000.0f) / 2.0f,
390 (float) out_width / 10000.0f,
391 (float) out_height / 10000.0f );
392 bufs[0] = frame;
393 num_bufs = 1;
394 } else {
395 /* Draw to a temporary surface */ 463 /* Draw to a temporary surface */
396 DFBSurfaceDescription dsc; 464 DFBSurfaceDescription dsc;
397 465
398 dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | 466 dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT |
399 DSDESC_PIXELFORMAT; 467 DSDESC_PIXELFORMAT;
400 dsc.width = in_width; 468 dsc.width = in_width;
401 dsc.height = in_height; 469 dsc.height = in_height;
402 dsc.pixelformat = dlc.pixelformat; 470 dsc.pixelformat = dlc.pixelformat;
471
472 /* Don't waste video memory since we don't need direct stretchblit */
473 if (use_bes) {
474 dsc.flags |= DSDESC_CAPS;
475 dsc.caps = DSCAPS_SYSTEMONLY;
476 }
403 477
404 for (num_bufs = 0; num_bufs < 3; num_bufs++) { 478 for (num_bufs = 0; num_bufs < 3; num_bufs++) {
405 if ((res = dfb->CreateSurface( dfb, &dsc, &bufs[num_bufs] )) != DFB_OK) { 479 if ((res = dfb->CreateSurface( dfb, &dsc, &bufs[num_bufs] )) != DFB_OK) {
406 if (num_bufs == 0) { 480 if (num_bufs == 0) {
407 mp_msg( MSGT_VO, MSGL_ERR, 481 mp_msg( MSGT_VO, MSGL_ERR,
408 "vo_dfbmga: Can't create surfaces - %s!\n", 482 "vo_dfbmga: Can't create surfaces - %s!\n",
409 DirectFBErrorString( res ) ); 483 DirectFBErrorString( res ) );
410 return -1; 484 return -1;
411 } 485 }
486 break;
412 } 487 }
413 } 488 }
414 frame = bufs[0]; 489 frame = bufs[0];
415 current_buf = 0; 490 current_buf = 0;
416 current_ip_buf = 0; 491 current_ip_buf = 0;
417 } 492 }
418 493 frame->GetPixelFormat( frame, &frame_format );
494 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Video surface %dx%d %s\n",
495 in_width, in_height,
496 pixelformat_name( frame_format ) );
497
498
499 /*
500 * BES
501 */
502 if (use_bes) {
503 dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
504 dlc.width = in_width;
505 dlc.height = in_height;
506
507 if (use_crtc2)
508 dlc.buffermode = DLBM_FRONTONLY;
509 else
510 dlc.buffermode = buffermode;
511
512 if ((res = bes->TestConfiguration( bes, &dlc, &failed )) != DFB_OK) {
513 mp_msg( MSGT_VO, MSGL_ERR,
514 "vo_dfbmga: Invalid BES configuration - %s!\n",
515 DirectFBErrorString( res ) );
516 return -1;
517 }
518 if ((res = bes->SetConfiguration( bes, &dlc )) != DFB_OK) {
519 mp_msg( MSGT_VO, MSGL_ERR,
520 "vo_dfbmga: BES configuration failed - %s!\n",
521 DirectFBErrorString( res ) );
522 return -1;
523 }
524 bes->GetSurface( bes, &besframe );
525 besframe->SetBlittingFlags( besframe, DSBLIT_NOFX );
526
527 aspect_save_screenres( 10000, 10000 );
528 aspect( &out_width, &out_height, A_ZOOM );
529 bes->SetScreenLocation( bes,
530 (1.0f - (float) out_width / 10000.0f) / 2.0f,
531 (1.0f - (float) out_height / 10000.0f) / 2.0f,
532 (float) out_width / 10000.0f,
533 (float) out_height / 10000.0f );
534
535 besframe->Clear( besframe, 0, 0, 0, 0xff );
536 besframe->Flip( besframe, NULL, 0 );
537 besframe->Clear( besframe, 0, 0, 0, 0xff );
538 besframe->Flip( besframe, NULL, 0 );
539 besframe->Clear( besframe, 0, 0, 0, 0xff );
540
541 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: BES using %s buffering\n",
542 dlc.buffermode == DLBM_TRIPLE ? "triple" :
543 dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" );
544 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: BES surface %dx%d %s\n", dlc.width, dlc.height, pixelformat_name( dlc.pixelformat ) );
545 }
546
547 /*
548 * CRTC2
549 */
419 if (use_crtc2) { 550 if (use_crtc2) {
420 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; 551 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS;
421 dlc.buffermode = DLBM_BACKVIDEO; 552 dlc.buffermode = buffermode;
553 dlc.options = DLOP_FLICKER_FILTERING;
422 554
423 #if DIRECTFBVERSION > 916 555 #if DIRECTFBVERSION > 916
424 if (field_parity != -1) { 556 if (field_parity != -1) {
425 dlc.flags |= DLCONF_OPTIONS;
426 dlc.options = DLOP_FIELD_PARITY; 557 dlc.options = DLOP_FIELD_PARITY;
427 } 558 }
428 #endif 559 #endif
429 560
430 switch (dlc.pixelformat) { 561 switch (dlc.pixelformat) {
442 default: 573 default:
443 /* sub-picture not supported */ 574 /* sub-picture not supported */
444 use_spic = 0; 575 use_spic = 0;
445 } 576 }
446 577
447 if (crtc2->TestConfiguration( crtc2, &dlc, &failed ) != DFB_OK) { 578 if ((res = crtc2->TestConfiguration( crtc2, &dlc, &failed )) != DFB_OK) {
448 mp_msg( MSGT_VO, MSGL_ERR, 579 mp_msg( MSGT_VO, MSGL_ERR,
449 "vo_dfbmga: Invalid CRTC2 configuration!\n" ); 580 "vo_dfbmga: Invalid CRTC2 configuration - %s!\n",
450 return -1; 581 DirectFBErrorString( res ) );
451 } 582 return -1;
452 crtc2->SetConfiguration( crtc2, &dlc ); 583 }
584 if ((res = crtc2->SetConfiguration( crtc2, &dlc )) != DFB_OK) {
585 mp_msg( MSGT_VO, MSGL_ERR,
586 "vo_dfbmga: CRTC2 configuration failed - %s!\n",
587 DirectFBErrorString( res ) );
588 return -1;
589 }
453 590
454 #if DIRECTFBVERSION > 916 591 #if DIRECTFBVERSION > 916
455 if (field_parity != -1) 592 if (field_parity != -1)
456 crtc2->SetFieldParity( crtc2, field_parity ); 593 crtc2->SetFieldParity( crtc2, field_parity );
457 #endif 594 #endif
458 595
459 crtc2->GetSurface( crtc2, &c2frame ); 596 crtc2->GetSurface( crtc2, &c2frame );
597 c2frame->SetBlittingFlags( c2frame, DSBLIT_NOFX );
598 c2frame->SetColor( c2frame, 0, 0, 0, 0xff );
460 599
461 c2frame->GetSize( c2frame, &screen_width, &screen_height ); 600 c2frame->GetSize( c2frame, &screen_width, &screen_height );
462 601
463 /* Don't stretch only slightly smaller videos */ 602 /* Don't stretch only slightly smaller videos */
464 if ((in_width > (0.95 * screen_width)) && 603 if ((in_width > (0.95 * screen_width)) &&
487 drect.h = out_height; 626 drect.h = out_height;
488 627
489 c2frame->Clear( c2frame, 0, 0, 0, 0xff ); 628 c2frame->Clear( c2frame, 0, 0, 0, 0xff );
490 c2frame->Flip( c2frame, NULL, 0 ); 629 c2frame->Flip( c2frame, NULL, 0 );
491 c2frame->Clear( c2frame, 0, 0, 0, 0xff ); 630 c2frame->Clear( c2frame, 0, 0, 0, 0xff );
492 631 c2frame->Flip( c2frame, NULL, 0 );
632 c2frame->Clear( c2frame, 0, 0, 0, 0xff );
633
634 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC2 using %s buffering\n",
635 dlc.buffermode == DLBM_TRIPLE ? "triple" :
636 dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" );
493 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC2 surface %dx%d %s\n", dlc.width, dlc.height, pixelformat_name( dlc.pixelformat ) ); 637 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC2 surface %dx%d %s\n", dlc.width, dlc.height, pixelformat_name( dlc.pixelformat ) );
494 } else { 638 } else {
495 screen_width = in_width;
496 screen_height = in_height;
497 use_spic = 0; 639 use_spic = 0;
498 } 640 }
499 641
500 frame->GetPixelFormat( frame, &frame_format ); 642 /*
501 frame_pixel_size = DFB_BYTES_PER_PIXEL( frame_format ); 643 * Sub-picture
502 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Video surface %dx%d %s (%s)\n", 644 */
503 in_width, in_height,
504 pixelformat_name( frame_format ),
505 use_bes ? "BES" : "offscreen" );
506
507 if (use_spic) { 645 if (use_spic) {
508 /* Draw OSD to sub-picture surface */ 646 /* Draw OSD to sub-picture surface */
509 IDirectFBPalette *palette; 647 IDirectFBPalette *palette;
510 DFBColor color; 648 DFBColor color;
511 int i; 649 int i;
514 &spic, 652 &spic,
515 DFB_UNSUPPORTED 653 DFB_UNSUPPORTED
516 }; 654 };
517 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l ); 655 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l );
518 if (l.res != DFB_OK) { 656 if (l.res != DFB_OK) {
519 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: Can't get sub-picture layer - %s\n", DirectFBErrorString( l.res ) ); 657 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: Can't get sub-picture layer - %s\n",
520 return -1; 658 DirectFBErrorString( l.res ) );
521 } 659 return -1;
522 spic->SetCooperativeLevel( spic, DLSCL_EXCLUSIVE ); 660 }
661 if ((res = spic->SetCooperativeLevel( spic, DLSCL_EXCLUSIVE )) != DFB_OK) {
662 mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to sub-picture - %s\n",
663 DirectFBErrorString( res ) );
664 return -1;
665 }
523 spic->SetOpacity( spic, 0 ); 666 spic->SetOpacity( spic, 0 );
524 667
525 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; 668 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
526 dlc.pixelformat = DSPF_LUT8; 669 dlc.pixelformat = DSPF_ALUT44;
527 dlc.buffermode = DLBM_BACKVIDEO; 670 dlc.buffermode = buffermode;
671
528 #if DIRECTFBVERSION > 916 672 #if DIRECTFBVERSION > 916
529 dlc.flags |= DLCONF_OPTIONS; 673 dlc.flags |= DLCONF_OPTIONS;
530 dlc.options = DLOP_ALPHACHANNEL; 674 dlc.options = DLOP_ALPHACHANNEL;
531 #endif 675 #endif
532 if (spic->TestConfiguration( spic, &dlc, &failed ) != DFB_OK) { 676 if ((res = spic->TestConfiguration( spic, &dlc, &failed )) != DFB_OK) {
533 mp_msg( MSGT_VO, MSGL_ERR, 677 mp_msg( MSGT_VO, MSGL_ERR,
534 "vo_dfbmga: Invalid sub-picture configuration!\n" ); 678 "vo_dfbmga: Invalid sub-picture configuration - %s!\n",
535 return -1; 679 DirectFBErrorString( res ) );
536 } 680 return -1;
537 spic->SetConfiguration( spic, &dlc ); 681 }
682 if ((res = spic->SetConfiguration( spic, &dlc )) != DFB_OK) {
683 mp_msg( MSGT_VO, MSGL_ERR,
684 "vo_dfbmga: Sub-picture configuration failed - %s!\n",
685 DirectFBErrorString( res ) );
686 return -1;
687 }
538 688
539 spic->GetSurface( spic, &subframe ); 689 spic->GetSurface( spic, &subframe );
540 690
541 subframe->GetPalette( subframe, &palette ); 691 subframe->GetPalette( subframe, &palette );
542 color.a = 0xff; 692 color.a = 0xff;
546 color.b = i * 17; 696 color.b = i * 17;
547 palette->SetEntries( palette, &color, 1, i ); 697 palette->SetEntries( palette, &color, 1, i );
548 } 698 }
549 palette->Release( palette ); 699 palette->Release( palette );
550 700
551 subframe->Clear( subframe, 0, 0, 0, 0xff ); 701 subframe->Clear( subframe, 0, 0, 0, 0 );
552 subframe->Flip( subframe, NULL, 0 ); 702 subframe->Flip( subframe, NULL, 0 );
553 subframe->Clear( subframe, 0, 0, 0, 0xff ); 703 subframe->Clear( subframe, 0, 0, 0, 0 );
704 subframe->Flip( subframe, NULL, 0 );
705 subframe->Clear( subframe, 0, 0, 0, 0 );
706
707 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Sub-picture layer using %s buffering\n",
708 dlc.buffermode == DLBM_TRIPLE ? "triple" :
709 dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" );
554 } else if (use_crtc2) { 710 } else if (use_crtc2) {
555 /* Draw OSD to CRTC2 surface */ 711 /* Draw OSD to CRTC2 surface */
556 subframe = c2frame; 712 subframe = c2frame;
557 } else { 713 } else {
558 /* Draw OSD to BES surface */ 714 /* Draw OSD to BES surface */
559 subframe = frame; 715 subframe = besframe;
560 } 716 }
561 717
562 subframe->GetSize( subframe, &sub_width, &sub_height ); 718 subframe->GetSize( subframe, &sub_width, &sub_height );
563 subframe->GetPixelFormat( subframe, &subframe_format ); 719 subframe->GetPixelFormat( subframe, &subframe_format );
564 subframe_pixel_size = DFB_BYTES_PER_PIXEL( subframe_format );
565 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Sub-picture surface %dx%d %s (%s)\n", 720 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Sub-picture surface %dx%d %s (%s)\n",
566 sub_width, sub_height, 721 sub_width, sub_height,
567 pixelformat_name( subframe_format ), 722 pixelformat_name( subframe_format ),
568 use_crtc2 ? (use_spic ? "Sub-picture layer" : "CRTC2") : "BES" ); 723 use_crtc2 ? (use_spic ? "Sub-picture layer" : "CRTC2") : "BES" );
569 724
608 763
609 return 0; 764 return 0;
610 } 765 }
611 766
612 static void 767 static void
613 vo_draw_alpha_lut8( int w, int h, 768 vo_draw_alpha_alut44( int w, int h,
614 unsigned char* src, 769 unsigned char* src,
615 unsigned char *srca, 770 unsigned char *srca,
616 int srcstride, 771 int srcstride,
617 unsigned char* dst, 772 unsigned char* dst,
618 int dststride ) 773 int dststride )
626 } 781 }
627 src += srcstride; 782 src += srcstride;
628 srca += srcstride; 783 srca += srcstride;
629 dst += dststride; 784 dst += dststride;
630 } 785 }
786 }
787
788 static void
789 clear_alpha( int x0, int y0,
790 int w, int h )
791 {
792 if (use_spic && !flipping && vo_osd_changed)
793 subframe->FillRectangle( subframe, x0, y0, w, h );
631 } 794 }
632 795
633 static void 796 static void
634 draw_alpha( int x0, int y0, 797 draw_alpha( int x0, int y0,
635 int w, int h, 798 int w, int h,
639 { 802 {
640 void *dst; 803 void *dst;
641 int pitch; 804 int pitch;
642 805
643 if (use_spic) { 806 if (use_spic) {
644 if (!osd_changed) 807 if (!osd_changed || (!flipping && !vo_osd_changed))
645 return; 808 return;
646 osd_dirty |= osd_current; 809 osd_dirty |= osd_current;
647 } else if (use_crtc2) { 810 } else if (use_crtc2) {
648 if (x0 < drect.x || 811 if (x0 < drect.x ||
649 y0 < drect.y || 812 y0 < drect.y ||
650 x0 + w > drect.x + drect.w || 813 x0 + w > drect.x + drect.w ||
651 y0 + h > drect.y + drect.h) 814 y0 + h > drect.y + drect.h)
652 osd_dirty |= osd_current; 815 osd_dirty |= osd_current;
653 } 816 }
654 817
655 if (subframe->Lock( subframe, DSLF_WRITE, &dst, &pitch ) != DFB_OK) 818 if (subframe->Lock( subframe, DSLF_READ | DSLF_WRITE, &dst, &pitch ) != DFB_OK)
656 return; 819 return;
657 820
658 switch (subframe_format) { 821 switch (subframe_format) {
659 case DSPF_LUT8: 822 case DSPF_ALUT44:
660 vo_draw_alpha_lut8( w, h, src, srca, stride, 823 vo_draw_alpha_alut44( w, h, src, srca, stride,
661 ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size * x0, 824 ((uint8_t *) dst) + pitch * y0 + x0,
662 pitch ); 825 pitch );
663 break; 826 break;
664 case DSPF_RGB32: 827 case DSPF_RGB32:
665 case DSPF_ARGB: 828 case DSPF_ARGB:
666 vo_draw_alpha_rgb32( w, h, src, srca, stride, 829 vo_draw_alpha_rgb32( w, h, src, srca, stride,
667 (( uint8_t *) dst) + pitch * y0 + subframe_pixel_size * x0, 830 (( uint8_t *) dst) + pitch * y0 + 4 * x0,
668 pitch ); 831 pitch );
669 break; 832 break;
670 case DSPF_RGB24: 833 case DSPF_RGB24:
671 vo_draw_alpha_rgb24( w, h, src, srca, stride, 834 vo_draw_alpha_rgb24( w, h, src, srca, stride,
672 ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size * x0, 835 ((uint8_t *) dst) + pitch * y0 + 3 * x0,
673 pitch ); 836 pitch );
674 break; 837 break;
675 case DSPF_RGB16: 838 case DSPF_RGB16:
676 vo_draw_alpha_rgb16( w, h, src, srca, stride, 839 vo_draw_alpha_rgb16( w, h, src, srca, stride,
677 ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size * x0, 840 ((uint8_t *) dst) + pitch * y0 + 2 * x0,
678 pitch ); 841 pitch );
679 break; 842 break;
680 #if DIRECTFBVERSION > 915
681 case DSPF_ARGB1555: 843 case DSPF_ARGB1555:
682 #else
683 case DSPF_RGB15:
684 #endif
685 vo_draw_alpha_rgb15( w, h, src, srca, stride, 844 vo_draw_alpha_rgb15( w, h, src, srca, stride,
686 ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size * x0, 845 ((uint8_t *) dst) + pitch * y0 + 2 * x0,
687 pitch ); 846 pitch );
688 break; 847 break;
689 case DSPF_YUY2: 848 case DSPF_YUY2:
690 vo_draw_alpha_yuy2( w, h, src, srca, stride, 849 vo_draw_alpha_yuy2( w, h, src, srca, stride,
691 ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size * x0, 850 ((uint8_t *) dst) + pitch * y0 + 2 * x0,
692 pitch ); 851 pitch );
693 break; 852 break;
694 case DSPF_UYVY: 853 case DSPF_UYVY:
695 vo_draw_alpha_yuy2( w, h, src, srca, stride, 854 vo_draw_alpha_yuy2( w, h, src, srca, stride,
696 ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size * x0 + 1, 855 ((uint8_t *) dst) + pitch * y0 + 2 * x0 + 1,
697 pitch ); 856 pitch );
698 break; 857 break;
699 case DSPF_I420: 858 case DSPF_I420:
700 case DSPF_YV12: 859 case DSPF_YV12:
701 vo_draw_alpha_yv12( w, h, src, srca, stride, 860 vo_draw_alpha_yv12( w, h, src, srca, stride,
702 ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size * x0, 861 ((uint8_t *) dst) + pitch * y0 + x0,
703 pitch ); 862 pitch );
704 break; 863 break;
705 default:
706 } 864 }
707 865
708 subframe->Unlock( subframe ); 866 subframe->Unlock( subframe );
709 } 867 }
710 868
754 } 912 }
755 913
756 static void 914 static void
757 blit_to_screen( void ) 915 blit_to_screen( void )
758 { 916 {
759 /* Flip BES */ 917 IDirectFBSurface *blitsrc = frame;
760 if (use_bes) 918
761 frame->Flip( frame, NULL, 0 ); 919 if (use_bes) {
762 920 if (vo_vsync && !flipping && !use_crtc2)
763 /* Blit from BES/temp to CRTC2 */ 921 bes->WaitForSync( bes );
764 c2frame->SetBlittingFlags( c2frame, DSBLIT_NOFX ); 922
923 besframe->Blit( besframe, blitsrc, NULL, 0, 0 );
924 blitsrc = besframe;
925 }
926
927 if (use_crtc2) {
928 if (vo_vsync && !flipping)
929 crtc2->WaitForSync( crtc2 );
930
765 if (stretch) 931 if (stretch)
766 c2frame->StretchBlit( c2frame, frame, NULL, &drect ); 932 c2frame->StretchBlit( c2frame, blitsrc, NULL, &drect );
767 else 933 else
768 c2frame->Blit( c2frame, frame, NULL, drect.x, drect.y ); 934 c2frame->Blit( c2frame, blitsrc, NULL, drect.x, drect.y );
935 }
769 } 936 }
770 937
771 static void 938 static void
772 draw_osd( void ) 939 draw_osd( void )
773 { 940 {
774 frame = bufs[current_buf]; 941 frame = bufs[current_buf];
775 frame->Unlock( frame ); 942 frame->Unlock( frame );
776 943
777 osd_changed = vo_osd_changed( 0 ); 944 osd_changed = vo_osd_changed( 0 );
778
779 if (osd_dirty & osd_current) { 945 if (osd_dirty & osd_current) {
780 if (use_spic) { 946 if (use_spic) {
781 subframe->Clear( subframe, 0, 0, 0, 0xff ); 947 if (flipping)
948 subframe->Clear( subframe, 0, 0, 0, 0 );
782 } else if (use_crtc2) { 949 } else if (use_crtc2) {
783 /* Clear black bars around the picture */ 950 /* Clear black bars around the picture */
784 subframe->SetColor( subframe, 0, 0, 0, 0xff );
785 subframe->FillRectangle( subframe, 951 subframe->FillRectangle( subframe,
786 0, 0, 952 0, 0,
787 screen_width, drect.y ); 953 screen_width, drect.y );
788 subframe->FillRectangle( subframe, 954 subframe->FillRectangle( subframe,
789 0, drect.y + drect.h, 955 0, drect.y + drect.h,
796 drect.x, drect.h ); 962 drect.x, drect.h );
797 } 963 }
798 osd_dirty &= ~osd_current; 964 osd_dirty &= ~osd_current;
799 } 965 }
800 966
801 if (use_crtc2) {
802 blit_to_screen(); 967 blit_to_screen();
803 blit_done = 1; 968 blit_done = 1;
804 } 969
805 970 vo_remove_text( sub_width, sub_height, clear_alpha );
806 vo_draw_text( sub_width, sub_height, draw_alpha ); 971 vo_draw_text( sub_width, sub_height, draw_alpha );
807 972
808 if (use_spic && osd_changed) { 973 if (use_spic && flipping && osd_changed) {
809 subframe->Flip( subframe, NULL, 0 ); 974 subframe->Flip( subframe, NULL, 0 );
810 osd_current ^= 3; 975 osd_current <<= 1;
976 if (osd_current > osd_max)
977 osd_current = 1;
811 } 978 }
812 } 979 }
813 980
814 static void 981 static void
815 flip_page( void ) 982 flip_page( void )
816 { 983 {
817 if (!use_crtc2) {
818 /* Flip BES */
819 frame->Flip( frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 );
820 } else {
821 if (!blit_done) 984 if (!blit_done)
822 blit_to_screen(); 985 blit_to_screen();
823 986
824 /* Flip CRTC2 */ 987 if (flipping) {
825 c2frame->Flip( c2frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 ); 988 if (use_crtc2)
826 if (!use_spic) 989 c2frame->Flip( c2frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : DSFLIP_ONSYNC );
827 osd_current ^= 3; 990 else
828 blit_done = 0; 991 besframe->Flip( besframe, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : DSFLIP_ONSYNC );
829 } 992
830 993 if (!use_spic) {
831 current_buf = vo_directrendering ? 0 : (current_buf + 1) % num_bufs; 994 osd_current <<= 1;
995 if (osd_current > osd_max)
996 osd_current = 1;
997 }
998 }
999
1000 blit_done = 0;
1001 current_buf = 0;//vo_directrendering ? 0 : (current_buf + 1) % num_bufs;
832 } 1002 }
833 1003
834 static void 1004 static void
835 uninit( void ) 1005 uninit( void )
836 { 1006 {
837 if (use_input) { 1007 if (buffer)
838 buffer->Release( buffer ); 1008 buffer->Release( buffer );
1009 if (keyboard)
839 keyboard->Release( keyboard ); 1010 keyboard->Release( keyboard );
840 } 1011 buffer = NULL;
1012 keyboard = NULL;
841 1013
842 while (num_bufs--) { 1014 while (num_bufs--) {
843 frame = bufs[num_bufs]; 1015 frame = bufs[num_bufs];
844 if (frame) 1016 if (frame)
845 frame->Release( frame ); 1017 frame->Release( frame );
846 bufs[num_bufs] = NULL; 1018 bufs[num_bufs] = NULL;
847 } 1019 }
848 if (use_bes) { 1020 if (bes) {
1021 if (besframe)
1022 besframe->Release( besframe );
849 bes->SetOpacity( bes, 0 ); 1023 bes->SetOpacity( bes, 0 );
850 bes->Release( bes ); 1024 bes->Release( bes );
851 } 1025 besframe = NULL;
852 if (use_crtc2) { 1026 bes = NULL;
1027 }
1028 if (crtc2) {
853 if (c2frame) 1029 if (c2frame)
854 c2frame->Release( c2frame ); 1030 c2frame->Release( c2frame );
855 crtc2->SetOpacity( crtc2, 0 ); 1031 crtc2->SetOpacity( crtc2, 0 );
856 crtc2->Release( crtc2 ); 1032 crtc2->Release( crtc2 );
857 c2frame = NULL; 1033 c2frame = NULL;
858 } 1034 crtc2 = NULL;
859 if (use_spic && spic) { 1035 }
1036 if (spic) {
860 if (subframe) 1037 if (subframe)
861 subframe->Release( subframe ); 1038 subframe->Release( subframe );
862 spic->SetOpacity( spic, 0 ); 1039 spic->SetOpacity( spic, 0 );
863 spic->Release( spic ); 1040 spic->Release( spic );
864 subframe = NULL; 1041 subframe = NULL;