Mercurial > mplayer.hg
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; |