2002-08-09 17:20:46 +00:00
/*
MPlayer video driver for DirectFramebuffer device
( C ) 2002
Written by Jiri Svoboda < Jiri . Svoboda @ seznam . cz >
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 2 of the License , or ( at your option ) any later version .
This library is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
License along with this library ; if not , write to the
2006-09-01 12:11:11 +00:00
Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor ,
Boston , MA 02110 - 1301 USA .
2002-08-09 17:20:46 +00:00
*/
// directfb includes
# include <directfb.h>
2006-10-08 22:16:38 +00:00
# define DFB_VERSION(a,b,c) (((a)<<16)|((b)<<8)|(c))
2002-08-09 17:20:46 +00:00
// other things
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
2003-04-19 11:25:19 +00:00
2002-11-10 13:57:42 +00:00
# ifdef __linux__
2002-08-09 17:20:46 +00:00
# include <sys/kd.h>
2002-11-10 13:57:42 +00:00
# else
# include <linux/kd.h>
# endif
2002-08-09 17:20:46 +00:00
# include "config.h"
# include "video_out.h"
# include "video_out_internal.h"
# include "fastmemcpy.h"
# include "sub.h"
2003-04-19 11:25:19 +00:00
# include "mp_msg.h"
2002-08-09 17:20:46 +00:00
# include "aspect.h"
2005-06-18 20:27:50 +00:00
# include "subopt-helper.h"
2007-03-29 17:16:11 +00:00
# include "mp_fifo.h"
2002-08-09 17:20:46 +00:00
# ifndef min
# define min(x,y) (((x)<(y))?(x):(y))
# endif
2003-04-27 17:24:26 +00:00
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION > DFB_VERSION(0,9,17)
2003-04-19 11:25:19 +00:00
// triple buffering
# define TRIPLE 1
# endif
2003-04-27 17:24:26 +00:00
2007-12-02 14:06:03 +00:00
static const vo_info_t info = {
2002-08-09 17:20:46 +00:00
" Direct Framebuffer Device " ,
" directfb " ,
" Jiri Svoboda Jiri.Svoboda@seznam.cz " ,
2002-11-10 13:57:42 +00:00
" v 2.0 (for DirectFB version >=0.9.13) "
2002-08-09 17:20:46 +00:00
} ;
2007-12-02 14:39:15 +00:00
const LIBVO_EXTERN ( directfb )
2002-11-11 15:22:10 +00:00
2002-08-09 17:20:46 +00:00
/******************************
* vo_directfb globals *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define DFBCHECK(x...) \
{ \
DFBResult err = x ; \
\
if ( err ! = DFB_OK ) \
{ \
fprintf ( stderr , " %s <%d>: \n \t " , __FILE__ , __LINE__ ) ; \
DirectFBErrorFatal ( # x , err ) ; \
} \
}
/*
* filled by preinit
*/
// main DirectFB handle
static IDirectFB * dfb = NULL ;
// keyboard handle
static IDirectFBInputDevice * keyboard = NULL ;
// A buffer for input events.
static IDirectFBEventBuffer * buffer = NULL ;
/*
* filled during config
*/
// handle of used layer
static IDirectFBDisplayLayer * layer = NULL ;
// surface of used layer
static IDirectFBSurface * primary = NULL ;
static int primarylocked = 0 ;
// handle of temporary surface (if used)
static IDirectFBSurface * frame = NULL ;
static int framelocked = 0 ;
// flipping mode flag (layer/surface)
static int flipping = 0 ;
// scaling flag
static int stretch = 0 ;
2007-11-06 09:49:55 +00:00
// picture position
2002-08-09 17:20:46 +00:00
static int xoffset = 0 , yoffset = 0 ;
// picture size
static int out_width = 0 , out_height = 0 ;
// frame/primary size
static int width = 0 , height = 0 ;
// frame primary format
DFBSurfacePixelFormat pixel_format ;
/*
static void ( * draw_alpha_p ) ( int w , int h , unsigned char * src ,
unsigned char * srca , int stride , unsigned char * dst ,
int dstride ) ;
*/
/******************************
* cmd line parameteres *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* command line/config file options */
2003-04-27 17:24:26 +00:00
static int layer_id = - 1 ;
static int buffer_mode = 1 ;
static int use_input = 1 ;
static int field_parity = - 1 ;
2002-08-09 17:20:46 +00:00
/******************************
* implementation *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-04-01 21:59:54 +00:00
void unlock ( void ) {
2002-08-09 17:20:46 +00:00
if ( frame & & framelocked ) frame - > Unlock ( frame ) ;
if ( primary & & primarylocked ) primary - > Unlock ( primary ) ;
}
2005-06-18 20:27:50 +00:00
static int get_parity ( strarg_t * arg ) {
if ( strargcmp ( arg , " top " ) = = 0 )
return 0 ;
if ( strargcmp ( arg , " bottom " ) = = 0 )
return 1 ;
return - 1 ;
}
static int check_parity ( void * arg ) {
return get_parity ( arg ) ! = - 1 ;
}
static int get_mode ( strarg_t * arg ) {
if ( strargcmp ( arg , " single " ) = = 0 )
return 1 ;
if ( strargcmp ( arg , " double " ) = = 0 )
return 2 ;
if ( strargcmp ( arg , " triple " ) = = 0 )
return 3 ;
return 0 ;
}
static int check_mode ( void * arg ) {
return get_mode ( arg ) ! = 0 ;
}
2002-08-09 17:20:46 +00:00
2005-08-05 01:24:37 +00:00
static int preinit ( const char * arg )
2002-08-09 17:20:46 +00:00
{
2003-04-27 17:24:26 +00:00
DFBResult ret ;
2005-06-18 20:27:50 +00:00
strarg_t mode_str = { 0 , NULL } ;
strarg_t par_str = { 0 , NULL } ;
strarg_t dfb_params = { 0 , NULL } ;
opt_t subopts [ ] = {
{ " input " , OPT_ARG_BOOL , & use_input , NULL } ,
{ " buffermode " , OPT_ARG_STR , & mode_str , check_mode } ,
{ " fieldparity " , OPT_ARG_STR , & par_str , check_parity } ,
{ " layer " , OPT_ARG_INT , & layer_id , NULL } ,
{ " dfbopts " , OPT_ARG_STR , & dfb_params , NULL } ,
{ NULL }
} ;
2002-08-09 17:20:46 +00:00
2007-11-06 09:41:38 +00:00
//mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Preinit entered\n");
2003-04-27 17:24:26 +00:00
2007-11-06 09:49:55 +00:00
if ( dfb ) return 0 ; // we are already initialized!
2003-04-27 17:24:26 +00:00
2005-06-18 20:27:50 +00:00
// set defaults
2003-04-27 17:24:26 +00:00
buffer_mode = 1 + vo_doublebuffering ; // honor -double switch
2005-06-18 20:27:50 +00:00
layer_id = - 1 ;
use_input = 1 ;
field_parity = - 1 ;
if ( subopt_parse ( arg , subopts ) ! = 0 ) {
2003-04-27 17:24:26 +00:00
mp_msg ( MSGT_VO , MSGL_ERR ,
2004-02-21 08:21:42 +00:00
" \n -vo directfb command line help: \n "
2003-04-27 17:24:26 +00:00
" Example: mplayer -vo directfb:layer=1:buffermode=single \n "
" \n Options (use 'no' prefix to disable): \n "
" input Use DirectFB for keyboard input \n "
" \n Other options: \n "
" layer=n \n "
" n=0..xx Use layer with id n for output (0=primary) \n "
" buffermode=(single|double|triple) \n "
" single Use single buffering \n "
" double Use double buffering \n "
" triple Use triple buffering \n "
" fieldparity=(top|bottom) \n "
" top Top field first \n "
" bottom Bottom field first \n "
2005-06-18 20:27:50 +00:00
" dfbopts=<str> \n "
" Specify a parameter list for DirectFB \n "
2003-04-27 17:24:26 +00:00
" \n " ) ;
return - 1 ;
}
2005-06-18 20:27:50 +00:00
if ( mode_str . len )
buffer_mode = get_mode ( & mode_str ) ;
if ( par_str . len )
field_parity = get_parity ( & par_str ) ;
2002-08-09 17:20:46 +00:00
2002-11-10 13:57:42 +00:00
2005-06-18 20:27:50 +00:00
if ( dfb_params . len > 0 )
2002-11-10 13:57:42 +00:00
{
int argc = 2 ;
char arg0 [ 10 ] = " mplayer " ;
2006-07-02 03:59:36 +00:00
char * arg1 = malloc ( dfb_params . len + 7 ) ;
2002-11-10 13:57:42 +00:00
char * argv [ 3 ] ;
char * * a ;
a = & argv [ 0 ] ;
2005-06-18 20:27:50 +00:00
strcpy ( arg1 , " --dfb: " ) ;
strncat ( arg1 , dfb_params . str , dfb_params . len ) ;
2002-11-10 13:57:42 +00:00
argv [ 0 ] = arg0 ;
argv [ 1 ] = arg1 ;
argv [ 2 ] = NULL ;
DFBCHECK ( DirectFBInit ( & argc , & a ) ) ;
2005-06-18 20:27:50 +00:00
free ( arg1 ) ;
2002-11-10 13:57:42 +00:00
} else {
2002-08-09 17:20:46 +00:00
DFBCHECK ( DirectFBInit ( NULL , NULL ) ) ;
2002-11-10 13:57:42 +00:00
}
2002-08-09 17:20:46 +00:00
if ( ( ( directfb_major_version < = 0 ) & &
( directfb_minor_version < = 9 ) & &
( directfb_micro_version < 13 ) ) )
{
2003-04-19 11:25:19 +00:00
mp_msg ( MSGT_VO , MSGL_ERR , " DirectFB: Unsupported DirectFB version \n " ) ;
2002-08-09 17:20:46 +00:00
return 1 ;
}
/*
* ( set options )
*/
2007-11-06 09:49:55 +00:00
// uncomment this if you do not wish to create a new VT for DirectFB
2002-08-09 17:20:46 +00:00
// DFBCHECK (DirectFBSetOption ("no-vt-switch",""));
2007-11-06 09:49:55 +00:00
// uncomment this if you want to allow VT switching
2002-08-09 17:20:46 +00:00
// DFBCHECK (DirectFBSetOption ("vt-switching",""));
// uncomment this if you want to hide gfx cursor (req dfb >=0.9.9)
2004-02-17 16:34:40 +00:00
DFBCHECK ( DirectFBSetOption ( " no-cursor " , " " ) ) ;
2002-08-09 17:20:46 +00:00
// bg color fix
DFBCHECK ( DirectFBSetOption ( " bg-color " , " 00000000 " ) ) ;
/*
* ( Initialize )
*/
DFBCHECK ( DirectFBCreate ( & dfb ) ) ;
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION < DFB_VERSION(0,9,17)
2003-03-05 20:34:29 +00:00
if ( DFB_OK ! = dfb - > SetCooperativeLevel ( dfb , DFSCL_FULLSCREEN ) ) {
2007-11-06 09:54:58 +00:00
mp_msg ( MSGT_VO , MSGL_WARN , " DirectFB: Warning - cannot switch to fullscreen mode " ) ;
2003-03-05 20:34:29 +00:00
} ;
# endif
2002-08-09 17:20:46 +00:00
/*
* ( Get keyboard )
*/
2003-04-27 17:24:26 +00:00
if ( use_input ) {
ret = dfb - > GetInputDevice ( dfb , DIDID_KEYBOARD , & keyboard ) ;
if ( ret = = DFB_OK ) {
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Keyboard init OK \n " ) ;
2003-04-27 17:24:26 +00:00
} else {
keyboard = NULL ;
mp_msg ( MSGT_VO , MSGL_ERR , " DirectFB: Keyboard init FAILED \n " ) ;
2002-08-09 17:20:46 +00:00
}
2003-04-27 17:24:26 +00:00
}
2002-08-09 17:20:46 +00:00
/*
* Create an input buffer for the keyboard .
*/
if ( keyboard ) DFBCHECK ( keyboard - > CreateEventBuffer ( keyboard , & buffer ) ) ;
2007-11-06 09:49:55 +00:00
// just to start clean ...
2002-08-09 17:20:46 +00:00
if ( buffer ) buffer - > Reset ( buffer ) ;
2007-11-06 09:41:38 +00:00
//mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Preinit OK\n");
2002-08-09 17:20:46 +00:00
return 0 ;
}
DFBSurfacePixelFormat convformat ( uint32_t format )
{
// add more formats !!!
switch ( format ) {
case IMGFMT_RGB32 : return DSPF_RGB32 ; break ;
case IMGFMT_BGR32 : return DSPF_RGB32 ; break ;
case IMGFMT_RGB24 : return DSPF_RGB24 ; break ;
case IMGFMT_BGR24 : return DSPF_RGB24 ; break ;
case IMGFMT_RGB16 : return DSPF_RGB16 ; break ;
case IMGFMT_BGR16 : return DSPF_RGB16 ; break ;
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION > DFB_VERSION(0,9,15)
2002-12-29 18:07:18 +00:00
case IMGFMT_RGB15 : return DSPF_ARGB1555 ; break ;
case IMGFMT_BGR15 : return DSPF_ARGB1555 ; break ;
# else
2002-08-09 17:20:46 +00:00
case IMGFMT_RGB15 : return DSPF_RGB15 ; break ;
case IMGFMT_BGR15 : return DSPF_RGB15 ; break ;
2002-12-29 18:07:18 +00:00
# endif
2002-08-09 17:20:46 +00:00
case IMGFMT_YUY2 : return DSPF_YUY2 ; break ;
case IMGFMT_UYVY : return DSPF_UYVY ; break ;
case IMGFMT_YV12 : return DSPF_YV12 ; break ;
case IMGFMT_I420 : return DSPF_I420 ; break ;
// case IMGFMT_IYUV: return DSPF_IYUV; break;
2003-03-05 20:34:29 +00:00
case IMGFMT_RGB8 : return DSPF_RGB332 ; break ;
case IMGFMT_BGR8 : return DSPF_RGB332 ; break ;
2002-08-09 17:20:46 +00:00
default : return 0 ;
}
return 0 ;
}
typedef struct enum1_s {
uint32_t format ;
int scale ;
int result ;
unsigned int id ;
unsigned int width ;
unsigned int height ;
int setsize ;
} enum1_t ;
DFBEnumerationResult test_format_callback ( unsigned int id ,
DFBDisplayLayerDescription desc ,
void * data )
{
enum1_t * params = ( enum1_t * ) data ;
IDirectFBDisplayLayer * layer ;
DFBResult ret ;
2002-11-10 13:57:42 +00:00
if ( ( layer_id = = - 1 ) | | ( layer_id = = id ) ) {
2002-08-09 17:20:46 +00:00
ret = dfb - > GetDisplayLayer ( dfb , id , & layer ) ;
if ( ret ) {
DirectFBError ( " dfb->GetDisplayLayer failed " , ret ) ;
return DFENUM_OK ;
} else {
DFBDisplayLayerConfig dlc ;
2003-03-05 20:34:29 +00:00
2002-08-09 17:20:46 +00:00
if ( params - > setsize ) {
dlc . flags = DLCONF_WIDTH | DLCONF_HEIGHT ;
dlc . width = params - > width ;
dlc . height = params - > height ;
layer - > SetConfiguration ( layer , & dlc ) ;
}
dlc . flags = DLCONF_PIXELFORMAT ;
dlc . pixelformat = convformat ( params - > format ) ;
2003-03-02 15:56:42 +00:00
2002-08-09 17:20:46 +00:00
layer - > SetOpacity ( layer , 0 ) ;
2003-03-02 15:56:42 +00:00
2002-08-09 17:20:46 +00:00
ret = layer - > TestConfiguration ( layer , & dlc , NULL ) ;
layer - > Release ( layer ) ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Test format - layer %i scale/pos %i \n " , id , ( desc . caps & DLCAPS_SCREEN_LOCATION ) ) ;
2002-08-09 17:20:46 +00:00
2003-03-02 15:56:42 +00:00
if ( ret = = DFB_OK ) {
2002-08-09 17:20:46 +00:00
// printf("Test OK\n");
if ( params - > result ) {
if ( ( ! params - > scale ) & & ( desc . caps & DLCAPS_SCREEN_LOCATION ) ) {
params - > scale = 1 ;
params - > id = id ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Test format - added layer %i scale/pos %i \n " , id , ( desc . caps & DLCAPS_SCREEN_LOCATION ) ) ;
2002-08-09 17:20:46 +00:00
}
} else {
params - > result = 1 ;
params - > id = id ;
if ( desc . caps & DLCAPS_SCREEN_LOCATION ) params - > scale = 1 ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Test format - added layer %i scale/pos %i \n " , id , ( desc . caps & DLCAPS_SCREEN_LOCATION ) ) ;
2002-08-09 17:20:46 +00:00
} ;
} ;
} ;
2002-11-10 13:57:42 +00:00
} ;
2003-03-02 15:56:42 +00:00
2002-08-09 17:20:46 +00:00
return DFENUM_OK ;
}
2005-08-05 01:24:37 +00:00
static int query_format ( uint32_t format )
2002-08-09 17:20:46 +00:00
{
2007-11-06 09:49:55 +00:00
int ret = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD ; // osd should be removed the in future -> will be handled outside...
2002-08-09 17:20:46 +00:00
enum1_t params ;
if ( ! convformat ( format ) ) return 0 ;
2007-11-06 09:49:55 +00:00
// temporarily disable YV12
2002-08-09 17:20:46 +00:00
// if (format == IMGFMT_YV12) return 0;
// if (format == IMGFMT_I420) return 0;
if ( format = = IMGFMT_IYUV ) return 0 ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Format query: %s \n " , vo_format_name ( format ) ) ;
2002-08-09 17:20:46 +00:00
params . format = format ;
params . scale = 0 ;
params . result = 0 ;
params . setsize = 0 ;
DFBCHECK ( dfb - > EnumDisplayLayers ( dfb , test_format_callback , & params ) ) ;
if ( params . result ) {
if ( params . scale ) ret | = VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN ;
return ret ;
}
return 0 ;
}
typedef struct videomode_s {
int width ;
int height ;
int out_width ;
int out_height ;
int overx ;
int overy ;
int bpp ;
} videomode_t ;
DFBEnumerationResult video_modes_callback ( unsigned int width , unsigned int height , unsigned int bpp , void * data )
{
videomode_t * params = ( videomode_t * ) data ;
int overx = 0 , overy = 0 , closer = 0 , over = 0 ;
int we_are_under = 0 ;
2007-11-06 09:41:38 +00:00
//mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Validator entered %i %i %i\n",width,height,bpp);
2002-08-09 17:20:46 +00:00
overx = width - params - > out_width ;
overy = height - params - > out_height ;
if ( ! params - > width ) {
params - > width = width ;
params - > height = height ;
params - > overx = overx ;
params - > overy = overy ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Mode added %i %i %i \n " , width , height , bpp ) ;
2002-08-09 17:20:46 +00:00
}
if ( ( params - > overy < 0 ) | | ( params - > overx < 0 ) ) we_are_under = 1 ; // stored mode is smaller than req mode
if ( abs ( overx * overy ) < abs ( params - > overx * params - > overy ) ) closer = 1 ; // current mode is closer to desired res
if ( ( overx > = 0 ) & & ( overy > = 0 ) ) over = 1 ; // current mode is bigger or equaul to desired res
if ( ( closer & & ( over | | we_are_under ) ) | | ( we_are_under & & over ) ) {
params - > width = width ;
params - > height = height ;
params - > overx = overx ;
params - > overy = overy ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Better mode added %i %i %i \n " , width , height , bpp ) ;
2002-08-09 17:20:46 +00:00
} ;
return DFENUM_OK ;
}
# define CONFIG_ERROR -1
2005-08-05 01:24:37 +00:00
static int config ( uint32_t s_width , uint32_t s_height , uint32_t d_width ,
2005-04-18 15:52:38 +00:00
uint32_t d_height , uint32_t flags , char * title ,
2002-09-04 21:53:38 +00:00
uint32_t format )
2002-08-09 17:20:46 +00:00
{
/*
* ( Locals )
*/
// decode flags
2005-04-18 15:52:38 +00:00
int fs = flags & VOFLAG_FULLSCREEN ;
int vm = flags & VOFLAG_MODESWITCHING ;
2002-08-09 17:20:46 +00:00
DFBSurfaceDescription dsc ;
DFBResult ret ;
DFBDisplayLayerConfig dlc ;
DFBSurfaceCapabilities caps ;
enum1_t params ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Config entered [%ix%i] \n " , s_width , s_height ) ;
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: With requested format: %s \n " , vo_format_name ( format ) ) ;
2003-04-19 11:25:19 +00:00
2007-11-06 09:49:55 +00:00
// initial cleanup
2002-08-09 17:20:46 +00:00
if ( frame ) {
frame - > Release ( frame ) ;
frame = NULL ;
}
if ( primary ) {
primary - > Release ( primary ) ;
primary = NULL ;
}
if ( layer ) {
layer - > Release ( layer ) ;
layer = NULL ;
}
// vm things
if ( vm ) {
videomode_t params ;
params . out_width = d_width ;
params . out_height = d_height ;
params . width = 0 ;
params . height = 0 ;
switch ( format ) {
2003-03-02 15:56:42 +00:00
case IMGFMT_RGB32 :
case IMGFMT_BGR32 :
2002-08-09 17:20:46 +00:00
params . bpp = 32 ;
break ;
2003-03-02 15:56:42 +00:00
case IMGFMT_RGB24 :
case IMGFMT_BGR24 :
2002-08-09 17:20:46 +00:00
params . bpp = 24 ;
break ;
case IMGFMT_RGB16 :
case IMGFMT_BGR16 :
case IMGFMT_RGB15 :
case IMGFMT_BGR15 :
params . bpp = 16 ;
break ;
2003-03-02 15:56:42 +00:00
default : params . bpp = 0 ;
}
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Config - trying to change videomode \n " ) ;
2002-08-09 17:20:46 +00:00
DFBCHECK ( dfb - > EnumVideoModes ( dfb , video_modes_callback , & params ) ) ;
ret = dfb - > SetVideoMode ( dfb , params . width , params . height , params . bpp ) ;
if ( ret ) {
ret = dfb - > SetVideoMode ( dfb , params . width , params . height , 24 ) ;
if ( ret ) {
ret = dfb - > SetVideoMode ( dfb , params . width , params . height , 32 ) ;
if ( ret ) {
ret = dfb - > SetVideoMode ( dfb , params . width , params . height , 16 ) ;
if ( ret ) {
ret = dfb - > SetVideoMode ( dfb , params . width , params . height , 8 ) ;
}
}
}
}
} // vm end
2007-11-06 09:49:55 +00:00
// just to be sure clear primary layer
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION > DFB_VERSION(0,9,13)
2003-09-07 19:42:35 +00:00
ret = dfb - > GetDisplayLayer ( dfb , DLID_PRIMARY , & layer ) ;
if ( ret = = DFB_OK ) {
ret = layer - > GetSurface ( layer , & primary ) ;
if ( ret = = DFB_OK ) {
primary - > Clear ( primary , 0 , 0 , 0 , 0xff ) ;
ret = primary - > Flip ( primary , NULL , 0 ) ;
if ( ret = = DFB_OK ) {
primary - > Clear ( primary , 0 , 0 , 0 , 0xff ) ;
}
primary - > Release ( primary ) ;
}
primary = NULL ;
layer - > Release ( layer ) ;
}
layer = NULL ;
# endif
2002-08-09 17:20:46 +00:00
// find best layer
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Config - looking for suitable layer \n " ) ;
2002-08-09 17:20:46 +00:00
params . format = format ;
params . scale = 0 ;
params . result = 0 ;
params . width = s_width ;
params . height = s_height ;
params . setsize = 1 ;
DFBCHECK ( dfb - > EnumDisplayLayers ( dfb , test_format_callback , & params ) ) ;
if ( ! params . result ) {
2003-04-19 11:25:19 +00:00
mp_msg ( MSGT_VO , MSGL_ERR , " DirectFB: ConfigError - no suitable layer found \n " ) ;
2002-08-09 17:20:46 +00:00
params . id = DLID_PRIMARY ;
2003-03-02 15:56:42 +00:00
}
2002-08-09 17:20:46 +00:00
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Config - layer %i \n " , params . id ) ;
2002-08-09 17:20:46 +00:00
2003-03-05 20:34:29 +00:00
// setup layer
2002-08-09 17:20:46 +00:00
DFBCHECK ( dfb - > GetDisplayLayer ( dfb , params . id , & layer ) ) ;
2003-03-05 20:34:29 +00:00
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION > DFB_VERSION(0,9,16)
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Config - switching layer to exclusive mode \n " ) ;
2003-03-05 20:34:29 +00:00
ret = layer - > SetCooperativeLevel ( layer , DLSCL_EXCLUSIVE ) ;
2002-08-09 17:20:46 +00:00
2003-03-05 20:34:29 +00:00
if ( DFB_OK ! = ret ) {
2007-11-06 09:54:58 +00:00
mp_msg ( MSGT_VO , MSGL_WARN , " DirectFB: Warning - cannot switch layer to exclusive mode. This could cause \n problems. You may need to select correct pixel format manually! \n " ) ;
2003-03-05 20:34:29 +00:00
DirectFBError ( " MPlayer - Switch layer to exlusive mode. " , ret ) ;
} ;
# endif
2002-08-09 17:20:46 +00:00
if ( params . scale ) {
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Config - changing layer configuration (size) \n " ) ;
2002-08-09 17:20:46 +00:00
dlc . flags = DLCONF_WIDTH | DLCONF_HEIGHT ;
dlc . width = s_width ;
dlc . height = s_height ;
2003-03-02 15:56:42 +00:00
2002-08-09 17:20:46 +00:00
ret = layer - > SetConfiguration ( layer , & dlc ) ;
2003-03-02 15:56:42 +00:00
2003-03-05 20:34:29 +00:00
if ( ret ) {
2003-04-19 11:25:19 +00:00
mp_msg ( MSGT_VO , MSGL_ERR , " DirectFB: ConfigError in layer configuration (size) \n " ) ;
2003-03-05 20:34:29 +00:00
DirectFBError ( " MPlayer - Layer size change. " , ret ) ;
} ;
2002-08-09 17:20:46 +00:00
}
2007-11-06 09:49:55 +00:00
// look if we need to change the pixel format of the layer
// and just to be sure also fetch all layer properties
2003-03-02 15:56:42 +00:00
dlc . flags = DLCONF_PIXELFORMAT | DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_OPTIONS | DLCONF_BUFFERMODE ;
2003-03-05 20:34:29 +00:00
2003-03-02 15:56:42 +00:00
ret = layer - > GetConfiguration ( layer , & dlc ) ;
dlc . flags = DLCONF_PIXELFORMAT | DLCONF_WIDTH | DLCONF_HEIGHT ;
2002-08-09 17:20:46 +00:00
if ( ret ) {
2003-04-19 11:25:19 +00:00
mp_msg ( MSGT_VO , MSGL_WARN , " DirectFB: Warning - could not get layer properties! \n " ) ;
} else {
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Layer reports format:%x \n " , dlc . pixelformat ) ;
2003-03-02 15:56:42 +00:00
}
if ( ( dlc . pixelformat ! = convformat ( params . format ) ) | | ( ret ! = DFB_OK ) ) {
dlc . flags = DLCONF_PIXELFORMAT ;
dlc . pixelformat = convformat ( params . format ) ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Desired pixelformat: %x \n " , dlc . pixelformat ) ;
2003-03-02 15:56:42 +00:00
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Config - changing layer configuration (format) \n " ) ;
2003-03-02 15:56:42 +00:00
ret = layer - > SetConfiguration ( layer , & dlc ) ;
if ( ret ) {
2003-03-05 20:34:29 +00:00
unsigned int bpp ;
2003-04-19 11:25:19 +00:00
mp_msg ( MSGT_VO , MSGL_ERR , " DirectFB: ConfigError in layer configuration (format, flags=%x) \n " , dlc . flags ) ;
2003-03-05 20:34:29 +00:00
DirectFBError ( " MPlayer - layer pixelformat change " , ret ) ;
2007-11-06 09:49:55 +00:00
// ugly fbdev workaround - try to switch pixelformat via videomode change
2003-03-05 20:34:29 +00:00
switch ( dlc . pixelformat ) {
case DSPF_ARGB :
case DSPF_RGB32 : bpp = 32 ; break ;
case DSPF_RGB24 : bpp = 24 ; break ;
case DSPF_RGB16 : bpp = 16 ; break ;
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION > DFB_VERSION(0,9,15)
2003-03-05 20:34:29 +00:00
case DSPF_ARGB1555 : bpp = 15 ; break ;
# else
case DSPF_RGB15 : bpp = 15 ; break ;
# endif
case DSPF_RGB332 : bpp = 8 ; break ;
}
switch ( dlc . pixelformat ) {
case DSPF_ARGB :
case DSPF_RGB32 :
case DSPF_RGB24 :
case DSPF_RGB16 :
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION > DFB_VERSION(0,9,15)
2003-03-05 20:34:29 +00:00
case DSPF_ARGB1555 :
# else
case DSPF_RGB15 :
# endif
case DSPF_RGB332 :
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_V , " DirectFB: Trying to recover via videomode change (VM). \n " ) ;
2003-03-05 20:34:29 +00:00
// get size
dlc . flags = DLCONF_WIDTH | DLCONF_HEIGHT ;
if ( DFB_OK = = layer - > GetConfiguration ( layer , & dlc ) ) {
// try to set videomode
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_V , " DirectFB: Videomode %ix%i BPP %i \n " , dlc . width , dlc . height , bpp ) ;
2003-03-05 20:34:29 +00:00
ret = dfb - > SetVideoMode ( dfb , dlc . width , dlc . height , bpp ) ;
if ( ret ) DirectFBError ( " MPlayer - VM - pixelformat change " , ret ) ;
} ;
//get current pixel format
dlc . flags = DLCONF_PIXELFORMAT ;
ret = layer - > GetConfiguration ( layer , & dlc ) ;
if ( ret ) {
DirectFBError ( " MPlayer - VM - Layer->GetConfiguration " , ret ) ;
} else {
2007-11-06 09:54:58 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Layer now has pixelformat [%x] \n " , dlc . pixelformat ) ;
2003-03-05 20:34:29 +00:00
} ;
2007-11-06 09:49:55 +00:00
// check if we were succesful
2003-03-05 20:34:29 +00:00
if ( ( dlc . pixelformat ! = convformat ( params . format ) ) | | ( ret ! = DFB_OK ) ) {
2003-04-19 11:25:19 +00:00
mp_msg ( MSGT_VO , MSGL_INFO , " DirectFB: Recovery failed!. \n " ) ;
2003-03-05 20:34:29 +00:00
return CONFIG_ERROR ;
}
break ;
default : return CONFIG_ERROR ;
} ;
2003-03-02 15:56:42 +00:00
} ;
2002-08-09 17:20:46 +00:00
} ;
// flipping of layer
2007-11-06 09:49:55 +00:00
// try triple, double... buffering
2002-08-09 17:20:46 +00:00
dlc . flags = DLCONF_BUFFERMODE ;
2003-04-19 11:25:19 +00:00
# ifdef TRIPLE
2003-04-27 17:24:26 +00:00
if ( buffer_mode > 2 ) {
dlc . buffermode = DLBM_TRIPLE ;
ret = layer - > SetConfiguration ( layer , & dlc ) ;
} else {
ret = ! DFB_OK ;
}
2003-04-19 11:25:19 +00:00
if ( ret ! = DFB_OK ) {
# endif
2003-04-27 17:24:26 +00:00
if ( buffer_mode > 1 ) {
2003-04-19 11:25:19 +00:00
dlc . buffermode = DLBM_BACKVIDEO ;
ret = layer - > SetConfiguration ( layer , & dlc ) ;
if ( ret ! = DFB_OK ) {
dlc . buffermode = DLBM_BACKSYSTEM ;
ret = layer - > SetConfiguration ( layer , & dlc ) ;
2002-08-09 17:20:46 +00:00
}
2003-04-19 11:25:19 +00:00
}
if ( ret = = DFB_OK ) {
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_V , " DirectFB: Double buffering is active \n " ) ;
2003-04-19 11:25:19 +00:00
}
# ifdef TRIPLE
} else {
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_V , " DirectFB: Triple buffering is active \n " ) ;
2003-04-19 11:25:19 +00:00
}
# endif
2002-08-09 17:20:46 +00:00
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION > DFB_VERSION(0,9,16)
2003-04-27 17:24:26 +00:00
if ( field_parity ! = - 1 ) {
dlc . flags = DLCONF_OPTIONS ;
ret = layer - > GetConfiguration ( layer , & dlc ) ;
if ( ret = = DFB_OK ) {
dlc . options | = DLOP_FIELD_PARITY ;
ret = layer - > SetConfiguration ( layer , & dlc ) ;
if ( ret = = DFB_OK ) {
layer - > SetFieldParity ( layer , field_parity ) ;
}
}
}
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Requested field parity: " ) ;
2004-02-17 16:34:40 +00:00
switch ( field_parity ) {
case - 1 :
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " Don't care \n " ) ;
2004-02-17 16:34:40 +00:00
break ;
case 0 :
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " Top field first \n " ) ;
2004-02-17 16:34:40 +00:00
break ;
case 1 :
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " Bottom field first \n " ) ;
2004-02-17 16:34:40 +00:00
break ;
}
2003-04-27 17:24:26 +00:00
# endif
2002-08-09 17:20:46 +00:00
// get layer surface
ret = layer - > GetSurface ( layer , & primary ) ;
if ( ret ) {
2003-04-19 11:25:19 +00:00
mp_msg ( MSGT_VO , MSGL_ERR , " DirectFB: ConfigError - could not get surface \n " ) ;
2007-11-06 09:49:55 +00:00
return CONFIG_ERROR ; // what shall we report on failure?
2002-08-09 17:20:46 +00:00
}
// test surface for flipping
DFBCHECK ( primary - > GetCapabilities ( primary , & caps ) ) ;
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION > DFB_VERSION(0,9,13)
2003-04-19 11:25:19 +00:00
primary - > Clear ( primary , 0 , 0 , 0 , 0xff ) ;
2002-11-10 13:57:42 +00:00
# endif
2002-08-09 17:20:46 +00:00
flipping = 0 ;
2003-04-27 17:24:26 +00:00
if ( caps & ( DSCAPS_FLIPPING
# ifdef TRIPLE
| DSCAPS_TRIPLE
# endif
) ) {
2002-08-09 17:20:46 +00:00
ret = primary - > Flip ( primary , NULL , 0 ) ;
if ( ret = = DFB_OK ) {
2004-02-17 16:34:40 +00:00
flipping = 1 ;
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION > DFB_VERSION(0,9,13)
2003-04-19 11:25:19 +00:00
primary - > Clear ( primary , 0 , 0 , 0 , 0xff ) ;
# ifdef TRIPLE
// if we have 3 buffers clean once more
if ( caps & DSCAPS_TRIPLE ) {
primary - > Flip ( primary , NULL , 0 ) ;
primary - > Clear ( primary , 0 , 0 , 0 , 0xff ) ;
2004-02-17 16:34:40 +00:00
flipping = 2 ;
2003-04-19 11:25:19 +00:00
}
# endif
2002-11-10 13:57:42 +00:00
# endif
2002-08-09 17:20:46 +00:00
}
} ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Config - flipping = %i \n " , flipping ) ;
2002-08-09 17:20:46 +00:00
// is scale needed ? Aspect ratio and layer pos/size
// get surface size
DFBCHECK ( primary - > GetSize ( primary , & width , & height ) ) ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Config - surface size = %ix%i \n " , width , height ) ;
2002-08-09 17:20:46 +00:00
aspect_save_orig ( s_width , s_height ) ;
aspect_save_prescale ( d_width , d_height ) ;
if ( params . scale ) {
aspect_save_screenres ( 10000 , 10000 ) ;
aspect ( & out_width , & out_height , A_ZOOM ) ;
ret = layer - > SetScreenLocation ( layer , ( 1 - ( float ) out_width / 10000 ) / 2 , ( 1 - ( float ) out_height / 10000 ) / 2 , ( ( float ) out_width / 10000 ) , ( ( float ) out_height / 10000 ) ) ;
2003-04-19 11:25:19 +00:00
if ( ret ) mp_msg ( MSGT_VO , MSGL_ERR , " DirectFB: ConfigError in layer configuration (position) \n " ) ;
2002-08-09 17:20:46 +00:00
xoffset = 0 ;
yoffset = 0 ;
} else {
aspect_save_screenres ( width , height ) ;
if ( fs ) /* -fs */
aspect ( & out_width , & out_height , A_ZOOM ) ;
else
aspect ( & out_width , & out_height , A_NOZOOM ) ;
xoffset = ( width - out_width ) / 2 ;
yoffset = ( height - out_height ) / 2 ;
}
if ( ( ( s_width = = out_width ) & & ( s_height = = out_height ) ) | | ( params . scale ) ) {
stretch = 0 ;
} else {
stretch = 1 ;
}
// temporary buffer in case of not flipping or scaling
if ( ( ! flipping ) | | stretch ) {
DFBCHECK ( primary - > GetPixelFormat ( primary , & dsc . pixelformat ) ) ;
dsc . flags = DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_WIDTH ;
dsc . width = s_width ;
dsc . height = s_height ;
DFBCHECK ( dfb - > CreateSurface ( dfb , & dsc , & frame ) ) ;
DFBCHECK ( frame - > GetSize ( frame , & width , & height ) ) ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Frame is active. \n " ) ;
2002-08-09 17:20:46 +00:00
}
// get format for draw_alpha - should be removed soon - osd will be rendered outside vo driver
if ( frame ) {
DFBCHECK ( frame - > GetPixelFormat ( frame , & pixel_format ) ) ;
} else {
DFBCHECK ( primary - > GetPixelFormat ( primary , & pixel_format ) ) ;
} ;
// finally turn on layer
layer - > SetOpacity ( layer , 255 ) ;
2007-11-06 09:41:38 +00:00
//mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Config finished [%ix%i] - [%ix%i]\n",out_width,out_height,width,height);
2002-08-09 17:20:46 +00:00
return 0 ;
}
2004-10-28 01:15:53 +00:00
# include "osdep/keycodes.h"
2002-08-09 17:20:46 +00:00
static void check_events ( void )
{
if ( buffer ) {
DFBInputEvent event ;
2006-03-27 07:22:48 +00:00
//if ( mp_msg_test(MSGT_VO,MSGL_V) ) printf ("DirectFB: Check events entered\n");
2002-08-09 17:20:46 +00:00
if ( buffer - > GetEvent ( buffer , DFB_EVENT ( & event ) ) = = DFB_OK ) {
if ( event . type = = DIET_KEYPRESS ) {
switch ( event . key_symbol ) {
case DIKS_ESCAPE :
2005-11-02 21:50:55 +00:00
mplayer_put_key ( KEY_ESC ) ;
2002-08-09 17:20:46 +00:00
break ;
case DIKS_PAGE_UP : mplayer_put_key ( KEY_PAGE_UP ) ; break ;
case DIKS_PAGE_DOWN : mplayer_put_key ( KEY_PAGE_DOWN ) ; break ;
case DIKS_CURSOR_UP : mplayer_put_key ( KEY_UP ) ; break ;
case DIKS_CURSOR_DOWN : mplayer_put_key ( KEY_DOWN ) ; break ;
case DIKS_CURSOR_LEFT : mplayer_put_key ( KEY_LEFT ) ; break ;
case DIKS_CURSOR_RIGHT : mplayer_put_key ( KEY_RIGHT ) ; break ;
case DIKS_INSERT : mplayer_put_key ( KEY_INSERT ) ; break ;
case DIKS_DELETE : mplayer_put_key ( KEY_DELETE ) ; break ;
case DIKS_HOME : mplayer_put_key ( KEY_HOME ) ; break ;
case DIKS_END : mplayer_put_key ( KEY_END ) ; break ;
default : mplayer_put_key ( event . key_symbol ) ;
} ;
} ;
} ;
// empty buffer, because of repeating (keyboard repeat is faster than key handling
// and this causes problems during seek)
2007-11-06 09:49:55 +00:00
// temporary workaround should be solved in the future
2002-08-09 17:20:46 +00:00
buffer - > Reset ( buffer ) ;
}
2006-03-27 07:22:48 +00:00
//if ( mp_msg_test(MSGT_VO,MSGL_V) ) printf ("DirectFB: Check events finished\n");
2002-08-09 17:20:46 +00:00
}
static void flip_page ( void )
{
DFBSurfaceBlittingFlags flags = DSBLIT_NOFX ;
unlock ( ) ; // unlock frame & primary
2006-03-27 07:22:48 +00:00
// if ( mp_msg_test(MSGT_VO,MSGL_V) ) printf("DirectFB: Flip page entered");
2002-08-09 17:20:46 +00:00
DFBCHECK ( primary - > SetBlittingFlags ( primary , flags ) ) ;
if ( frame ) {
if ( stretch ) {
DFBRectangle rect ;
rect . x = xoffset ;
rect . y = yoffset ;
rect . w = out_width ;
rect . h = out_height ;
DFBCHECK ( primary - > StretchBlit ( primary , frame , NULL , & rect ) ) ;
} else {
DFBCHECK ( primary - > Blit ( primary , frame , NULL , xoffset , yoffset ) ) ;
} ;
} ;
2004-02-17 16:34:40 +00:00
# ifdef TRIPLE
switch ( flipping ) {
case 1 : DFBCHECK ( primary - > Flip ( primary , NULL , DSFLIP_WAIT ) ) ;
break ;
case 2 : DFBCHECK ( primary - > Flip ( primary , NULL , DSFLIP_ONSYNC ) ) ;
break ;
2007-11-06 09:49:55 +00:00
default : ; // should never be reached
2004-02-17 16:34:40 +00:00
}
# else
2002-08-09 17:20:46 +00:00
if ( flipping ) {
DFBCHECK ( primary - > Flip ( primary , NULL , DSFLIP_WAITFORSYNC ) ) ;
}
2004-02-17 16:34:40 +00:00
# endif
2002-08-09 17:20:46 +00:00
}
static void uninit ( void )
{
2007-11-06 09:41:38 +00:00
//mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Uninit entered\n");
2002-08-09 17:20:46 +00:00
unlock ( ) ;
/*
* ( Release )
*/
2003-04-27 17:24:26 +00:00
/*
2003-04-19 11:25:19 +00:00
mp_msg ( MSGT_VO , MSGL_INFO , " DirectFB: Releasing buffer \n " ) ;
2002-08-09 17:20:46 +00:00
if ( buffer ) buffer - > Release ( buffer ) ;
2003-04-19 11:25:19 +00:00
mp_msg ( MSGT_VO , MSGL_INFO , " DirectFB: Releasing keyboard \n " ) ;
2002-08-09 17:20:46 +00:00
if ( keyboard ) keyboard - > Release ( keyboard ) ;
2003-04-27 17:24:26 +00:00
*/
2002-08-09 17:20:46 +00:00
if ( frame ) {
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Releasing frame \n " ) ;
2002-08-09 17:20:46 +00:00
frame - > Release ( frame ) ;
2003-04-27 17:24:26 +00:00
frame = NULL ;
2002-08-09 17:20:46 +00:00
} ;
// switch off BES
// if (layer) layer->SetOpacity(layer,0);
2003-04-27 17:24:26 +00:00
if ( layer ) {
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Releasing layer \n " ) ;
2003-04-27 17:24:26 +00:00
layer - > Release ( layer ) ;
layer = NULL ;
}
2002-08-09 17:20:46 +00:00
2003-04-27 17:24:26 +00:00
if ( primary ) {
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: Releasing primary \n " ) ;
2003-04-27 17:24:26 +00:00
primary - > Release ( primary ) ;
primary = NULL ;
}
2002-08-09 17:20:46 +00:00
2003-04-27 17:24:26 +00:00
/* mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Releasing DirectFB library\n");
dfb - > Release ( dfb ) ;
*/
2007-11-06 09:41:38 +00:00
//mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Uninit done.\n");
2002-08-09 17:20:46 +00:00
}
static uint32_t directfb_set_video_eq ( char * data , int value ) //data==name
{
DFBColorAdjustment ca ;
float factor = ( float ) 0xffff / 200.0 ;
DFBDisplayLayerDescription desc ;
unlock ( ) ;
if ( layer ) {
layer - > GetDescription ( layer , & desc ) ;
ca . flags = DCAF_NONE ;
if ( ! strcmp ( data , " brightness " ) ) {
if ( desc . caps & DLCAPS_BRIGHTNESS ) {
ca . brightness = value * factor + 0x8000 ;
ca . flags | = DCAF_BRIGHTNESS ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: SetVEq Brightness 0x%X %i \n " , ca . brightness , value ) ;
2002-08-09 17:20:46 +00:00
} else return VO_FALSE ;
}
if ( ! strcmp ( data , " contrast " ) ) {
if ( ( desc . caps & DLCAPS_CONTRAST ) ) {
ca . contrast = value * factor + 0x8000 ;
ca . flags | = DCAF_CONTRAST ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: SetVEq Contrast 0x%X %i \n " , ca . contrast , value ) ;
2002-08-09 17:20:46 +00:00
} else return VO_FALSE ;
}
if ( ! strcmp ( data , " hue " ) ) {
if ( ( desc . caps & DLCAPS_HUE ) ) {
ca . hue = value * factor + 0x8000 ;
ca . flags | = DCAF_HUE ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: SetVEq Hue 0x%X %i \n " , ca . hue , value ) ;
2002-08-09 17:20:46 +00:00
} else return VO_FALSE ;
}
if ( ! strcmp ( data , " saturation " ) ) {
if ( ( desc . caps & DLCAPS_SATURATION ) ) {
ca . saturation = value * factor + 0x8000 ;
ca . flags | = DCAF_SATURATION ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: SetVEq Saturation 0x%X %i \n " , ca . saturation , value ) ;
2002-08-09 17:20:46 +00:00
} else return VO_FALSE ;
}
if ( ca . flags ! = DCAF_NONE ) {
layer - > SetColorAdjustment ( layer , & ca ) ;
return VO_TRUE ;
}
}
return VO_FALSE ;
}
static uint32_t directfb_get_video_eq ( char * data , int * value ) // data==name
{
DFBColorAdjustment ca ;
float factor = 200.0 / ( float ) 0xffff ;
DFBDisplayLayerDescription desc ;
if ( layer ) {
unlock ( ) ;
layer - > GetDescription ( layer , & desc ) ;
layer - > GetColorAdjustment ( layer , & ca ) ;
if ( ! strcmp ( data , " brightness " ) ) {
if ( desc . caps & DLCAPS_BRIGHTNESS ) {
* value = ( int ) ( ( ca . brightness - 0x8000 ) * factor ) ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: GetVEq Brightness 0x%X %i \n " , ca . brightness , * value ) ;
2002-08-09 17:20:46 +00:00
return VO_TRUE ;
} else return VO_FALSE ;
}
if ( ! strcmp ( data , " contrast " ) ) {
if ( ( desc . caps & DLCAPS_CONTRAST ) ) {
* value = ( int ) ( ( ca . contrast - 0x8000 ) * factor ) ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: GetVEq Contrast 0x%X %i \n " , ca . contrast , * value ) ;
2002-08-09 17:20:46 +00:00
return VO_TRUE ;
} else return VO_FALSE ;
}
if ( ! strcmp ( data , " hue " ) ) {
if ( ( desc . caps & DLCAPS_HUE ) ) {
* value = ( int ) ( ( ca . hue - 0x8000 ) * factor ) ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: GetVEq Hue 0x%X %i \n " , ca . hue , * value ) ;
2002-08-09 17:20:46 +00:00
return VO_TRUE ;
} else return VO_FALSE ;
}
if ( ! strcmp ( data , " saturation " ) ) {
if ( ( desc . caps & DLCAPS_SATURATION ) ) {
* value = ( int ) ( ( ca . saturation - 0x8000 ) * factor ) ;
2007-11-06 09:41:38 +00:00
mp_msg ( MSGT_VO , MSGL_DBG2 , " DirectFB: GetVEq Saturation 0x%X %i \n " , ca . saturation , * value ) ;
2002-08-09 17:20:46 +00:00
return VO_TRUE ;
} else return VO_FALSE ;
}
}
return VO_FALSE ;
}
static uint32_t get_image ( mp_image_t * mpi )
{
int err ;
void * dst ;
int pitch ;
2006-03-27 07:22:48 +00:00
// if ( mp_msg_test(MSGT_VO,MSGL_V) ) printf("DirectFB: get_image() called\n");
2003-04-19 11:25:19 +00:00
if ( mpi - > flags & MP_IMGFLAG_READABLE ) return VO_FALSE ; // slow video ram
2002-08-09 17:20:46 +00:00
if ( mpi - > type = = MP_IMGTYPE_STATIC ) return VO_FALSE ; // it is not static
// printf("width=%d vs. pitch=%d, flags=0x%X \n",mpi->width,pitch,mpi->flags);
2002-08-13 08:41:49 +00:00
if ( ( mpi - > width = = pitch ) | |
2002-08-09 17:20:46 +00:00
( mpi - > flags & ( MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH ) ) ) {
// we're lucky or codec accepts stride => ok, let's go!
if ( frame ) {
2003-04-27 17:24:26 +00:00
err = frame - > Lock ( frame , DSLF_WRITE | DSLF_READ , & dst , & pitch ) ;
2002-08-09 17:20:46 +00:00
framelocked = 1 ;
} else {
err = primary - > Lock ( primary , DSLF_WRITE , & dst , & pitch ) ;
primarylocked = 1 ;
}
if ( err ) {
2003-04-19 11:25:19 +00:00
mp_msg ( MSGT_VO , MSGL_ERR , " DirectFB: DR lock failed! " ) ;
2002-08-09 17:20:46 +00:00
return VO_FALSE ;
} ;
if ( mpi - > flags & MP_IMGFLAG_PLANAR ) {
//YV12 format
mpi - > planes [ 0 ] = dst ;
if ( mpi - > flags & MP_IMGFLAG_SWAPPED ) {
mpi - > planes [ 1 ] = dst + pitch * height ;
mpi - > planes [ 2 ] = mpi - > planes [ 1 ] + pitch * height / 4 ;
} else {
mpi - > planes [ 2 ] = dst + pitch * height ;
mpi - > planes [ 1 ] = mpi - > planes [ 2 ] + pitch * height / 4 ;
}
2002-08-13 08:41:49 +00:00
mpi - > width = width ;
mpi - > stride [ 0 ] = pitch ;
2002-08-09 17:20:46 +00:00
mpi - > stride [ 1 ] = mpi - > stride [ 2 ] = pitch / 2 ;
} else {
//YUY2 and RGB formats
mpi - > planes [ 0 ] = dst ;
mpi - > width = width ;
mpi - > stride [ 0 ] = pitch ;
}
2003-09-07 19:42:35 +00:00
// center image
if ( ! frame ) {
if ( mpi - > flags & MP_IMGFLAG_PLANAR ) {
mpi - > planes [ 0 ] = dst + yoffset * pitch + xoffset ;
2007-11-04 23:39:05 +00:00
mpi - > planes [ 1 ] + = ( ( yoffset * pitch ) > > 2 ) + ( xoffset > > 1 ) ;
mpi - > planes [ 2 ] + = ( ( yoffset * pitch ) > > 2 ) + ( xoffset > > 1 ) ;
2003-09-07 19:42:35 +00:00
} else {
mpi - > planes [ 0 ] = dst + yoffset * pitch + xoffset * ( mpi - > bpp > > 3 ) ;
}
}
2002-08-09 17:20:46 +00:00
mpi - > flags | = MP_IMGFLAG_DIRECT ;
2006-03-27 07:22:48 +00:00
// if ( mp_msg_test(MSGT_VO,MSGL_V) ) printf("DirectFB: get_image() SUCCESS -> Direct Rendering ENABLED\n");
2002-08-09 17:20:46 +00:00
return VO_TRUE ;
}
return VO_FALSE ;
}
2005-08-05 01:24:37 +00:00
static int draw_slice ( uint8_t * src [ ] , int stride [ ] , int w , int h , int x , int y )
2002-08-09 17:20:46 +00:00
{
int i ;
unsigned int pitch ;
void * dst ;
void * dst2 ;
void * srcp ;
unsigned int p ;
2006-03-27 07:22:48 +00:00
// if ( mp_msg_test(MSGT_VO,MSGL_V) ) printf("DirectFB: draw_slice entered\n");
2003-09-07 19:42:35 +00:00
2002-08-09 17:20:46 +00:00
unlock ( ) ;
if ( frame ) {
2003-04-27 17:24:26 +00:00
DFBCHECK ( frame - > Lock ( frame , DSLF_WRITE | DSLF_READ , & dst , & pitch ) ) ;
2002-08-09 17:20:46 +00:00
framelocked = 1 ;
} else {
DFBCHECK ( primary - > Lock ( primary , DSLF_WRITE , & dst , & pitch ) ) ;
primarylocked = 1 ;
} ;
p = min ( w , pitch ) ;
dst + = y * pitch + x ;
dst2 = dst + pitch * height - y * pitch + y * pitch / 4 - x / 2 ;
srcp = src [ 0 ] ;
for ( i = 0 ; i < h ; i + + ) {
2007-06-05 14:27:54 +00:00
fast_memcpy ( dst , srcp , p ) ;
2002-08-09 17:20:46 +00:00
dst + = pitch ;
srcp + = stride [ 0 ] ;
}
if ( pixel_format = = DSPF_YV12 ) {
dst = dst2 ;
srcp = src [ 2 ] ;
p = p / 2 ;
for ( i = 0 ; i < h / 2 ; i + + ) {
2007-06-05 14:27:54 +00:00
fast_memcpy ( dst , srcp , p ) ;
2002-08-09 17:20:46 +00:00
dst + = pitch / 2 ;
srcp + = stride [ 2 ] ;
}
dst = dst2 + pitch * height / 4 ;
srcp = src [ 1 ] ;
for ( i = 0 ; i < h / 2 ; i + + ) {
2007-06-05 14:27:54 +00:00
fast_memcpy ( dst , srcp , p ) ;
2002-08-09 17:20:46 +00:00
dst + = pitch / 2 ;
srcp + = stride [ 1 ] ;
}
} else {
dst = dst2 ;
srcp = src [ 1 ] ;
p = p / 2 ;
for ( i = 0 ; i < h / 2 ; i + + ) {
2007-06-05 14:27:54 +00:00
fast_memcpy ( dst , srcp , p ) ;
2002-08-09 17:20:46 +00:00
dst + = pitch / 2 ;
srcp + = stride [ 1 ] ;
}
dst = dst2 + pitch * height / 4 ;
srcp = src [ 2 ] ;
for ( i = 0 ; i < h / 2 ; i + + ) {
2007-06-05 14:27:54 +00:00
fast_memcpy ( dst , srcp , p ) ;
2002-08-09 17:20:46 +00:00
dst + = pitch / 2 ;
srcp + = stride [ 2 ] ;
}
}
unlock ( ) ;
return 0 ;
}
static uint32_t put_image ( mp_image_t * mpi ) {
2007-08-25 16:32:20 +00:00
// static IDirectFBSurface *tmp = NULL;
// DFBSurfaceDescription dsc;
// DFBRectangle rect;
2002-08-09 17:20:46 +00:00
2006-03-27 07:22:48 +00:00
// if ( mp_msg_test(MSGT_VO,MSGL_V) ) printf("DirectFB: Put_image entered %i %i %i %i %i %i\n",mpi->x,mpi->y,mpi->w,mpi->h,mpi->width,mpi->height);
2002-08-09 17:20:46 +00:00
unlock ( ) ;
// already out?
2002-08-13 08:41:49 +00:00
if ( ( mpi - > flags & ( MP_IMGFLAG_DIRECT | MP_IMGFLAG_DRAW_CALLBACK ) ) ) {
2007-11-06 09:54:58 +00:00
// if ( mp_msg_test(MSGT_VO,MSGL_V) ) printf("DirectFB: Put_image - nothing to do\n");
2002-08-09 17:20:46 +00:00
return VO_TRUE ;
}
if ( mpi - > flags & MP_IMGFLAG_PLANAR ) {
// memcpy all planes - sad but necessary
int i ;
unsigned int pitch ;
void * dst ;
void * src ;
unsigned int p ;
2006-03-27 07:22:48 +00:00
// if ( mp_msg_test(MSGT_VO,MSGL_V) ) printf("DirectFB: Put_image - planar branch\n");
2002-08-09 17:20:46 +00:00
if ( frame ) {
2003-04-27 17:24:26 +00:00
DFBCHECK ( frame - > Lock ( frame , DSLF_WRITE | DSLF_READ , & dst , & pitch ) ) ;
2002-08-09 17:20:46 +00:00
framelocked = 1 ;
} else {
DFBCHECK ( primary - > Lock ( primary , DSLF_WRITE , & dst , & pitch ) ) ;
primarylocked = 1 ;
} ;
p = min ( mpi - > w , pitch ) ;
src = mpi - > planes [ 0 ] + mpi - > y * mpi - > stride [ 0 ] + mpi - > x ;
for ( i = 0 ; i < mpi - > h ; i + + ) {
2007-06-05 14:27:54 +00:00
fast_memcpy ( dst + i * pitch , src + i * mpi - > stride [ 0 ] , p ) ;
2002-08-09 17:20:46 +00:00
}
2003-09-07 19:42:35 +00:00
2002-08-09 17:20:46 +00:00
if ( pixel_format = = DSPF_YV12 ) {
dst + = pitch * height ;
p = p / 2 ;
src = mpi - > planes [ 2 ] + mpi - > y * mpi - > stride [ 2 ] + mpi - > x / 2 ;
for ( i = 0 ; i < mpi - > h / 2 ; i + + ) {
2007-06-05 14:27:54 +00:00
fast_memcpy ( dst + i * pitch / 2 , src + i * mpi - > stride [ 2 ] , p ) ;
2002-08-09 17:20:46 +00:00
}
dst + = pitch * height / 4 ;
src = mpi - > planes [ 1 ] + mpi - > y * mpi - > stride [ 1 ] + mpi - > x / 2 ;
for ( i = 0 ; i < mpi - > h / 2 ; i + + ) {
2007-06-05 14:27:54 +00:00
fast_memcpy ( dst + i * pitch / 2 , src + i * mpi - > stride [ 1 ] , p ) ;
2002-08-09 17:20:46 +00:00
}
} else {
dst + = pitch * height ;
p = p / 2 ;
src = mpi - > planes [ 1 ] + mpi - > y * mpi - > stride [ 1 ] + mpi - > x / 2 ;
for ( i = 0 ; i < mpi - > h / 2 ; i + + ) {
2007-06-05 14:27:54 +00:00
fast_memcpy ( dst + i * pitch / 2 , src + i * mpi - > stride [ 1 ] , p ) ;
2002-08-09 17:20:46 +00:00
}
dst + = pitch * height / 4 ;
src = mpi - > planes [ 2 ] + mpi - > y * mpi - > stride [ 2 ] + mpi - > x / 2 ;
for ( i = 0 ; i < mpi - > h / 2 ; i + + ) {
2007-06-05 14:27:54 +00:00
fast_memcpy ( dst + i * pitch / 2 , src + i * mpi - > stride [ 2 ] , p ) ;
2002-08-09 17:20:46 +00:00
}
}
unlock ( ) ;
} else {
2003-09-07 19:42:35 +00:00
// I had to disable native directfb blit because it wasn't working under some conditions :-(
2002-08-09 17:20:46 +00:00
2003-09-07 19:42:35 +00:00
/*
2002-08-09 17:20:46 +00:00
dsc . flags = DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_WIDTH | DSDESC_PREALLOCATED ;
dsc . preallocated [ 0 ] . data = mpi - > planes [ 0 ] ;
dsc . preallocated [ 0 ] . pitch = mpi - > stride [ 0 ] ;
dsc . width = mpi - > width ;
dsc . height = mpi - > height ;
dsc . pixelformat = convformat ( mpi - > imgfmt ) ;
DFBCHECK ( dfb - > CreateSurface ( dfb , & dsc , & tmp ) ) ;
rect . x = mpi - > x ;
rect . y = mpi - > y ;
rect . w = mpi - > w ;
rect . h = mpi - > h ;
if ( frame ) {
DFBCHECK ( tmp - > Blit ( tmp , frame , & rect , 0 , 0 ) ) ;
} else {
DFBCHECK ( tmp - > Blit ( tmp , primary , & rect , xoffset , yoffset ) ) ;
} ;
tmp - > Release ( tmp ) ;
2003-09-07 19:42:35 +00:00
*/
unsigned int pitch ;
void * dst ;
2007-11-06 09:54:58 +00:00
// if ( mp_msg_test(MSGT_VO,MSGL_V) ) printf("DirectFB: Put_image - non-planar branch\n");
2003-09-07 19:42:35 +00:00
if ( frame ) {
DFBCHECK ( frame - > Lock ( frame , DSLF_WRITE , & dst , & pitch ) ) ;
framelocked = 1 ;
mem2agpcpy_pic ( dst , mpi - > planes [ 0 ] + mpi - > y * mpi - > stride [ 0 ] + mpi - > x * ( mpi - > bpp > > 3 ) , mpi - > w * ( mpi - > bpp > > 3 ) , mpi - > h , pitch , mpi - > stride [ 0 ] ) ;
} else {
DFBCHECK ( primary - > Lock ( primary , DSLF_WRITE , & dst , & pitch ) ) ;
primarylocked = 1 ;
mem2agpcpy_pic ( dst + yoffset * pitch + xoffset * ( mpi - > bpp > > 3 ) , mpi - > planes [ 0 ] + mpi - > y * mpi - > stride [ 0 ] + mpi - > x * ( mpi - > bpp > > 3 ) , mpi - > w * ( mpi - > bpp > > 3 ) , mpi - > h , pitch , mpi - > stride [ 0 ] ) ;
} ;
unlock ( ) ;
2002-08-09 17:20:46 +00:00
}
return VO_TRUE ;
}
2005-08-05 01:24:37 +00:00
static int control ( uint32_t request , void * data , . . . )
2002-08-09 17:20:46 +00:00
{
switch ( request ) {
case VOCTRL_QUERY_FORMAT :
return query_format ( * ( ( uint32_t * ) data ) ) ;
case VOCTRL_GET_IMAGE :
return get_image ( data ) ;
case VOCTRL_DRAW_IMAGE :
return put_image ( data ) ;
case VOCTRL_SET_EQUALIZER :
{
va_list ap ;
int value ;
va_start ( ap , data ) ;
value = va_arg ( ap , int ) ;
va_end ( ap ) ;
return ( directfb_set_video_eq ( data , value ) ) ;
}
case VOCTRL_GET_EQUALIZER :
{
va_list ap ;
int * value ;
va_start ( ap , data ) ;
value = va_arg ( ap , int * ) ;
va_end ( ap ) ;
return ( directfb_get_video_eq ( data , value ) ) ;
}
} ;
return VO_NOTIMPL ;
}
// unused function
2005-08-05 01:24:37 +00:00
static int draw_frame ( uint8_t * src [ ] )
2002-08-09 17:20:46 +00:00
{
return - 1 ;
}
// hopefully will be removed soon
static void draw_alpha ( int x0 , int y0 , int w , int h , unsigned char * src ,
unsigned char * srca , int stride )
{
void * dst ;
int pitch ;
2003-10-04 17:29:08 +00:00
unlock ( ) ; // isn't it silly I have to unlock surface and then lock it again :-)
2002-08-09 17:20:46 +00:00
if ( frame ) {
2003-04-27 17:24:26 +00:00
DFBCHECK ( frame - > Lock ( frame , DSLF_WRITE | DSLF_READ , & dst , & pitch ) ) ;
2002-08-09 17:20:46 +00:00
framelocked = 1 ;
} else {
DFBCHECK ( primary - > Lock ( primary , DSLF_WRITE , & dst , & pitch ) ) ;
primarylocked = 1 ;
} ;
switch ( pixel_format ) {
case DSPF_RGB32 :
case DSPF_ARGB :
vo_draw_alpha_rgb32 ( w , h , src , srca , stride , ( ( uint8_t * ) dst ) + pitch * y0 + 4 * x0 , pitch ) ;
break ;
case DSPF_RGB24 :
vo_draw_alpha_rgb24 ( w , h , src , srca , stride , ( ( uint8_t * ) dst ) + pitch * y0 + 3 * x0 , pitch ) ;
break ;
case DSPF_RGB16 :
vo_draw_alpha_rgb16 ( w , h , src , srca , stride , ( ( uint8_t * ) dst ) + pitch * y0 + 2 * x0 , pitch ) ;
break ;
2006-10-08 22:16:38 +00:00
# if DIRECTFBVERSION > DFB_VERSION(0,9,15)
2002-12-29 18:07:18 +00:00
case DSPF_ARGB1555 :
# else
2002-08-09 17:20:46 +00:00
case DSPF_RGB15 :
2002-12-29 18:07:18 +00:00
# endif
2002-08-09 17:20:46 +00:00
vo_draw_alpha_rgb15 ( w , h , src , srca , stride , ( ( uint8_t * ) dst ) + pitch * y0 + 2 * x0 , pitch ) ;
break ;
case DSPF_YUY2 :
vo_draw_alpha_yuy2 ( w , h , src , srca , stride , ( ( uint8_t * ) dst ) + pitch * y0 + 2 * x0 , pitch ) ;
break ;
case DSPF_UYVY :
vo_draw_alpha_yuy2 ( w , h , src , srca , stride , ( ( uint8_t * ) dst ) + pitch * y0 + 2 * x0 + 1 , pitch ) ;
break ;
case DSPF_I420 :
case DSPF_YV12 :
vo_draw_alpha_yv12 ( w , h , src , srca , stride , ( ( uint8_t * ) dst ) + pitch * y0 + 1 * x0 , pitch ) ;
break ;
}
unlock ( ) ;
}
static void draw_osd ( void )
{
vo_draw_text ( width , height , draw_alpha ) ;
}