2009-02-08 03:27:30 +00:00
/*
* This file is part of MPlayer .
*
* MPlayer is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* MPlayer 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 General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with MPlayer ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
2001-02-24 20:28:24 +00:00
2001-04-21 21:06:37 +00:00
# include "fastmemcpy.h"
2004-10-28 01:15:53 +00:00
# include "cpudetect.h"
2006-06-30 12:00:31 +00:00
# include "libswscale/swscale.h"
2011-03-28 01:07:26 +00:00
# include <libavutil/imgutils.h>
2004-10-28 01:15:53 +00:00
# include "libmpcodecs/vf_scale.h"
2002-11-01 00:21:45 +00:00
# include "mp_msg.h"
2008-04-20 20:29:28 +00:00
# include "old_vo_wrapper.h"
2001-04-14 19:29:28 +00:00
2001-02-24 20:28:24 +00:00
// mga_vid drawing functions
2002-11-01 00:21:45 +00:00
static void set_window ( void ) ; /* forward declaration to kill warnings */
2002-06-07 22:43:29 +00:00
# ifdef VO_XMGA
2002-11-01 00:21:45 +00:00
static void mDrawColorKey ( void ) ; /* forward declaration to kill warnings */
2002-06-07 22:43:29 +00:00
# endif
2001-02-24 20:28:24 +00:00
2001-03-08 01:06:03 +00:00
static int mga_next_frame = 0 ;
static mga_vid_config_t mga_vid_config ;
static uint8_t * vid_data , * frames [ 4 ] ;
2002-03-29 05:03:25 +00:00
static int f = - 1 ;
2001-03-08 01:06:03 +00:00
2002-11-06 23:54:29 +00:00
static uint32_t drwX , drwY , drwWidth , drwHeight ;
2010-10-09 11:12:53 +00:00
static uint32_t drwcX , drwcY ;
2002-11-01 00:21:45 +00:00
2010-09-16 23:25:04 +00:00
static struct SwsContext * sws_ctx ;
2001-03-24 04:36:17 +00:00
static void draw_alpha ( int x0 , int y0 , int w , int h , unsigned char * src , unsigned char * srca , int stride ) {
2010-10-09 11:33:50 +00:00
uint32_t bespitch = FFALIGN ( mga_vid_config . src_width , 32 ) ;
2003-04-26 16:56:21 +00:00
x0 + = mga_vid_config . src_width * ( vo_panscan_x > > 1 ) / ( vo_dwidth + vo_panscan_x ) ;
2001-04-16 01:26:08 +00:00
switch ( mga_vid_config . format ) {
case MGA_VID_FORMAT_YV12 :
2001-04-16 03:33:35 +00:00
case MGA_VID_FORMAT_IYUV :
case MGA_VID_FORMAT_I420 :
2001-04-10 02:29:38 +00:00
vo_draw_alpha_yv12 ( w , h , src , srca , stride , vid_data + bespitch * y0 + x0 , bespitch ) ;
2001-04-16 01:26:08 +00:00
break ;
case MGA_VID_FORMAT_YUY2 :
2001-04-10 02:29:38 +00:00
vo_draw_alpha_yuy2 ( w , h , src , srca , stride , vid_data + 2 * ( bespitch * y0 + x0 ) , 2 * bespitch ) ;
2001-04-16 01:26:08 +00:00
break ;
case MGA_VID_FORMAT_UYVY :
vo_draw_alpha_yuy2 ( w , h , src , srca , stride , vid_data + 2 * ( bespitch * y0 + x0 ) + 1 , 2 * bespitch ) ;
break ;
}
2001-02-24 20:28:24 +00:00
}
2002-10-09 13:40:23 +00:00
static void draw_osd ( void )
{
2003-04-26 16:56:21 +00:00
// vo_draw_text(mga_vid_config.src_width,mga_vid_config.src_height,draw_alpha);
vo_draw_text ( mga_vid_config . src_width - mga_vid_config . src_width * vo_panscan_x / ( vo_dwidth + vo_panscan_x ) , mga_vid_config . src_height , draw_alpha ) ;
2002-10-09 13:40:23 +00:00
}
2001-02-24 20:28:24 +00:00
static void
draw_slice_g200 ( uint8_t * image [ ] , int stride [ ] , int width , int height , int x , int y )
{
2010-10-09 11:33:50 +00:00
uint32_t bespitch = FFALIGN ( mga_vid_config . src_width , 32 ) ;
2010-09-16 23:25:04 +00:00
int dst_stride [ 4 ] = { bespitch , bespitch } ;
uint8_t * dst [ 4 ] ;
2001-02-24 20:28:24 +00:00
2010-09-16 23:25:04 +00:00
av_image_fill_pointers ( dst , PIX_FMT_NV12 , mga_vid_config . src_height ,
vid_data , dst_stride ) ;
2002-03-30 17:40:22 +00:00
2010-09-16 23:25:04 +00:00
sws_scale ( sws_ctx , image , stride , y , height , dst , dst_stride ) ;
2001-02-24 20:28:24 +00:00
}
static void
draw_slice_g400 ( uint8_t * image [ ] , int stride [ ] , int w , int h , int x , int y )
{
uint8_t * dest ;
2002-03-24 20:45:30 +00:00
uint8_t * dest2 ;
2001-02-24 20:28:24 +00:00
uint32_t bespitch , bespitch2 ;
2010-10-09 11:33:50 +00:00
bespitch = FFALIGN ( mga_vid_config . src_width , 32 ) ;
2001-02-24 20:28:24 +00:00
bespitch2 = bespitch / 2 ;
dest = vid_data + bespitch * y + x ;
2002-03-06 15:48:54 +00:00
mem2agpcpy_pic ( dest , image [ 0 ] , w , h , bespitch , stride [ 0 ] ) ;
2009-07-06 23:26:13 +00:00
2001-02-24 20:28:24 +00:00
w / = 2 ; h / = 2 ; x / = 2 ; y / = 2 ;
2002-03-24 20:45:30 +00:00
2001-02-24 20:28:24 +00:00
dest = vid_data + bespitch * mga_vid_config . src_height + bespitch2 * y + x ;
2009-07-06 23:26:13 +00:00
dest2 = dest + bespitch2 * mga_vid_config . src_height / 2 ;
2001-02-24 20:28:24 +00:00
2002-03-24 20:45:30 +00:00
if ( mga_vid_config . format = = MGA_VID_FORMAT_YV12 ) {
2010-10-09 11:33:50 +00:00
// mga_vid's YV12 assumes Y,U,V order (instead of Y,V,U) :(
2002-03-24 20:45:30 +00:00
mem2agpcpy_pic ( dest , image [ 1 ] , w , h , bespitch2 , stride [ 1 ] ) ;
mem2agpcpy_pic ( dest2 , image [ 2 ] , w , h , bespitch2 , stride [ 2 ] ) ;
} else {
2002-03-06 15:48:54 +00:00
mem2agpcpy_pic ( dest , image [ 2 ] , w , h , bespitch2 , stride [ 2 ] ) ;
2002-03-24 20:45:30 +00:00
mem2agpcpy_pic ( dest2 , image [ 1 ] , w , h , bespitch2 , stride [ 1 ] ) ;
}
2001-02-24 20:28:24 +00:00
}
2005-08-05 01:24:37 +00:00
static int
2001-02-24 20:28:24 +00:00
draw_slice ( uint8_t * src [ ] , int stride [ ] , int w , int h , int x , int y )
{
2002-03-06 15:48:54 +00:00
#if 0
printf ( " vo: %p/%d %p/%d %p/%d %dx%d/%d;%d \n " ,
src [ 0 ] , stride [ 0 ] ,
src [ 1 ] , stride [ 1 ] ,
src [ 2 ] , stride [ 2 ] ,
w , h , x , y ) ;
# endif
2001-02-24 20:28:24 +00:00
if ( mga_vid_config . card_type = = MGA_G200 )
draw_slice_g200 ( src , stride , w , h , x , y ) ;
else
draw_slice_g400 ( src , stride , w , h , x , y ) ;
return 0 ;
}
static void
2001-03-03 21:46:39 +00:00
vo_mga_flip_page ( void )
2001-02-24 20:28:24 +00:00
{
2001-03-07 01:07:46 +00:00
// printf("-- flip to %d --\n",mga_next_frame);
2001-02-24 20:28:24 +00:00
2001-03-07 01:07:46 +00:00
ioctl ( f , MGA_VID_FSEL , & mga_next_frame ) ;
2001-03-08 01:06:03 +00:00
mga_next_frame = ( mga_next_frame + 1 ) % mga_vid_config . num_frames ;
2001-03-07 01:07:46 +00:00
vid_data = frames [ mga_next_frame ] ;
2001-02-24 20:28:24 +00:00
}
2005-08-05 01:24:37 +00:00
static int
2001-02-24 20:28:24 +00:00
draw_frame ( uint8_t * src [ ] )
{
2006-04-24 04:23:53 +00:00
mp_msg ( MSGT_VO , MSGL_WARN , " !!! mga::draw_frame() called !!! \n " ) ;
2001-04-15 20:31:58 +00:00
return 0 ;
2001-02-24 20:28:24 +00:00
}
2002-10-09 14:38:38 +00:00
static uint32_t get_image ( mp_image_t * mpi ) {
2010-10-09 11:33:50 +00:00
uint32_t bespitch = FFALIGN ( mga_vid_config . src_width , 32 ) ;
2002-03-07 02:44:16 +00:00
uint32_t bespitch2 = bespitch / 2 ;
// printf("mga: get_image() called\n");
2002-03-07 13:02:35 +00:00
if ( mpi - > type = = MP_IMGTYPE_STATIC & & mga_vid_config . num_frames > 1 ) return VO_FALSE ; // it is not static
2002-03-07 02:44:16 +00:00
if ( mpi - > flags & MP_IMGFLAG_READABLE ) return VO_FALSE ; // slow video ram
2002-03-25 16:21:39 +00:00
if ( mga_vid_config . card_type = = MGA_G200 & & mpi - > flags & MP_IMGFLAG_PLANAR ) return VO_FALSE ;
2002-03-07 02:44:16 +00:00
// printf("width=%d vs. bespitch=%d, flags=0x%X \n",mpi->width,bespitch,mpi->flags);
if ( ( mpi - > width = = bespitch ) | |
( mpi - > flags & ( MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH ) ) ) {
// we're lucky or codec accepts stride => ok, let's go!
if ( mpi - > flags & MP_IMGFLAG_PLANAR ) {
mpi - > planes [ 0 ] = vid_data ;
2002-03-24 20:45:30 +00:00
if ( mpi - > flags & MP_IMGFLAG_SWAPPED ) {
mpi - > planes [ 1 ] = vid_data + bespitch * mga_vid_config . src_height ;
mpi - > planes [ 2 ] = mpi - > planes [ 1 ] + bespitch2 * mga_vid_config . src_height / 2 ;
} else {
mpi - > planes [ 2 ] = vid_data + bespitch * mga_vid_config . src_height ;
mpi - > planes [ 1 ] = mpi - > planes [ 2 ] + bespitch2 * mga_vid_config . src_height / 2 ;
}
2002-03-07 02:44:16 +00:00
mpi - > width = mpi - > stride [ 0 ] = bespitch ;
mpi - > stride [ 1 ] = mpi - > stride [ 2 ] = bespitch2 ;
} else {
mpi - > planes [ 0 ] = vid_data ;
mpi - > width = bespitch ;
mpi - > stride [ 0 ] = mpi - > width * ( mpi - > bpp / 8 ) ;
}
mpi - > flags | = MP_IMGFLAG_DIRECT ;
// printf("mga: get_image() SUCCESS -> Direct Rendering ENABLED\n");
return VO_TRUE ;
}
return VO_FALSE ;
}
2002-10-09 14:38:38 +00:00
static uint32_t
draw_image ( mp_image_t * mpi ) {
2010-10-09 11:33:50 +00:00
uint32_t bespitch = FFALIGN ( mga_vid_config . src_width , 32 ) ;
2002-10-09 14:38:38 +00:00
// if -dr or -slices then do nothing:
if ( mpi - > flags & ( MP_IMGFLAG_DIRECT | MP_IMGFLAG_DRAW_CALLBACK ) ) return VO_TRUE ;
if ( mpi - > flags & MP_IMGFLAG_PLANAR ) {
// copy planar:
2012-02-24 14:25:22 +00:00
draw_slice ( mpi - > planes , mpi - > stride , mpi - > w , mpi - > h , 0 , 0 ) ;
2002-10-09 14:38:38 +00:00
} else {
// copy packed:
mem2agpcpy_pic ( vid_data , mpi - > planes [ 0 ] , // dst,src
mpi - > w * ( mpi - > bpp / 8 ) , mpi - > h , // w,h
bespitch * 2 , mpi - > stride [ 0 ] ) ; // dstride,sstride
}
return VO_TRUE ;
}
2005-08-05 01:24:37 +00:00
static int
2001-02-24 20:28:24 +00:00
query_format ( uint32_t format )
{
switch ( format ) {
case IMGFMT_YV12 :
2001-04-16 03:33:35 +00:00
case IMGFMT_I420 :
case IMGFMT_IYUV :
2001-02-24 20:28:24 +00:00
case IMGFMT_YUY2 :
2001-04-15 20:31:58 +00:00
case IMGFMT_UYVY :
2005-04-18 15:52:38 +00:00
return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE ;
2001-02-24 20:28:24 +00:00
}
return 0 ;
}
2007-08-28 11:04:36 +00:00
# ifndef VO_XMGA
2009-01-05 14:48:03 +00:00
static void mga_fullscreen ( void )
2002-05-05 18:58:42 +00:00
{
uint32_t w , h ;
if ( ! vo_fs ) {
vo_fs = VO_TRUE ;
w = vo_screenwidth ; h = vo_screenheight ;
aspect ( & w , & h , A_ZOOM ) ;
} else {
vo_fs = VO_FALSE ;
w = vo_dwidth ; h = vo_dheight ;
aspect ( & w , & h , A_NOZOOM ) ;
}
mga_vid_config . dest_width = w ;
mga_vid_config . dest_height = h ;
2002-10-09 13:40:23 +00:00
mga_vid_config . x_org = ( vo_screenwidth - w ) / 2 ;
mga_vid_config . y_org = ( vo_screenheight - h ) / 2 ;
2002-05-05 18:58:42 +00:00
if ( ioctl ( f , MGA_VID_CONFIG , & mga_vid_config ) )
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_WARN , " [MGA] error in mga_vid_config ioctl (wrong mga_vid.o version?) " ) ;
2002-05-05 18:58:42 +00:00
}
2007-08-28 11:04:36 +00:00
# endif
2002-05-05 18:58:42 +00:00
2008-04-02 16:38:34 +00:00
static int control ( uint32_t request , void * data )
2002-03-07 01:51:28 +00:00
{
switch ( request ) {
case VOCTRL_QUERY_FORMAT :
return query_format ( * ( ( uint32_t * ) data ) ) ;
2002-03-07 02:44:16 +00:00
case VOCTRL_GET_IMAGE :
return get_image ( data ) ;
2002-10-09 14:38:38 +00:00
case VOCTRL_DRAW_IMAGE :
return draw_image ( data ) ;
2002-07-25 21:36:04 +00:00
case VOCTRL_SET_EQUALIZER :
{
short value ;
uint32_t luma , prev ;
2008-04-02 15:51:38 +00:00
struct voctrl_set_equalizer_args * args = data ;
2002-07-25 21:36:04 +00:00
2008-04-02 15:51:38 +00:00
if ( strcmp ( args - > name , " brightness " ) & & strcmp ( args - > name , " contrast " ) )
return VO_FALSE ;
2002-07-25 21:36:04 +00:00
if ( ioctl ( f , MGA_VID_GET_LUMA , & prev ) ) {
perror ( " Error in mga_vid_config ioctl() " ) ;
2009-07-06 23:26:13 +00:00
mp_tmsg ( MSGT_VO , MSGL_WARN , " [MGA] Could not get luma values from the kernel module! \n " ) ;
2002-07-25 21:36:04 +00:00
return VO_FALSE ;
}
// printf("GET: 0x%4X 0x%4X \n",(prev>>16),(prev&0xffff));
2008-04-02 15:51:38 +00:00
value = args - > value ;
2009-07-06 23:26:13 +00:00
2002-07-25 21:36:04 +00:00
// printf("value: %d -> ",value);
value = ( ( value + 100 ) * 255 ) / 200 - 128 ; // maps -100=>-128 and +100=>127
// printf("%d \n",value);
2008-04-02 15:51:38 +00:00
if ( ! strcmp ( args - > name , " contrast " ) )
2002-07-25 21:36:04 +00:00
luma = ( prev & 0xFFFF0000 ) | ( value & 0xFFFF ) ;
else
luma = ( prev & 0xFFFF ) | ( value < < 16 ) ;
2009-07-06 23:26:13 +00:00
2002-07-25 21:36:04 +00:00
if ( ioctl ( f , MGA_VID_SET_LUMA , luma ) ) {
perror ( " Error in mga_vid_config ioctl() " ) ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_WARN , " [MGA] Could not set luma values from the kernel module! \n " ) ;
2002-07-25 21:36:04 +00:00
return VO_FALSE ;
}
return VO_TRUE ;
}
2002-06-10 18:40:19 +00:00
2002-07-25 21:36:04 +00:00
case VOCTRL_GET_EQUALIZER :
{
short val ;
uint32_t luma ;
2008-04-02 15:51:38 +00:00
struct voctrl_get_equalizer_args * args = data ;
2009-07-06 23:26:13 +00:00
2008-04-02 15:51:38 +00:00
if ( strcmp ( args - > name , " brightness " ) & & strcmp ( args - > name , " contrast " ) )
return VO_FALSE ;
2002-07-25 21:36:04 +00:00
if ( ioctl ( f , MGA_VID_GET_LUMA , & luma ) ) {
perror ( " Error in mga_vid_config ioctl() " ) ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_WARN , " [MGA] Could not get luma values from the kernel module! \n " ) ;
2002-07-25 21:36:04 +00:00
return VO_FALSE ;
}
2009-07-06 23:26:13 +00:00
2008-04-02 15:51:38 +00:00
if ( ! strcmp ( args - > name , " contrast " ) )
2002-07-25 21:36:04 +00:00
val = ( luma & 0xFFFF ) ;
else
val = ( luma > > 16 ) ;
2009-07-06 23:26:13 +00:00
2008-04-02 15:51:38 +00:00
* args - > valueptr = ( val * 200 ) / 255 ;
2002-07-25 21:36:04 +00:00
return VO_TRUE ;
}
2009-07-06 23:26:13 +00:00
2002-06-10 18:40:19 +00:00
# ifndef VO_XMGA
2002-03-07 17:50:25 +00:00
case VOCTRL_FULLSCREEN :
2002-10-09 13:40:23 +00:00
if ( vo_screenwidth & & vo_screenheight )
mga_fullscreen ( ) ;
else
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_WARN , " [MGA] Screen width/height unknown! \n " ) ;
2002-05-05 18:58:42 +00:00
return VO_TRUE ;
2002-11-01 00:21:45 +00:00
case VOCTRL_GET_PANSCAN :
if ( ! vo_fs ) return VO_FALSE ;
return VO_TRUE ;
2002-06-10 18:40:19 +00:00
# endif
2002-06-05 19:35:54 +00:00
# ifdef VO_XMGA
2003-11-30 16:36:10 +00:00
case VOCTRL_ONTOP :
vo_x11_ontop ( ) ;
return VO_TRUE ;
2002-06-05 19:35:54 +00:00
case VOCTRL_GET_PANSCAN :
2008-02-14 14:23:55 +00:00
if ( ! initialized | | ! vo_fs ) return VO_FALSE ;
2002-06-05 19:35:54 +00:00
return VO_TRUE ;
2002-06-10 18:40:19 +00:00
case VOCTRL_FULLSCREEN :
vo_x11_fullscreen ( ) ;
vo_panscan_amount = 0 ;
2010-10-09 11:33:50 +00:00
/* intended, fallthrough to update panscan on fullscreen/windowed switch */
2002-11-01 00:21:45 +00:00
# endif
2002-06-05 19:35:54 +00:00
case VOCTRL_SET_PANSCAN :
2002-06-10 18:40:19 +00:00
if ( vo_fs & & ( vo_panscan ! = vo_panscan_amount ) ) // || ( !vo_fs && vo_panscan_amount ) )
2002-06-05 19:35:54 +00:00
{
2002-11-06 23:54:29 +00:00
// int old_y = vo_panscan_y;
2002-06-05 19:35:54 +00:00
panscan_calc ( ) ;
2009-07-06 23:26:13 +00:00
// if ( old_y != vo_panscan_y )
2002-06-10 18:40:19 +00:00
set_window ( ) ;
2002-06-05 19:35:54 +00:00
}
return VO_TRUE ;
2010-10-09 11:12:53 +00:00
case VOCTRL_UPDATE_SCREENINFO :
# ifdef VO_XMGA
update_xinerama_info ( ) ;
# else
aspect_save_screenres ( vo_screenwidth , vo_screenheight ) ;
# endif
return VO_TRUE ;
2002-03-07 01:51:28 +00:00
}
return VO_NOTIMPL ;
}
2002-10-09 13:25:13 +00:00
static int mga_init ( int width , int height , unsigned int format ) {
2010-10-09 11:33:50 +00:00
uint32_t bespitch = FFALIGN ( width , 32 ) ;
2002-10-09 13:25:13 +00:00
switch ( format ) {
case IMGFMT_YV12 :
2010-10-09 11:33:50 +00:00
width = FFALIGN ( width , 2 ) ;
height = FFALIGN ( height , 2 ) ;
mga_vid_config . frame_size = bespitch * height + ( bespitch * height ) / 2 ;
2002-10-09 13:25:13 +00:00
mga_vid_config . format = MGA_VID_FORMAT_I420 ; break ;
case IMGFMT_I420 :
case IMGFMT_IYUV :
2010-10-09 11:33:50 +00:00
width = FFALIGN ( width , 2 ) ;
height = FFALIGN ( height , 2 ) ;
mga_vid_config . frame_size = bespitch * height + ( bespitch * height ) / 2 ;
2002-10-09 13:25:13 +00:00
mga_vid_config . format = MGA_VID_FORMAT_YV12 ; break ;
case IMGFMT_YUY2 :
2010-10-09 11:33:50 +00:00
mga_vid_config . frame_size = bespitch * height * 2 ;
2002-10-09 13:25:13 +00:00
mga_vid_config . format = MGA_VID_FORMAT_YUY2 ; break ;
case IMGFMT_UYVY :
2010-10-09 11:33:50 +00:00
mga_vid_config . frame_size = bespitch * height * 2 ;
2002-10-09 13:25:13 +00:00
mga_vid_config . format = MGA_VID_FORMAT_UYVY ; break ;
2009-07-06 23:26:13 +00:00
default :
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_WARN , " [MGA] invalid output format %0X \n " , format ) ;
2008-05-16 08:33:27 +00:00
return - 1 ;
2002-10-09 13:25:13 +00:00
}
mga_vid_config . src_width = width ;
mga_vid_config . src_height = height ;
2002-10-09 13:40:23 +00:00
if ( ! mga_vid_config . dest_width )
mga_vid_config . dest_width = width ;
if ( ! mga_vid_config . dest_height )
mga_vid_config . dest_height = height ;
2001-03-08 01:06:03 +00:00
2002-10-09 13:40:23 +00:00
mga_vid_config . colkey_on = 0 ;
2009-07-06 23:26:13 +00:00
2002-03-31 20:39:38 +00:00
mga_vid_config . num_frames = ( vo_directrendering & & ! vo_doublebuffering ) ? 1 : 3 ;
2001-03-08 01:06:03 +00:00
mga_vid_config . version = MGA_VID_VERSION ;
2007-03-18 11:03:34 +00:00
if ( width > 1024 & & height > 1024 )
{
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_ERR , " [MGA] Source resolution exceeds 1023x1023 in at least one dimension. \n [MGA] Rescale in software or use -lavdopts lowres=1. \n " ) ;
2008-05-16 08:33:27 +00:00
return - 1 ;
2007-03-18 11:03:34 +00:00
} else if ( height < = 1024 )
{
// try whether we have a G550
int ret ;
2007-09-13 13:16:30 +00:00
if ( ( ret = ioctl ( f , MGA_VID_CONFIG , & mga_vid_config ) ) )
2007-03-18 11:03:34 +00:00
{
if ( mga_vid_config . card_type ! = MGA_G550 )
{
// we don't have a G550, so our resolution is too high
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_ERR , " [MGA] Source resolution exceeds 1023x1023 in at least one dimension. \n [MGA] Rescale in software or use -lavdopts lowres=1. \n " ) ;
2008-05-16 08:33:27 +00:00
return - 1 ;
2007-03-18 11:03:34 +00:00
} else {
// there is a deeper problem
// we have a G550, but still couldn't configure mga_vid
perror ( " Error in mga_vid_config ioctl() " ) ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_WARN , " [MGA] Your mga_vid driver version is incompatible with this MPlayer version! \n " ) ;
2007-03-18 11:03:34 +00:00
return - 1 ;
}
// if we arrived here, then we could successfully configure mga_vid
// at this high resolution
}
} else {
2007-03-18 11:04:47 +00:00
// configure mga_vid in case resolution is < 1024x1024 too
if ( ioctl ( f , MGA_VID_CONFIG , & mga_vid_config ) )
{
perror ( " Error in mga_vid_config ioctl() " ) ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_WARN , " [MGA] Your mga_vid driver version is incompatible with this MPlayer version! \n " ) ;
2007-03-18 11:04:47 +00:00
return - 1 ;
}
2007-03-18 11:03:34 +00:00
}
2010-09-09 14:50:51 +00:00
if ( mga_vid_config . card_type = = MGA_G200 ) {
2010-09-16 23:25:04 +00:00
sws_ctx = sws_getContext ( width , height , PIX_FMT_YUV420P ,
width , height , PIX_FMT_NV12 ,
SWS_BILINEAR , NULL , NULL , NULL ) ;
if ( ! sws_ctx ) {
mp_msg ( MSGT_VO , MSGL_FATAL ,
" Could not get swscale context to scale for G200. \n " ) ;
return - 1 ;
}
mp_msg ( MSGT_VO , MSGL_WARN , " G200 cards support is untested. "
" Please report whether it works. \n " ) ;
2010-09-09 14:50:51 +00:00
}
2009-07-06 23:26:13 +00:00
2007-09-04 22:57:06 +00:00
mp_msg ( MSGT_VO , MSGL_V , " [MGA] Using %d buffers. \n " , mga_vid_config . num_frames ) ;
2001-03-08 01:06:03 +00:00
2011-07-02 22:59:40 +00:00
frames [ 0 ] = mmap ( 0 , mga_vid_config . frame_size * mga_vid_config . num_frames , PROT_WRITE , MAP_SHARED , f , 0 ) ;
2001-03-08 01:06:03 +00:00
frames [ 1 ] = frames [ 0 ] + 1 * mga_vid_config . frame_size ;
frames [ 2 ] = frames [ 0 ] + 2 * mga_vid_config . frame_size ;
frames [ 3 ] = frames [ 0 ] + 3 * mga_vid_config . frame_size ;
mga_next_frame = 0 ;
vid_data = frames [ mga_next_frame ] ;
//clear the buffer
memset ( frames [ 0 ] , 0x80 , mga_vid_config . frame_size * mga_vid_config . num_frames ) ;
2002-10-17 09:49:25 +00:00
# ifndef VO_XMGA
2002-10-09 13:25:13 +00:00
ioctl ( f , MGA_VID_ON , 0 ) ;
2002-10-17 09:49:25 +00:00
# endif
2002-10-09 13:25:13 +00:00
2001-03-08 01:06:03 +00:00
return 0 ;
}
2009-05-04 17:35:26 +00:00
static int mga_uninit ( void ) {
2002-10-09 13:25:13 +00:00
if ( f > = 0 ) {
2001-08-22 21:34:27 +00:00
ioctl ( f , MGA_VID_OFF , 0 ) ;
munmap ( frames [ 0 ] , mga_vid_config . frame_size * mga_vid_config . num_frames ) ;
close ( f ) ;
2002-03-29 05:03:25 +00:00
f = - 1 ;
2002-10-09 13:25:13 +00:00
}
2010-09-16 23:25:04 +00:00
if ( sws_ctx ) {
sws_freeContext ( sws_ctx ) ;
}
2002-09-22 02:33:28 +00:00
return 0 ;
2001-08-22 21:34:27 +00:00
}
2002-03-07 01:51:28 +00:00
2005-08-05 01:24:37 +00:00
static int preinit ( const char * vo_subdevice )
2002-03-07 01:51:28 +00:00
{
2008-05-23 20:18:06 +00:00
uint32_t ver ;
2002-10-10 00:10:58 +00:00
const char * devname = vo_subdevice ? vo_subdevice : " /dev/mga_vid " ;
2002-03-31 20:45:31 +00:00
f = open ( devname , O_RDWR ) ;
if ( f = = - 1 )
{
perror ( " open " ) ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_WARN , " [MGA] Couldn't open: %s \n " , devname ) ;
2008-05-16 08:33:27 +00:00
return - 1 ;
2002-03-31 20:45:31 +00:00
}
2009-07-06 23:26:13 +00:00
2008-05-23 20:18:06 +00:00
// check whether the mga_vid driver has the same
// version as we expect
2009-07-06 23:26:13 +00:00
2008-05-23 20:18:06 +00:00
ioctl ( f , MGA_VID_GET_VERSION , & ver ) ;
if ( MGA_VID_VERSION ! = ver )
{
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_VO , MSGL_ERR , " [MGA] mismatch between kernel (%u) and MPlayer (%u) mga_vid driver versions \n " , ver , MGA_VID_VERSION ) ;
2008-05-23 20:18:06 +00:00
return - 1 ;
2002-03-31 20:45:31 +00:00
}
2002-10-09 13:25:13 +00:00
# ifdef VO_XMGA
2003-01-04 19:17:37 +00:00
if ( ! vo_init ( ) ) {
close ( f ) ;
return - 1 ;
}
2002-10-09 13:25:13 +00:00
# endif
2002-03-07 01:51:28 +00:00
return 0 ;
}
2002-11-01 00:21:45 +00:00
static void set_window ( void ) {
2010-10-09 11:12:53 +00:00
drwcX = vo_dx ;
drwcY = vo_dy ;
drwWidth = vo_dwidth ;
drwHeight = vo_dheight ;
aspect ( & drwWidth , & drwHeight , A_WINZOOM ) ;
panscan_calc_windowed ( ) ;
drwWidth + = vo_panscan_x ;
drwHeight + = vo_panscan_y ;
drwWidth = FFMIN ( drwWidth , vo_screenwidth ) ;
drwHeight = FFMIN ( drwHeight , vo_screenheight ) ;
drwX = ( vo_dwidth - drwWidth ) / 2 ;
drwY = ( vo_dheight - drwHeight ) / 2 ;
drwcX + = drwX ;
drwcY + = drwY ;
2002-11-01 00:21:45 +00:00
# ifdef VO_XMGA
2008-08-04 06:16:23 +00:00
# ifdef CONFIG_XINERAMA
2002-11-01 00:21:45 +00:00
if ( XineramaIsActive ( mDisplay ) )
{
XineramaScreenInfo * screens ;
int num_screens ;
int i ;
screens = XineramaQueryScreens ( mDisplay , & num_screens ) ;
/* find the screen we are on */
i = 0 ;
2003-01-18 14:33:29 +00:00
while ( i < num_screens & &
( ( screens [ i ] . x_org < drwcX ) | |
( screens [ i ] . y_org < drwcY ) | |
( screens [ i ] . x_org + screens [ i ] . width > = drwcX ) | |
( screens [ i ] . y_org + screens [ i ] . height > = drwcY ) ) )
2002-11-01 00:21:45 +00:00
{
i + + ;
}
2003-01-18 14:33:29 +00:00
if ( i < num_screens )
{
/* save the screen we are on */
xinerama_screen = i ;
} else {
/* oops.. couldnt find the screen we are on
* because the upper left corner left the
* visual range . assume we are still on the
* same screen
*/
i = xinerama_screen ;
}
2007-08-28 09:15:40 +00:00
if ( xinerama_screen = = - 1 )
{
// The default value of the xinerama_screen is
// still there. Which means we could never
// figure out on which screen we are.
// Choose the first screen as default
xinerama_screen = i = 0 ;
}
2002-11-01 00:21:45 +00:00
/* set drwcX and drwcY to the right values */
drwcX = drwcX - screens [ i ] . x_org ;
drwcY = drwcY - screens [ i ] . y_org ;
XFree ( screens ) ;
}
# endif
mDrawColorKey ( ) ;
# endif
mga_vid_config . x_org = drwcX ;
mga_vid_config . y_org = drwcY ;
mga_vid_config . dest_width = drwWidth ;
mga_vid_config . dest_height = drwHeight ;
2003-01-20 21:35:31 +00:00
if ( ioctl ( f , MGA_VID_CONFIG , & mga_vid_config ) ) mp_msg ( MSGT_VO , MSGL_WARN , " Error in mga_vid_config ioctl (wrong mga_vid.o version?) " ) ;
2002-11-01 00:21:45 +00:00
}