Mercurial > mplayer.hg
comparison libvo/vo_dfbmga.c @ 9021:070b91093606
* Remove unneeded includes & macros
* Get layers by name rather that fixed ID. Only works for DirectFB >=
0.9.16 so fall back to ID based stuff for older releases.
* New option "noinput" (useful in X)
* Add some NULL pointer checks to uninit()
* Improve error messages and use mp_msg()
* Direct rendering fix (at least IPB was broken)
* Use 0xff for alpha component in all colors
* Blit from temp surface to screen was only done in draw_osd() which
doesn't always get called. Do the blit in flip_page() in this case.
* Add GUI support to control()
* Change the driver name to include G450/G550 ;)
patch by Ville Syrj¸«£l¸«£ <syrjala@sci.fi>
author | arpi |
---|---|
date | Sun, 19 Jan 2003 15:41:26 +0000 |
parents | 554e6aa7da5f |
children | edfe34c5405d |
comparison
equal
deleted
inserted
replaced
9020:721a7b3dde59 | 9021:070b91093606 |
---|---|
1 /* | 1 /* |
2 MPlayer video driver for DirectFB / Matrox G400 | 2 MPlayer video driver for DirectFB / Matrox G400/G450/G550 |
3 | 3 |
4 Copyright (C) 2002 Ville Syrjala <syrjala@sci.fi> | 4 Copyright (C) 2002,2003 Ville Syrjala <syrjala@sci.fi> |
5 | 5 |
6 Originally based on vo_directfb.c by | 6 Originally based on vo_directfb.c by |
7 Jiri Svoboda <Jiri.Svoboda@seznam.cz> | 7 Jiri Svoboda <Jiri.Svoboda@seznam.cz> |
8 | 8 |
9 This library is free software; you can redistribute it and/or | 9 This library is free software; you can redistribute it and/or |
27 | 27 |
28 /* other things */ | 28 /* other things */ |
29 #include <stdio.h> | 29 #include <stdio.h> |
30 #include <stdlib.h> | 30 #include <stdlib.h> |
31 #include <string.h> | 31 #include <string.h> |
32 #include <fcntl.h> | |
33 #include <unistd.h> | |
34 #include <errno.h> | |
35 #include <assert.h> | |
36 | |
37 #include <sys/mman.h> | |
38 #include <sys/ioctl.h> | |
39 #include <sys/kd.h> | |
40 #include <linux/fb.h> | |
41 | 32 |
42 #include "config.h" | 33 #include "config.h" |
43 #include "video_out.h" | 34 #include "video_out.h" |
44 #include "video_out_internal.h" | 35 #include "video_out_internal.h" |
45 #include "fastmemcpy.h" | 36 #include "fastmemcpy.h" |
46 #include "sub.h" | 37 #include "sub.h" |
47 #include "../postproc/rgb2rgb.h" | 38 #include "mp_msg.h" |
48 | |
49 #include "aspect.h" | 39 #include "aspect.h" |
50 | 40 |
51 #ifndef min | |
52 #define min(x,y) (((x)<(y))?(x):(y)) | |
53 #endif | |
54 | |
55 static vo_info_t info = { | 41 static vo_info_t info = { |
56 "DirectFB / Matrox G400", | 42 "DirectFB / Matrox G400/G450/G550", |
57 "dfbmga", | 43 "dfbmga", |
58 "Ville Syrjala <syrjala@sci.fi>", | 44 "Ville Syrjala <syrjala@sci.fi>", |
59 "" | 45 "" |
60 }; | 46 }; |
61 | 47 |
96 static unsigned int frame_pixel_size; | 82 static unsigned int frame_pixel_size; |
97 static unsigned int subframe_pixel_size; | 83 static unsigned int subframe_pixel_size; |
98 | 84 |
99 static int inited = 0; | 85 static int inited = 0; |
100 | 86 |
101 static int stretch = 0; | 87 static int blit_done; |
102 | 88 static int stretch; |
103 static int use_bes = 0; | 89 |
104 static int use_crtc2 = 1; | 90 static int use_bes; |
105 static int use_spic = 1; | 91 static int use_crtc2; |
92 static int use_spic; | |
93 static int use_input; | |
106 | 94 |
107 static int osd_changed; | 95 static int osd_changed; |
108 static int osd_dirty; | 96 static int osd_dirty; |
109 static int osd_current; | 97 static int osd_current; |
110 | 98 |
192 default: | 180 default: |
193 return DSPF_UNKNOWN; | 181 return DSPF_UNKNOWN; |
194 } | 182 } |
195 } | 183 } |
196 | 184 |
185 struct layer_enum | |
186 { | |
187 const char *name; | |
188 IDirectFBDisplayLayer **layer; | |
189 DFBResult res; | |
190 }; | |
191 | |
192 static DFBEnumerationResult | |
193 get_layer_by_name( DFBDisplayLayerID id, | |
194 DFBDisplayLayerDescription desc, | |
195 void *data ) | |
196 { | |
197 struct layer_enum *l = (struct layer_enum *) data; | |
198 | |
199 #if DIRECTFBVERSION > 915 | |
200 /* We have desc.name so use it */ | |
201 if (!strcmp( l->name, desc.name )) | |
202 if ((l->res = dfb->GetDisplayLayer( dfb, id, l->layer )) == DFB_OK) | |
203 return DFENUM_CANCEL; | |
204 #else | |
205 /* Fake it according to id */ | |
206 if ((id == 1 && !strcmp( l->name, "Matrox Backend Scaler" )) || | |
207 (id == 2 && !strcmp( l->name, "Matrox CRTC2" )) || | |
208 (id == 3 && !strcmp( l->name, "Matrox CRTC2 Sub-Picture" ))) | |
209 if ((l->res = dfb->GetDisplayLayer( dfb, id, l->layer )) == DFB_OK) | |
210 return DFENUM_CANCEL; | |
211 #endif | |
212 | |
213 return DFENUM_OK; | |
214 } | |
215 | |
197 static uint32_t | 216 static uint32_t |
198 preinit( const char *arg ) | 217 preinit( const char *arg ) |
199 { | 218 { |
219 DFBResult res; | |
220 | |
221 /* Some defaults */ | |
222 use_bes = 0; | |
223 use_crtc2 = 1; | |
224 use_spic = 1; | |
225 use_input = 1; | |
226 | |
200 if (vo_subdevice) { | 227 if (vo_subdevice) { |
228 int opt_no = 0; | |
201 while (*vo_subdevice != '\0') { | 229 while (*vo_subdevice != '\0') { |
202 if (!strncmp(vo_subdevice, "bes", 3)) { | 230 if (!strncmp(vo_subdevice, "bes", 3)) { |
203 use_bes = 1; | 231 use_bes = !opt_no; |
204 vo_subdevice += 3; | 232 vo_subdevice += 3; |
205 } else if (!strncmp(vo_subdevice, "nocrtc2", 7)) { | 233 opt_no = 0; |
206 use_crtc2 = 0; | 234 } else if (!strncmp(vo_subdevice, "crtc2", 5)) { |
207 vo_subdevice += 7; | 235 use_crtc2 = !opt_no; |
208 } else if (!strncmp(vo_subdevice, "nospic", 6)) { | 236 vo_subdevice += 5; |
209 use_spic = 0; | 237 opt_no = 0; |
210 vo_subdevice += 6; | 238 } else if (!strncmp(vo_subdevice, "spic", 4)) { |
211 } else | 239 use_spic = !opt_no; |
240 vo_subdevice += 4; | |
241 opt_no = 0; | |
242 } else if (!strncmp(vo_subdevice, "input", 5)) { | |
243 use_spic = !opt_no; | |
244 vo_subdevice += 5; | |
245 opt_no = 0; | |
246 } else if (!strncmp(vo_subdevice, "no", 2)) { | |
247 vo_subdevice += 2; | |
248 opt_no = 1; | |
249 } else { | |
212 vo_subdevice++; | 250 vo_subdevice++; |
251 opt_no = 0; | |
252 } | |
213 } | 253 } |
214 } | 254 } |
215 if (!use_bes && !use_crtc2) { | 255 if (!use_bes && !use_crtc2) { |
216 fprintf( stderr, "vo_dfbmga: No output selected\n" ); | 256 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: No output selected\n" ); |
217 return -1; | 257 return -1; |
218 } | 258 } |
219 | 259 |
220 if (!inited) { | 260 if (!inited) { |
221 if (DirectFBInit( NULL, NULL ) != DFB_OK) | 261 if ((res = DirectFBInit( NULL, NULL )) != DFB_OK) { |
262 mp_msg( MSGT_VO, MSGL_ERR, | |
263 "vo_dfbmga: DirectFBInit() failed - %s\n", | |
264 DirectFBErrorString( res ) ); | |
222 return -1; | 265 return -1; |
266 } | |
223 | 267 |
224 if (!fb_dev_name && !(fb_dev_name = getenv( "FRAMEBUFFER" ))) | 268 if (!fb_dev_name && !(fb_dev_name = getenv( "FRAMEBUFFER" ))) |
225 fb_dev_name = "/dev/fb0"; | 269 fb_dev_name = "/dev/fb0"; |
226 DirectFBSetOption( "fbdev", fb_dev_name ); | 270 DirectFBSetOption( "fbdev", fb_dev_name ); |
227 DirectFBSetOption( "no-cursor", "" ); | 271 DirectFBSetOption( "no-cursor", "" ); |
228 DirectFBSetOption( "bg-color", "00000000" ); | 272 DirectFBSetOption( "bg-color", "00000000" ); |
229 | 273 |
230 if (DirectFBCreate( &dfb ) != DFB_OK) | 274 if ((res = DirectFBCreate( &dfb )) != DFB_OK) { |
275 mp_msg( MSGT_VO, MSGL_ERR, | |
276 "vo_dfbmga: DirectFBCreate() failed - %s\n", | |
277 DirectFBErrorString( res ) ); | |
231 return -1; | 278 return -1; |
279 } | |
232 | 280 |
233 inited = 1; | 281 inited = 1; |
234 } | 282 } |
235 | 283 |
236 if (use_bes) { | 284 if (use_bes) { |
237 if (dfb->GetDisplayLayer( dfb, 1, &bes ) != DFB_OK) | 285 struct layer_enum l = { |
286 "Matrox Backend Scaler", | |
287 &bes, | |
288 DFB_UNSUPPORTED | |
289 }; | |
290 | |
291 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l ); | |
292 if (l.res != DFB_OK) { | |
293 mp_msg( MSGT_VO, MSGL_ERR, "Can't get BES layer - %s\n", | |
294 DirectFBErrorString( l.res ) ); | |
238 return -1; | 295 return -1; |
296 } | |
239 bes->SetCooperativeLevel( bes, DLSCL_EXCLUSIVE ); | 297 bes->SetCooperativeLevel( bes, DLSCL_EXCLUSIVE ); |
240 bes->SetOpacity( bes, 0 ); | 298 bes->SetOpacity( bes, 0 ); |
241 } | 299 } |
242 | 300 |
243 if (use_crtc2) { | 301 if (use_crtc2) { |
244 if (dfb->GetDisplayLayer( dfb, 2, &crtc2 ) != DFB_OK) | 302 struct layer_enum l = { |
303 "Matrox CRTC2", | |
304 &crtc2, | |
305 DFB_UNSUPPORTED | |
306 }; | |
307 | |
308 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l ); | |
309 if (l.res != DFB_OK) { | |
310 mp_msg( MSGT_VO, MSGL_ERR, "Can't get CRTC2 layer - %s\n", | |
311 DirectFBErrorString( l.res ) ); | |
245 return -1; | 312 return -1; |
313 } | |
246 crtc2->SetCooperativeLevel( crtc2, DLSCL_EXCLUSIVE ); | 314 crtc2->SetCooperativeLevel( crtc2, DLSCL_EXCLUSIVE ); |
247 crtc2->SetOpacity( crtc2, 0 ); | 315 crtc2->SetOpacity( crtc2, 0 ); |
248 } | 316 } |
249 | 317 |
250 if (dfb->GetInputDevice( dfb, DIDID_KEYBOARD, &keyboard ) != DFB_OK) | 318 if (use_input) { |
251 return -1; | 319 if ((res = dfb->GetInputDevice( dfb, DIDID_KEYBOARD, &keyboard )) != DFB_OK) { |
252 keyboard->CreateEventBuffer( keyboard, &buffer ); | 320 mp_msg( MSGT_VO, MSGL_ERR, |
253 buffer->Reset( buffer ); | 321 "vo_dfbmga: Can't get keyboard - %s\n", |
322 DirectFBErrorString( res ) ); | |
323 return -1; | |
324 } | |
325 keyboard->CreateEventBuffer( keyboard, &buffer ); | |
326 buffer->Reset( buffer ); | |
327 } | |
254 | 328 |
255 return 0; | 329 return 0; |
256 } | 330 } |
257 | 331 |
258 static uint32_t | 332 static uint32_t |
260 uint32_t d_width, uint32_t d_height, | 334 uint32_t d_width, uint32_t d_height, |
261 uint32_t fullscreen, | 335 uint32_t fullscreen, |
262 char *title, | 336 char *title, |
263 uint32_t format ) | 337 uint32_t format ) |
264 { | 338 { |
339 DFBResult res; | |
340 | |
265 DFBDisplayLayerConfig dlc; | 341 DFBDisplayLayerConfig dlc; |
266 DFBDisplayLayerConfigFlags failed; | 342 DFBDisplayLayerConfigFlags failed; |
267 | 343 |
268 uint32_t out_width; | 344 uint32_t out_width; |
269 uint32_t out_height; | 345 uint32_t out_height; |
270 | 346 |
347 c2frame = NULL; | |
348 spic = NULL; | |
349 subframe = NULL; | |
350 bufs[0] = bufs[1] = bufs[2] = NULL; | |
351 | |
271 in_width = width; | 352 in_width = width; |
272 in_height = height; | 353 in_height = height; |
273 | 354 |
274 aspect_save_orig(width, height); | 355 aspect_save_orig(width, height); |
275 aspect_save_prescale(d_width, d_height); | 356 aspect_save_prescale(d_width, d_height); |
281 dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; | 362 dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; |
282 dlc.width = in_width; | 363 dlc.width = in_width; |
283 dlc.height = in_height; | 364 dlc.height = in_height; |
284 dlc.buffermode = DLBM_BACKVIDEO; | 365 dlc.buffermode = DLBM_BACKVIDEO; |
285 | 366 |
286 if (bes->TestConfiguration( bes, &dlc, &failed ) != DFB_OK) | 367 if (bes->TestConfiguration( bes, &dlc, &failed ) != DFB_OK) { |
368 mp_msg( MSGT_VO, MSGL_ERR, | |
369 "vo_dfbmga: Invalid BES configuration!\n" ); | |
287 return -1; | 370 return -1; |
371 } | |
288 bes->SetConfiguration( bes, &dlc ); | 372 bes->SetConfiguration( bes, &dlc ); |
289 bes->GetSurface( bes, &frame ); | 373 bes->GetSurface( bes, &frame ); |
290 | 374 |
291 aspect_save_screenres( 10000, 10000 ); | 375 aspect_save_screenres( 10000, 10000 ); |
292 aspect( &out_width, &out_height, A_ZOOM ); | 376 aspect( &out_width, &out_height, A_ZOOM ); |
306 dsc.width = in_width; | 390 dsc.width = in_width; |
307 dsc.height = in_height; | 391 dsc.height = in_height; |
308 dsc.pixelformat = dlc.pixelformat; | 392 dsc.pixelformat = dlc.pixelformat; |
309 | 393 |
310 for (num_bufs = 0; num_bufs < 3; num_bufs++) { | 394 for (num_bufs = 0; num_bufs < 3; num_bufs++) { |
311 if (dfb->CreateSurface( dfb, &dsc, &bufs[num_bufs] ) != DFB_OK) { | 395 if ((res = dfb->CreateSurface( dfb, &dsc, &bufs[num_bufs] )) != DFB_OK) { |
312 if (num_bufs == 0) | 396 if (num_bufs == 0) { |
397 mp_msg( MSGT_VO, MSGL_ERR, | |
398 "vo_dfbmga: Can't create surfaces - %s!\n", | |
399 DirectFBErrorString( res ) ); | |
313 return -1; | 400 return -1; |
401 } | |
314 } | 402 } |
315 } | 403 } |
316 frame = bufs[0]; | 404 frame = bufs[0]; |
317 current_buf = 0; | 405 current_buf = 0; |
318 current_ip_buf = 0; | 406 current_ip_buf = 0; |
337 default: | 425 default: |
338 /* sub-picture not supported */ | 426 /* sub-picture not supported */ |
339 use_spic = 0; | 427 use_spic = 0; |
340 } | 428 } |
341 | 429 |
342 if (crtc2->TestConfiguration( crtc2, &dlc, &failed ) != DFB_OK) | 430 if (crtc2->TestConfiguration( crtc2, &dlc, &failed ) != DFB_OK) { |
431 mp_msg( MSGT_VO, MSGL_ERR, | |
432 "vo_dfbmga: Invalid CRTC2 configuration!\n" ); | |
343 return -1; | 433 return -1; |
434 } | |
344 crtc2->SetConfiguration( crtc2, &dlc ); | 435 crtc2->SetConfiguration( crtc2, &dlc ); |
345 crtc2->GetSurface( crtc2, &c2frame ); | 436 crtc2->GetSurface( crtc2, &c2frame ); |
346 | 437 |
347 c2frame->GetSize( c2frame, &screen_width, &screen_height ); | 438 c2frame->GetSize( c2frame, &screen_width, &screen_height ); |
348 | 439 |
370 drect.x = (screen_width - out_width) / 2; | 461 drect.x = (screen_width - out_width) / 2; |
371 drect.y = (screen_height - out_height) / 2; | 462 drect.y = (screen_height - out_height) / 2; |
372 drect.w = out_width; | 463 drect.w = out_width; |
373 drect.h = out_height; | 464 drect.h = out_height; |
374 | 465 |
375 c2frame->Clear( c2frame, 0, 0, 0, 0 ); | 466 c2frame->Clear( c2frame, 0, 0, 0, 0xff ); |
376 c2frame->Flip( c2frame, NULL, 0 ); | 467 c2frame->Flip( c2frame, NULL, 0 ); |
377 c2frame->Clear( c2frame, 0, 0, 0, 0 ); | 468 c2frame->Clear( c2frame, 0, 0, 0, 0xff ); |
378 | 469 |
379 printf( "vo_dfbmga: CRTC2 surface %dx%d %s\n", dlc.width, dlc.height, pixelformat_name( dlc.pixelformat ) ); | 470 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC2 surface %dx%d %s\n", dlc.width, dlc.height, pixelformat_name( dlc.pixelformat ) ); |
380 } else { | 471 } else { |
381 screen_width = in_width; | 472 screen_width = in_width; |
382 screen_height = in_height; | 473 screen_height = in_height; |
383 use_spic = 0; | 474 use_spic = 0; |
384 } | 475 } |
385 | 476 |
386 frame->GetPixelFormat( frame, &frame_format ); | 477 frame->GetPixelFormat( frame, &frame_format ); |
387 frame_pixel_size = DFB_BYTES_PER_PIXEL( frame_format ); | 478 frame_pixel_size = DFB_BYTES_PER_PIXEL( frame_format ); |
388 printf( "vo_dfbmga: Video surface %dx%d %s (%s)\n", | 479 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Video surface %dx%d %s (%s)\n", |
389 in_width, in_height, | 480 in_width, in_height, |
390 pixelformat_name( frame_format ), | 481 pixelformat_name( frame_format ), |
391 use_bes ? "BES" : "offscreen" ); | 482 use_bes ? "BES" : "offscreen" ); |
392 | 483 |
393 if (use_spic) { | 484 if (use_spic) { |
394 /* Draw OSD to sub-picture surface */ | 485 /* Draw OSD to sub-picture surface */ |
395 IDirectFBPalette *palette; | 486 IDirectFBPalette *palette; |
396 DFBColor color; | 487 DFBColor color; |
397 int i; | 488 int i; |
398 | 489 struct layer_enum l = { |
399 if (dfb->GetDisplayLayer( dfb, 3, &spic ) != DFB_OK) | 490 "Matrox CRTC2 Sub-Picture", |
491 &spic, | |
492 DFB_UNSUPPORTED | |
493 }; | |
494 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l ); | |
495 if (l.res != DFB_OK) { | |
496 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: Can't get sub-picture layer - %s\n", DirectFBErrorString( l.res ) ); | |
400 return -1; | 497 return -1; |
498 } | |
401 spic->SetCooperativeLevel( spic, DLSCL_EXCLUSIVE ); | 499 spic->SetCooperativeLevel( spic, DLSCL_EXCLUSIVE ); |
402 spic->SetOpacity( spic, 0 ); | 500 spic->SetOpacity( spic, 0 ); |
403 | 501 |
404 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; | 502 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; |
405 dlc.pixelformat = DSPF_LUT8; | 503 dlc.pixelformat = DSPF_LUT8; |
406 dlc.buffermode = DLBM_BACKVIDEO; | 504 dlc.buffermode = DLBM_BACKVIDEO; |
407 if (spic->TestConfiguration( spic, &dlc, &failed ) != DFB_OK) | 505 if (spic->TestConfiguration( spic, &dlc, &failed ) != DFB_OK) { |
506 mp_msg( MSGT_VO, MSGL_ERR, | |
507 "vo_dfbmga: Invalid sub-picture configuration!\n" ); | |
408 return -1; | 508 return -1; |
509 } | |
409 spic->SetConfiguration( spic, &dlc ); | 510 spic->SetConfiguration( spic, &dlc ); |
410 | 511 |
411 spic->GetSurface( spic, &subframe ); | 512 spic->GetSurface( spic, &subframe ); |
412 | 513 |
413 subframe->GetPalette( subframe, &palette ); | 514 subframe->GetPalette( subframe, &palette ); |
414 color.a = 0; | 515 color.a = 0xff; |
415 for (i = 0; i < 16; i++) { | 516 for (i = 0; i < 16; i++) { |
416 color.r = i * 17; | 517 color.r = i * 17; |
417 color.g = i * 17; | 518 color.g = i * 17; |
418 color.b = i * 17; | 519 color.b = i * 17; |
419 palette->SetEntries( palette, &color, 1, i ); | 520 palette->SetEntries( palette, &color, 1, i ); |
420 } | 521 } |
421 palette->Release( palette ); | 522 palette->Release( palette ); |
422 | 523 |
423 subframe->Clear( subframe, 0, 0, 0, 0 ); | 524 subframe->Clear( subframe, 0, 0, 0, 0xff ); |
424 subframe->Flip( subframe, NULL, 0 ); | 525 subframe->Flip( subframe, NULL, 0 ); |
425 subframe->Clear( subframe, 0, 0, 0, 0 ); | 526 subframe->Clear( subframe, 0, 0, 0, 0xff ); |
426 } else if (use_crtc2) { | 527 } else if (use_crtc2) { |
427 /* Draw OSD to CRTC2 surface */ | 528 /* Draw OSD to CRTC2 surface */ |
428 subframe = c2frame; | 529 subframe = c2frame; |
429 } else { | 530 } else { |
430 /* Draw OSD to BES surface */ | 531 /* Draw OSD to BES surface */ |
432 } | 533 } |
433 | 534 |
434 subframe->GetSize( subframe, &sub_width, &sub_height ); | 535 subframe->GetSize( subframe, &sub_width, &sub_height ); |
435 subframe->GetPixelFormat( subframe, &subframe_format ); | 536 subframe->GetPixelFormat( subframe, &subframe_format ); |
436 subframe_pixel_size = DFB_BYTES_PER_PIXEL( subframe_format ); | 537 subframe_pixel_size = DFB_BYTES_PER_PIXEL( subframe_format ); |
437 printf( "vo_dfbmga: Sub-picture surface %dx%d %s (%s)\n", | 538 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Sub-picture surface %dx%d %s (%s)\n", |
438 sub_width, sub_height, | 539 sub_width, sub_height, |
439 pixelformat_name( subframe_format ), | 540 pixelformat_name( subframe_format ), |
440 use_crtc2 ? (use_spic ? "Sub-picture layer" : "CRTC2") : "BES" ); | 541 use_crtc2 ? (use_spic ? "Sub-picture layer" : "CRTC2") : "BES" ); |
441 | 542 |
442 /* Display all needed layers */ | 543 /* Display all needed layers */ |
447 if (use_spic) | 548 if (use_spic) |
448 spic->SetOpacity( spic, 0xFF ); | 549 spic->SetOpacity( spic, 0xFF ); |
449 | 550 |
450 osd_dirty = 0; | 551 osd_dirty = 0; |
451 osd_current = 1; | 552 osd_current = 1; |
553 blit_done = 0; | |
452 | 554 |
453 return 0; | 555 return 0; |
454 } | 556 } |
455 | 557 |
456 static uint32_t | 558 static uint32_t |
589 draw_slice( uint8_t * src[], int stride[], int w, int h, int x, int y ) | 691 draw_slice( uint8_t * src[], int stride[], int w, int h, int x, int y ) |
590 { | 692 { |
591 void *dst; | 693 void *dst; |
592 int pitch; | 694 int pitch; |
593 | 695 |
594 if (vo_directrendering) | |
595 frame->Unlock( frame ); | |
596 | |
597 if (frame->Lock( frame, DSLF_WRITE, &dst, &pitch ) != DFB_OK) | 696 if (frame->Lock( frame, DSLF_WRITE, &dst, &pitch ) != DFB_OK) |
598 return VO_FALSE; | 697 return VO_FALSE; |
599 | 698 |
600 memcpy_pic( dst + pitch * y + x, src[0], | 699 memcpy_pic( dst + pitch * y + x, src[0], |
601 w, h, pitch, stride[0] ); | 700 w, h, pitch, stride[0] ); |
626 | 725 |
627 return VO_TRUE; | 726 return VO_TRUE; |
628 } | 727 } |
629 | 728 |
630 static void | 729 static void |
730 blit_to_screen( void ) | |
731 { | |
732 /* Flip BES */ | |
733 if (use_bes) | |
734 frame->Flip( frame, NULL, 0 ); | |
735 | |
736 /* Blit from BES/temp to CRTC2 */ | |
737 c2frame->SetBlittingFlags( c2frame, DSBLIT_NOFX ); | |
738 if (stretch) | |
739 c2frame->StretchBlit( c2frame, frame, NULL, &drect ); | |
740 else | |
741 c2frame->Blit( c2frame, frame, NULL, drect.x, drect.y ); | |
742 } | |
743 | |
744 static void | |
631 draw_osd( void ) | 745 draw_osd( void ) |
632 { | 746 { |
633 if (vo_directrendering) | 747 frame = bufs[current_buf]; |
634 frame->Unlock( frame ); | 748 frame->Unlock( frame ); |
635 | 749 |
636 osd_changed = vo_osd_changed( 0 ); | 750 osd_changed = vo_osd_changed( 0 ); |
637 | 751 |
638 if (osd_dirty & osd_current) { | 752 if (osd_dirty & osd_current) { |
639 if (use_spic) { | 753 if (use_spic) { |
640 subframe->Clear( subframe, 0, 0, 0, 0 ); | 754 subframe->Clear( subframe, 0, 0, 0, 0xff ); |
641 } else if (use_crtc2) { | 755 } else if (use_crtc2) { |
642 /* Clear black bars around the picture */ | 756 /* Clear black bars around the picture */ |
643 subframe->SetColor( subframe, 0, 0, 0, 0 ); | 757 subframe->SetColor( subframe, 0, 0, 0, 0xff ); |
644 subframe->FillRectangle( subframe, | 758 subframe->FillRectangle( subframe, |
645 0, 0, | 759 0, 0, |
646 screen_width, drect.y ); | 760 screen_width, drect.y ); |
647 subframe->FillRectangle( subframe, | 761 subframe->FillRectangle( subframe, |
648 0, drect.y + drect.h, | 762 0, drect.y + drect.h, |
656 } | 770 } |
657 osd_dirty &= ~osd_current; | 771 osd_dirty &= ~osd_current; |
658 } | 772 } |
659 | 773 |
660 if (use_crtc2) { | 774 if (use_crtc2) { |
661 /* Flip BES */ | 775 blit_to_screen(); |
662 if (use_bes) | 776 blit_done = 1; |
663 frame->Flip( frame, NULL, 0 ); | |
664 | |
665 /* Blit from BES/temp to CRTC2 */ | |
666 c2frame->SetBlittingFlags( c2frame, DSBLIT_NOFX ); | |
667 if (stretch) | |
668 c2frame->StretchBlit( c2frame, frame, NULL, &drect ); | |
669 else | |
670 c2frame->Blit( c2frame, frame, NULL, drect.x, drect.y ); | |
671 } | 777 } |
672 | 778 |
673 vo_draw_text( sub_width, sub_height, draw_alpha ); | 779 vo_draw_text( sub_width, sub_height, draw_alpha ); |
674 | 780 |
675 if (use_spic && osd_changed) { | 781 if (use_spic && osd_changed) { |
683 { | 789 { |
684 if (!use_crtc2) { | 790 if (!use_crtc2) { |
685 /* Flip BES */ | 791 /* Flip BES */ |
686 frame->Flip( frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 ); | 792 frame->Flip( frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 ); |
687 } else { | 793 } else { |
794 if (!blit_done) | |
795 blit_to_screen(); | |
796 | |
688 /* Flip CRTC2 */ | 797 /* Flip CRTC2 */ |
689 c2frame->Flip( c2frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 ); | 798 c2frame->Flip( c2frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 ); |
690 if (!use_spic) | 799 if (!use_spic) |
691 osd_current ^= 3; | 800 osd_current ^= 3; |
692 } | 801 blit_done = 0; |
693 | 802 } |
694 current_buf = 0; | 803 |
804 current_buf = vo_directrendering ? 0 : (current_buf + 1) % num_bufs; | |
695 } | 805 } |
696 | 806 |
697 static void | 807 static void |
698 uninit( void ) | 808 uninit( void ) |
699 { | 809 { |
700 buffer->Release( buffer ); | 810 if (use_input) { |
701 keyboard->Release( keyboard ); | 811 buffer->Release( buffer ); |
812 keyboard->Release( keyboard ); | |
813 } | |
702 | 814 |
703 while (num_bufs--) { | 815 while (num_bufs--) { |
704 frame = bufs[num_bufs]; | 816 frame = bufs[num_bufs]; |
705 frame->Release( frame ); | 817 if (frame) |
818 frame->Release( frame ); | |
819 bufs[num_bufs] = NULL; | |
706 } | 820 } |
707 if (use_bes) { | 821 if (use_bes) { |
708 bes->SetOpacity( bes, 0 ); | 822 bes->SetOpacity( bes, 0 ); |
709 bes->Release( bes ); | 823 bes->Release( bes ); |
710 } | 824 } |
711 if (use_crtc2) { | 825 if (use_crtc2) { |
712 c2frame->Release( c2frame ); | 826 if (c2frame) |
827 c2frame->Release( c2frame ); | |
713 crtc2->SetOpacity( crtc2, 0 ); | 828 crtc2->SetOpacity( crtc2, 0 ); |
714 crtc2->Release( crtc2 ); | 829 crtc2->Release( crtc2 ); |
715 } | 830 c2frame = NULL; |
716 if (use_spic) { | 831 } |
717 subframe->Release( subframe ); | 832 if (use_spic && spic) { |
833 if (subframe) | |
834 subframe->Release( subframe ); | |
718 spic->SetOpacity( spic, 0 ); | 835 spic->SetOpacity( spic, 0 ); |
719 spic->Release( spic ); | 836 spic->Release( spic ); |
837 subframe = NULL; | |
838 spic = NULL; | |
720 } | 839 } |
721 | 840 |
722 /* | 841 /* |
723 * Don't release. Segfault in preinit() if | 842 * Don't release. Segfault in preinit() if |
724 * DirectFBCreate() called more than once. | 843 * DirectFBCreate() called more than once. |
728 } | 847 } |
729 | 848 |
730 static uint32_t | 849 static uint32_t |
731 get_image( mp_image_t *mpi ) | 850 get_image( mp_image_t *mpi ) |
732 { | 851 { |
852 int buf = current_buf; | |
733 void *dst; | 853 void *dst; |
734 int pitch; | 854 int pitch; |
735 | 855 |
736 if (use_bes && | 856 if (use_bes && |
737 (mpi->type == MP_IMGTYPE_STATIC || | 857 (mpi->type == MP_IMGTYPE_STATIC || |
738 mpi->flags & MP_IMGFLAG_READABLE)) | 858 mpi->flags & MP_IMGFLAG_READABLE)) |
739 return VO_FALSE; | 859 return VO_FALSE; |
740 | 860 |
741 if (mpi->flags & MP_IMGFLAG_READABLE && | 861 if (mpi->flags & MP_IMGFLAG_READABLE && |
742 (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP)) { | 862 (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP)) { |
743 int buf = current_buf; | |
744 | |
745 if (num_bufs < 2) | 863 if (num_bufs < 2) |
746 return VO_FALSE; | 864 return VO_FALSE; |
747 | 865 |
748 current_ip_buf ^= 1; | 866 current_ip_buf ^= 1; |
749 | 867 |
752 | 870 |
753 buf = current_ip_buf; | 871 buf = current_ip_buf; |
754 | 872 |
755 if (mpi->type == MP_IMGTYPE_IPB) | 873 if (mpi->type == MP_IMGTYPE_IPB) |
756 buf++; | 874 buf++; |
757 | 875 } |
758 current_buf = buf; | 876 frame = bufs[buf]; |
759 frame = bufs[current_buf]; | 877 frame->Unlock( frame ); |
760 } | 878 |
761 | 879 /* Always use DSLF_READ to preserve system memory copy */ |
762 if (frame->Lock( frame, DSLF_WRITE | (mpi->flags & MP_IMGFLAG_READABLE ? DSLF_READ : 0), | 880 if (frame->Lock( frame, DSLF_WRITE | DSLF_READ, |
763 &dst, &pitch ) != DFB_OK) | 881 &dst, &pitch ) != DFB_OK) |
764 return VO_FALSE; | 882 return VO_FALSE; |
765 | 883 |
766 if ((mpi->width == pitch) || | 884 if ((mpi->width == pitch) || |
767 (mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH))) { | 885 (mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH))) { |
781 mpi->planes[1] = mpi->planes[2] + in_height * pitch / 4; | 899 mpi->planes[1] = mpi->planes[2] + in_height * pitch / 4; |
782 } | 900 } |
783 } | 901 } |
784 | 902 |
785 mpi->flags |= MP_IMGFLAG_DIRECT; | 903 mpi->flags |= MP_IMGFLAG_DIRECT; |
904 mpi->priv = (void *) buf; | |
905 current_buf = buf; | |
786 | 906 |
787 return VO_TRUE; | 907 return VO_TRUE; |
788 } | 908 } |
789 | 909 |
790 frame->Unlock( frame ); | 910 frame->Unlock( frame ); |
795 | 915 |
796 | 916 |
797 static uint32_t | 917 static uint32_t |
798 draw_image( mp_image_t *mpi ) | 918 draw_image( mp_image_t *mpi ) |
799 { | 919 { |
800 if (mpi->flags & (MP_IMGFLAG_DIRECT | MP_IMGFLAG_DRAW_CALLBACK)) | 920 if (mpi->flags & MP_IMGFLAG_DIRECT) { |
921 current_buf = (int) mpi->priv; | |
922 return VO_TRUE; | |
923 } | |
924 if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) | |
801 return VO_TRUE; | 925 return VO_TRUE; |
802 | 926 |
803 if (mpi->flags & MP_IMGFLAG_PLANAR) | 927 if (mpi->flags & MP_IMGFLAG_PLANAR) |
804 return draw_slice( mpi->planes, mpi->stride, | 928 return draw_slice( mpi->planes, mpi->stride, |
805 mpi->w, mpi->h, 0, 0 ); | 929 mpi->w, mpi->h, 0, 0 ); |
890 | 1014 |
891 static uint32_t | 1015 static uint32_t |
892 control( uint32_t request, void *data, ... ) | 1016 control( uint32_t request, void *data, ... ) |
893 { | 1017 { |
894 switch (request) { | 1018 switch (request) { |
1019 case VOCTRL_GUISUPPORT: | |
1020 case VOCTRL_GUI_NOWINDOW: | |
1021 return VO_TRUE; | |
1022 | |
895 case VOCTRL_QUERY_FORMAT: | 1023 case VOCTRL_QUERY_FORMAT: |
896 return query_format( *((uint32_t *) data) ); | 1024 return query_format( *((uint32_t *) data) ); |
897 | 1025 |
898 case VOCTRL_GET_IMAGE: | 1026 case VOCTRL_GET_IMAGE: |
899 return get_image( data ); | 1027 return get_image( data ); |
934 | 1062 |
935 static void | 1063 static void |
936 check_events( void ) | 1064 check_events( void ) |
937 { | 1065 { |
938 DFBInputEvent event; | 1066 DFBInputEvent event; |
1067 | |
1068 if (!use_input) | |
1069 return; | |
939 | 1070 |
940 if (buffer->GetEvent( buffer, DFB_EVENT( &event )) == DFB_OK) { | 1071 if (buffer->GetEvent( buffer, DFB_EVENT( &event )) == DFB_OK) { |
941 if (event.type == DIET_KEYPRESS) { | 1072 if (event.type == DIET_KEYPRESS) { |
942 switch (event.key_symbol) { | 1073 switch (event.key_symbol) { |
943 case DIKS_ESCAPE: | 1074 case DIKS_ESCAPE: |