Commit d55f5d62 authored by Gildas Bazin's avatar Gildas Bazin

* modified the directx video plugin to try to create an YUV surface before
   falling back to an RGB surface when it's not possible to use overlays.
   Some graphic cards can do the YUV->RGB conversion in hardware during the
   blitting stage.
* in the directx video plugin, we now request that the RGB surface be created
   in video memory. The reasoning behind this is that usually surfaces in
   video memory benefit from more hardware acceleration (like for instance
   hw rescaling, hw blitting, etc...)
* added two options to the directx video plugin to disable the above features.
   (mainly because my video driver is buggy and doesn't handle them well).

* small cosmetic changes to the generation of the config file.

* fix for config_GetHomeDir() on win32. SHGetFolderPath() is located in
   shfolder.dll not shell32.dll.
* fix for the gtk preferences dialog box. To be sure that an int or float value
   is actually changed we call gtk_spin_button_update() in the
   GtkInt/FloatChanged() event handler.
parent 74a2caa2
......@@ -2,7 +2,7 @@
* directx.c : Windows DirectX plugin for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: directx.c,v 1.7 2002/04/19 13:56:10 sam Exp $
* $Id: directx.c,v 1.8 2002/05/18 13:30:28 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -43,7 +43,22 @@ void _M( vout_getfunctions )( function_list_t * p_function_list );
/*****************************************************************************
* Building configuration tree
*****************************************************************************/
#define HW_YUV_TEXT N_("Disable hardware YUV->RGB conversions")
#define HW_YUV_LONGTEXT N_( \
"Don't try to use hardware acceleration for YUV->RGB conversions. This " \
"option doesn't have any effect when using overlays." )
#define SYSMEM_TEXT N_("Use video buffers in system memory")
#define SYSMEM_LONGTEXT N_( \
"Create video buffers in system memory instead of video memory. This " \
"isn't recommended as usually using video memory allows to benefit from " \
"more hardware acceleration (like rescaling or YUV->RGB conversions). " \
"This option doesn't have any effect when using overlays." )
MODULE_CONFIG_START
ADD_CATEGORY_HINT( N_("Video"), NULL )
ADD_BOOL ( "no-directx-hw-yuv", NULL, HW_YUV_TEXT, HW_YUV_LONGTEXT )
ADD_BOOL ( "directx-use-sysmem", NULL, SYSMEM_TEXT, SYSMEM_LONGTEXT )
ADD_CATEGORY_HINT( N_("Audio"), NULL )
MODULE_CONFIG_STOP
MODULE_INIT_START
......
......@@ -2,7 +2,7 @@
* vout_directx.c: Windows DirectX video output display method
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: vout_directx.c,v 1.32 2002/04/29 21:22:35 gbazin Exp $
* $Id: vout_directx.c,v 1.33 2002/05/18 13:30:28 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -129,6 +129,8 @@ static int vout_Create( vout_thread_t *p_vout )
p_vout->p_sys->b_caps_overlay_clipping = 0;
SetRectEmpty( &p_vout->p_sys->rect_display );
p_vout->p_sys->b_using_overlay = !config_GetIntVariable( "nooverlay" );
p_vout->p_sys->b_use_sysmem = config_GetIntVariable( "directx-use-sysmem");
p_vout->p_sys->b_hw_yuv = !config_GetIntVariable( "no-directx-hw-yuv" );
p_vout->p_sys->b_cursor_hidden = 0;
p_vout->p_sys->i_lastmoved = mdate();
......@@ -229,6 +231,9 @@ static int vout_Init( vout_thread_t *p_vout )
p_vout->output.i_aspect = p_vout->render.i_aspect;
#define MAX_DIRECTBUFFERS 1
/* Right now we use only 1 directbuffer because we don't want the
* video decoder to decode directly into direct buffers as they are
* created into video memory and video memory is _really_ slow */
NewPictureVec( p_vout, p_vout->p_picture, MAX_DIRECTBUFFERS );
......@@ -236,6 +241,9 @@ static int vout_Init( vout_thread_t *p_vout )
if( p_vout->p_sys->b_using_overlay )
SetWindowText( p_vout->p_sys->hwnd,
"VLC DirectX (using hardware overlay)" );
else if( p_vout->p_sys->b_hw_yuv )
SetWindowText( p_vout->p_sys->hwnd,
"VLC DirectX (using hardware YUV->RGB conversion)" );
return( 0 );
}
......@@ -409,14 +417,14 @@ static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
/* We ask for the "NOTEARING" option */
memset( &ddbltfx, 0, sizeof(DDBLTFX) );
ddbltfx.dwSize = sizeof(DDBLTFX);
ddbltfx.dwDDFX = DDBLTFX_NOTEARING | DDBLT_ASYNC;
ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
/* Blit video surface to display */
dxresult = IDirectDrawSurface3_Blt(p_vout->p_sys->p_display,
&p_vout->p_sys->rect_dest_clipped,
p_pic->p_sys->p_surface,
&p_vout->p_sys->rect_src_clipped,
0, &ddbltfx );
DDBLT_ASYNC, &ddbltfx );
if ( dxresult == DDERR_SURFACELOST )
{
/* Our surface can be lost so be sure
......@@ -428,7 +436,7 @@ static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
&p_vout->p_sys->rect_dest_clipped,
p_pic->p_sys->p_surface,
&p_vout->p_sys->rect_src_clipped,
0, &ddbltfx );
DDBLT_ASYNC, &ddbltfx );
}
if( dxresult != DD_OK )
......@@ -463,6 +471,7 @@ static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
if( dxresult != DD_OK )
intf_WarnMsg( 8, "vout: couldn't flip overlay surface" );
if( !DirectXGetSurfaceDesc( p_pic ) )
{
/* AAARRGG */
......@@ -748,17 +757,32 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
if( !b_overlay )
{
/* Now try to create a plain RGB surface. */
boolean_t b_rgb_surface = ( i_chroma == FOURCC_RGB2 ) ||
( i_chroma == FOURCC_RV15 ) || ( i_chroma == FOURCC_RV16 ) ||
( i_chroma == FOURCC_RV24 ) || ( i_chroma == FOURCC_RV32 );
memset( &ddsd, 0, sizeof( DDSURFACEDESC ) );
ddsd.dwSize = sizeof(DDSURFACEDESC);
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.dwFlags = DDSD_HEIGHT |
DDSD_WIDTH |
DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |
DDSCAPS_SYSTEMMEMORY;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwHeight = p_vout->render.i_height;
ddsd.dwWidth = p_vout->render.i_width;
if( p_vout->p_sys->b_use_sysmem )
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
else
ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
if( !b_rgb_surface )
{
ddsd.dwFlags |= DDSD_PIXELFORMAT;
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
ddsd.ddpfPixelFormat.dwFourCC = i_chroma;
}
dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,
&ddsd,
&p_surface, NULL );
......@@ -898,6 +922,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
int i_num_pics )
{
int i;
boolean_t b_result_ok;
LPDIRECTDRAWSURFACE3 p_surface;
intf_WarnMsg( 3, "vout: NewPictureVec" );
......@@ -919,13 +944,8 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
case FOURCC_YVYU:
p_vout->output.i_chroma = FOURCC_YVYU;
break;
case FOURCC_YV12:
p_vout->output.i_chroma = FOURCC_YV12;
break;
case FOURCC_I420:
case FOURCC_IYUV:
default:
p_vout->output.i_chroma = FOURCC_IYUV;
p_vout->output.i_chroma = FOURCC_YV12;
break;
}
......@@ -937,8 +957,6 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
* memcpy() to the overlay surface. */
if( p_vout->p_sys->b_using_overlay )
{
boolean_t b_result_ok;
/* Triple buffering rocks! it doesn't have any processing overhead
* (you don't have to wait for the vsync) and provides for a very nice
* video quality (no tearing). */
......@@ -947,16 +965,6 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
2 /* number of backbuffers */ );
if( !b_result_ok )
/* Try another chroma */
if( p_vout->output.i_chroma == FOURCC_IYUV )
{
p_vout->output.i_chroma = FOURCC_YV12;
b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
2 /* number of backbuffers */);
}
if( !b_result_ok )
/* Try to reduce the number of backbuffers */
......@@ -1023,47 +1031,32 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
}
}
/* As we can't have overlays, we'll try to create plain RBG surfaces in
* system memory. These surfaces will then be blitted onto the primary
* surface (display) so they can be displayed */
/* As we can't have an overlay, we'll try to create a plain offscreen
* surface. This surface will reside in video memory because there's a
* better chance then that we'll be able to use some kind of hardware
* acceleration like rescaling, blitting or YUV->RGB conversions.
* We then only need to blit this surface onto the main display when we
* want to display it */
if( !p_vout->p_sys->b_using_overlay )
{
DDPIXELFORMAT ddpfPixelFormat;
for( i = 0; i < i_num_pics; i++ )
{
if( DirectXCreateSurface( p_vout, &p_surface,
if( p_vout->p_sys->b_hw_yuv )
b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
0 /* no back buffers */ ) )
{
/* Allocate internal structure */
p_pic[i].p_sys = malloc( sizeof( picture_sys_t ) );
if( p_pic[i].p_sys == NULL )
{
DirectXCloseSurface( p_vout, p_surface );
FreePictureVec( p_vout, p_pic, I_OUTPUTPICTURES );
I_OUTPUTPICTURES = 0;
return -1;
}
p_pic[i].p_sys->p_surface = p_surface;
p_pic[i].p_sys->p_front_surface = NULL;
I_OUTPUTPICTURES++;
0 /* no back buffers */ );
}
else break;
}
if( I_OUTPUTPICTURES )
intf_WarnMsg( 3,"vout: DirectX RGB surface created successfully" );
else
intf_ErrMsg( "vout error: can't create RGB surface." );
if( !p_vout->p_sys->b_hw_yuv || !b_result_ok )
{
/* Our last choice is to use a plain RGB surface */
DDPIXELFORMAT ddpfPixelFormat;
/* We couldn't use an YUV overlay so we need to indicate to
* video_output which format we are falling back to */
ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
IDirectDrawSurface3_GetPixelFormat( p_vout->p_sys->p_display,
&ddpfPixelFormat );
if( ddpfPixelFormat.dwFlags & DDPF_RGB )
{
switch( ddpfPixelFormat.dwRGBBitCount )
{
case 8: /* FIXME: set the palette */
......@@ -1083,7 +1076,35 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
p_vout->output.i_rmask = ddpfPixelFormat.dwRBitMask;
p_vout->output.i_gmask = ddpfPixelFormat.dwGBitMask;
p_vout->output.i_bmask = ddpfPixelFormat.dwBBitMask;
}
p_vout->p_sys->b_hw_yuv = 0;
b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
0 /* no back buffers */ );
}
if( b_result_ok )
{
/* Allocate internal structure */
p_pic[0].p_sys = malloc( sizeof( picture_sys_t ) );
if( p_pic[0].p_sys == NULL )
{
DirectXCloseSurface( p_vout, p_surface );
return -1;
}
p_pic[0].p_sys->p_surface = p_pic[0].p_sys->p_front_surface
= p_surface;
I_OUTPUTPICTURES = 1;
intf_WarnMsg( 3, "vout: DirectX plain surface created "
"successfully" );
}
else
intf_ErrMsg( "vout error: DirectX can't create plain surface." );
}
......@@ -1132,13 +1153,7 @@ static void FreePictureVec( vout_thread_t *p_vout, picture_t *p_pic,
for( i = 0; i < i_num_pics; i++ )
{
#if 0
if( p_pic->p_sys->p_front_surface &&
( p_pic->p_sys->p_surface != p_pic->p_sys->p_front_surface ) )
DirectXCloseSurface( p_vout, p_pic[i].p_sys->p_front_surface );
#endif
DirectXCloseSurface( p_vout, p_pic[i].p_sys->p_surface );
for( i = 0; i < i_num_pics; i++ )
{
......
......@@ -2,7 +2,7 @@
* vout_directx.h: Windows DirectX video output header file
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vout_directx.h,v 1.5 2002/04/23 22:07:05 gbazin Exp $
* $Id: vout_directx.h,v 1.6 2002/05/18 13:30:28 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -39,6 +39,8 @@ typedef struct vout_sys_s
HWND hwnd; /* Handle of the main window */
boolean_t b_using_overlay; /* Are we using an overlay surface */
boolean_t b_use_sysmem; /* Should we use system memory for surfaces */
boolean_t b_hw_yuv; /* Should we use hardware YUV->RGB conversions */
/* size of the display */
RECT rect_display;
......@@ -73,7 +75,7 @@ typedef struct vout_sys_s
vlc_cond_t event_thread_wait;
volatile int i_event_thread_status; /* DirectXEventThread status */
boolean_t b_event_thread_die; /* flag to kill the event thread */
volatile boolean_t b_event_thread_die; /* flag to kill the event thread */
} vout_sys_t;
......
......@@ -2,7 +2,7 @@
* vout_events.c: Windows DirectX video output events handler
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: vout_events.c,v 1.15 2002/04/24 23:49:32 gbazin Exp $
* $Id: vout_events.c,v 1.16 2002/05/18 13:30:28 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -142,7 +142,7 @@ void DirectXEventThread( vout_thread_t *p_vout )
case VK_ESCAPE:
case VK_F12:
/* exit application */
p_main->p_intf->b_die = 1;
p_main->p_intf->b_die = p_vout->p_sys->b_event_thread_die = 1;
break;
}
TranslateMessage(&msg);
......@@ -154,7 +154,7 @@ void DirectXEventThread( vout_thread_t *p_vout )
case 'q':
case 'Q':
/* exit application */
p_main->p_intf->b_die = 1;
p_main->p_intf->b_die = p_vout->p_sys->b_event_thread_die = 1;
break;
case 'f': /* switch to fullscreen */
......@@ -512,6 +512,8 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
DirectXUpdateOverlay( p_vout );
/* signal the size change */
if( !p_vout->p_sys->b_using_overlay &&
!p_vout->p_sys->b_event_thread_die )
p_vout->p_sys->i_changes |= VOUT_SIZE_CHANGE;
return 0;
......@@ -522,7 +524,8 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
case WM_CLOSE:
intf_WarnMsg( 4, "vout: WinProc WM_CLOSE" );
/* exit application */
p_main->p_intf->b_die = 1;
p_vout = (vout_thread_t *)GetWindowLong( hwnd, GWL_USERDATA );
p_main->p_intf->b_die = p_vout->p_sys->b_event_thread_die = 1;
return 0;
break;
......
......@@ -2,7 +2,7 @@
* gtk_preferences.c: functions to handle the preferences dialog box.
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: gtk_preferences.c,v 1.27 2002/05/04 16:17:08 gbazin Exp $
* $Id: gtk_preferences.c,v 1.28 2002/05/18 13:30:28 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
* Loc Minier <lool@via.ecp.fr>
......@@ -733,6 +733,7 @@ static void GtkIntChanged( GtkEditable *editable, gpointer user_data )
p_config = malloc( sizeof(module_config_t) );
p_config->i_type = MODULE_CONFIG_ITEM_INTEGER;
gtk_spin_button_update( GTK_SPIN_BUTTON(editable) );
p_config->i_value = gtk_spin_button_get_value_as_int(
GTK_SPIN_BUTTON(editable) );
p_config->psz_name = (char *)gtk_object_get_data( GTK_OBJECT(editable),
......@@ -767,6 +768,7 @@ static void GtkFloatChanged( GtkEditable *editable, gpointer user_data )
p_config = malloc( sizeof(module_config_t) );
p_config->i_type = MODULE_CONFIG_ITEM_FLOAT;
gtk_spin_button_update( GTK_SPIN_BUTTON(editable) );
p_config->f_value = gtk_spin_button_get_value_as_float(
GTK_SPIN_BUTTON(editable) );
p_config->psz_name = (char *)gtk_object_get_data( GTK_OBJECT(editable),
......
......@@ -2,7 +2,7 @@
* configuration.c management of the modules configuration
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: configuration.c,v 1.23 2002/05/15 01:29:07 sam Exp $
* $Id: configuration.c,v 1.24 2002/05/18 13:30:28 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -411,8 +411,8 @@ int config_LoadConfigFile( const char *psz_module_name )
file = fopen( psz_filename, "rt" );
if( !file )
{
intf_WarnMsg( 1, "config: couldn't open config file %s for reading (%s)",
psz_filename, strerror(errno) );
intf_WarnMsg( 1, "config: config file %s doesn't already exist",
psz_filename );
free( psz_filename );
vlc_mutex_unlock( &p_main->config_lock );
return -1;
......@@ -450,7 +450,8 @@ int config_LoadConfigFile( const char *psz_module_name )
if( line[0] == '[' ) break; /* end of section */
/* ignore comments or empty lines */
if( (line[0] == '#') || (line[0] == (char)0) ) continue;
if( (line[0] == '#') || (line[0] == '\n') || (line[0] == (char)0) )
continue;
/* get rid of line feed */
if( line[strlen(line)-1] == '\n' )
......@@ -599,8 +600,8 @@ int config_SaveConfigFile( const char *psz_module_name )
file = fopen( psz_filename, "rt" );
if( !file )
{
intf_WarnMsg( 1, "config: couldn't open config file %s for reading (%s)",
psz_filename, strerror(errno) );
intf_WarnMsg( 1, "config: config file %s doesn't already exist",
psz_filename );
}
else
{
......@@ -702,10 +703,11 @@ int config_SaveConfigFile( const char *psz_module_name )
intf_WarnMsg( 5, "config: saving config for module <%s>",
p_module->psz_name );
fprintf( file, "[%s]\n", p_module->psz_name );
fprintf( file, "[%s]", p_module->psz_name );
if( p_module->psz_longname )
fprintf( file, "###\n### %s\n###\n", p_module->psz_longname );
fprintf( file, " # %s\n\n", p_module->psz_longname );
else
fprintf( file, "\n\n" );
for( p_item = p_module->p_config;
p_item->i_type != MODULE_CONFIG_HINT_END;
......@@ -1022,13 +1024,13 @@ char *config_GetHomeDir( void )
# define CSIDL_APPDATA 0x1A
# define SHGFP_TYPE_CURRENT 0
HINSTANCE shell32_dll;
HINSTANCE shfolder_dll;
SHGETFOLDERPATH SHGetFolderPath ;
/* load the shell32 dll to retreive SHGetFolderPath */
if( ( shell32_dll = LoadLibrary("shell32.dll") ) != NULL )
if( ( shfolder_dll = LoadLibrary("shfolder.dll") ) != NULL )
{
SHGetFolderPath = (void *)GetProcAddress( shell32_dll,
SHGetFolderPath = (void *)GetProcAddress( shfolder_dll,
"SHGetFolderPathA" );
if ( SHGetFolderPath != NULL )
{
......@@ -1045,12 +1047,12 @@ char *config_GetHomeDir( void )
NULL, SHGFP_TYPE_CURRENT,
p_homedir ) )
{
FreeLibrary( shell32_dll );
FreeLibrary( shfolder_dll );
return p_homedir;
}
free( p_homedir );
}
FreeLibrary( shell32_dll );
FreeLibrary( shfolder_dll );
}
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment