win32 binary package

Gildas Bazin gbazin at netcourrier.com
Tue Jun 12 09:47:07 CEST 2001


I just put a binary smapshot of the VLC with a GTK and DirectX plugin on the videolan ftp site (in incoming).
I definitly don't like the Direct sound audio plugin as it is now. Hacks have been put to help to deal with this delay problem, and there are other problems too. So the next priority is to fix it.

Apart from that it's running fine on my computer.

I would really like to have feedback on all the bugs and strange behaviour, because as I said it's working on my computer but I'm sure there will be problems on others, and bugs that I missed.

Would it be possible to put this binary package on the videolan web site (with a warning that it's unstable) so that a lot of people can test it?

Following is the patch from which this binary was made. It is almost identical to the former one I sent.
There is one big difference (in video_output.c) which could affect other plugins (not verified yet): I initialise p_vout->p_rendered_pic in the thread loop.

Cheers,

--
Gildas

----- La messagerie itinérante sans abonnement NetCourrier -----
Web : www.netcourrier.com - Minitel : 3615 NETCOURRIER
Téléphone : 08 36 69 00 21


-- Attached file included as plaintext by Listar --

Index: configure.in
===================================================================
RCS file: /var/cvs/videolan/vlc/configure.in,v
retrieving revision 1.106
diff -u -r1.106 configure.in
--- configure.in	2001/06/07 15:27:44	1.106
+++ configure.in	2001/06/12 06:06:39
@@ -421,18 +421,18 @@
       PLUGINS="${PLUGINS} directx";
       if test "x$withval" != "xyes";
       then
-        LIB_DIRECTX="${LIB_DIRECTX} -L"$withval"/lib -lddraw -ldsound"
+        LIB_DIRECTX="${LIB_DIRECTX} -L"$withval"/lib -lgdi32 -ldxguid"
         INCLUDE="${INCLUDE} -I"$withval"/include"
       else
         AC_CHECK_HEADERS(directx.h, , [echo "Cannot find DirectX headers !"; exit])
-        LIB_DIRECTX="${LIB_DIRECTX} -L/usr/lib -lddraw -ldsound"
+        LIB_DIRECTX="${LIB_DIRECTX} -L/usr/lib -lgdi32 -ldxguid"
       fi
     fi ])
     if test "x$withval" = "x";
     then
       AC_CHECK_HEADERS(directx.h,
       [PLUGINS="${PLUGINS} directx"
-       LIB_DIRECTX="${LIB_DIRECTX} -L/usr/lib -lddraw -ldsound"])
+       LIB_DIRECTX
="${LIB_DIRECTX} -L/usr/lib -lgdi32 -ldxguid"])
     fi
 
 dnl
Index: plugins/directx/aout_directx.c
===================================================================
RCS file: /var/cvs/videolan/vlc/plugins/directx/aout_directx.c,v
retrieving revision 1.2
diff -u -r1.2 aout_directx.c
--- plugins/directx/aout_directx.c	2001/06/03 12:47:21	1.2
+++ plugins/directx/aout_directx.c	2001/06/12 06:06:40
@@ -24,7 +24,7 @@
 #define MODULE_NAME directx
 #include "modules_inner.h"
 
-/* The most important this to do for now is to fix the audio bug we've got
+/* The most important thing to do for now is to fix the audio bug we've got
  * on startup: the audio will start later than the video (sometimes) and
  * is trying to catching up with it.
  * At first sight it seems to be a scheduling problem
@@ -77,6 +77,8 @@
                                        * takes care of mixing all the
                                        * secondary buffers into the primary) */
 
+    HINSTANCE           hdsound_dll;      /* handle o
f the opened dsound dll */
+
     long l_buffer_size;                       /* secondary sound buffer size */
     long l_write_position;             /* next write position for the buffer */
 
@@ -96,7 +98,8 @@
 static void    aout_Close       ( aout_thread_t *p_aout );
 
 /* local function */
-static int windx_CreateSecondaryBuffer( aout_thread_t *p_aout );
+static int DirectxCreateSecondaryBuffer( aout_thread_t *p_aout );
+static int DirectxInitDSound( aout_thread_t *p_aout );
 
 /*****************************************************************************
  * Functions exported as capabilities. They are declared as static so that
@@ -135,11 +138,11 @@
  *****************************************************************************/
 static int aout_Open( aout_thread_t *p_aout )
 {
-#if 0
     HRESULT dsresult;
     DSBUFFERDESC dsbuffer_desc;
     WAVEFORMATEX waveformat;
-#endif
+
+    intf_WarnMsg( 3, "aout: DirectX aout_Open ");
 
    /* Allocate structure */
     p_aout->p_sys = malloc( sizeof( aout_sy
s_t ) );
@@ -162,32 +165,13 @@
     p_aout->l_rate     = main_GetIntVariable( AOUT_RATE_VAR,
                                               AOUT_RATE_DEFAULT );
 
-    /* Create the direct sound object */
-    if( DirectSoundCreate(NULL, &p_aout->p_sys->p_dsobject, NULL) != DS_OK )
+    /* Initialise DirectSound */
+    if( DirectxInitDSound( p_aout ) )
     {
-        intf_WarnMsg( 3, "aout: can't create a direct sound device ");
-        p_aout->p_sys->p_dsobject = NULL;
+        intf_WarnMsg( 3, "aout: can't initialise DirectSound ");
         return( 1 );
     }
 
-    /* Set DirectSound Cooperative level, ie what control we want over Windows
-     * sound device. In our case, DSSCL_EXCLUSIVE means that we can modify the
-     * settings of the primary buffer, but also that only the sound of our
-     * application will be hearable when it will have the focus.
-     * !!! (this is not really working as intended yet because to set the
-     * cooperative level you need the window handle of your application
, and
-     * I don't know of any easy way to get it. Especially since we might play
-     * sound without any video, and so what window handle should we use ???
-     * The hack for now is to use the Desktop window handle - it seems to be
-     * working */
-    if( IDirectSound_SetCooperativeLevel(p_aout->p_sys->p_dsobject,
-                                         GetDesktopWindow(),
-                                         DSSCL_EXCLUSIVE) )
-    {
-        intf_WarnMsg( 3, "aout: can't set direct sound cooperative level ");
-    }
-
-#if 0
     /* Obtain (not create) Direct Sound primary buffer */
     memset( &dsbuffer_desc, 0, sizeof(DSBUFFERDESC) );
     dsbuffer_desc.dwSize = sizeof(DSBUFFERDESC);
@@ -240,22 +224,7 @@
         p_aout->p_sys->p_dsbuffer_primary = NULL;
         return( 1 );
     }
-#endif
 
-    /* Now create the buffer that we'll actually use: the secondary buffer */
-    if( windx_CreateSecondaryBuffer( p_aout ) )
-    {
-        intf_WarnMsg( 3, "aout: can't create direct sound se
condary buffer ");
-#if 0
-        IDirectSound_Release( p_aout->p_sys->p_dsbuffer_primary );
-#endif
-        IDirectSound_Release( p_aout->p_sys->p_dsobject );
-        p_aout->p_sys->p_dsobject = NULL;
-        p_aout->p_sys->p_dsbuffer_primary = NULL;
-        p_aout->p_sys->p_dsbuffer = NULL;
-        return( 1 );
-    }
-
     return( 0 );
 }
 
@@ -270,6 +239,8 @@
 {
     HRESULT dsresult;
 
+    intf_WarnMsg( 3, "aout: DirectX aout_SetFormat ");
+
     /* first release the current secondary buffer */
     if( p_aout->p_sys->p_dsbuffer != NULL )
     {
@@ -278,10 +249,10 @@
     }
 
     /* then create a new secondary buffer */
-    dsresult = windx_CreateSecondaryBuffer( p_aout );    
+    dsresult = DirectxCreateSecondaryBuffer( p_aout );    
     if( dsresult != DS_OK )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_SetFormat cannot create buffer");
+        intf_WarnMsg( 3, "aout: DirectX aout_SetFormat cannot create buffer");
         return( 1 );
     }
   
@@ -311,16 +282,25 @@
     }
     if
( dsresult != DS_OK )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_GetBufInfo cannot get current pos");
+        intf_WarnMsg(3,"aout: DirectX aout_GetBufInfo cannot get current pos");
         return( l_buffer_limit );
     }
+
+    /* temporary hack. When you start playing a new file, the play position
+     * doesn't start changing immediatly, even though sound is already
+     * playing from the sound card */
+    if( l_play_position == 0 )
+    { 
+       intf_WarnMsg( 5, "aout: DirectX aout_GetBufInfo: %li", l_buffer_limit);
+       return( l_buffer_limit );
+    }
 
-    l_result = ((p_aout->p_sys->l_write_position >= l_play_position) ?
-                (p_aout->p_sys->l_write_position - l_play_position)/2
-                : (p_aout->p_sys->l_buffer_size - l_play_position
-                    + p_aout->p_sys->l_write_position)/2 );
+    l_result = (p_aout->p_sys->l_write_position >= l_play_position) ?
+      (p_aout->p_sys->l_write_position - l_play_position) /2
+               : (p_aout->p_sys->
l_buffer_size - l_play_position
+                  + p_aout->p_sys->l_write_position) /2 ;
 
-    intf_WarnMsg( 5, "aout: WinDX aout_GetBufInfo: %li", l_result);
+    intf_WarnMsg( 5, "aout: DirectX aout_GetBufInfo: %li", l_result);
     return l_result;
 }
 
@@ -336,7 +316,7 @@
     long            l_play_position, l_notused, l_buffer_free_length;
     HRESULT         dsresult;
 
-    /* We want to copy data to the circular sound buffer, so first we need to
+    /* We want to copy data to the circular sound buffer, so we first need to
      * find out were in the buffer we can write our data */
     dsresult = IDirectSoundBuffer_GetCurrentPosition(p_aout->p_sys->p_dsbuffer,
                                                      &l_play_position,
@@ -351,20 +331,31 @@
     }
     if( dsresult != DS_OK )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_Play can'get buffer position");
+        intf_WarnMsg( 3, "aout: DirectX aout_Play can'get buffer position");
     }
 
     /* check that we are not overflowin
g the circular buffer (everything should
      * be alright but just in case) */
     l_buffer_free_length =  l_play_position - p_aout->p_sys->l_write_position;
     if( l_buffer_free_length <= 0 )
-        l_buffer_free_length += p_aout->p_sys->l_buffer_size  ;
+        l_buffer_free_length += p_aout->p_sys->l_buffer_size;
 
     if( i_size > l_buffer_free_length )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_Play buffer overflow: size %i, free %i !!!", i_size, l_buffer_free_length);
-        intf_WarnMsg( 3, "aout: WinDX aout_Play buffer overflow: writepos %i, readpos %i !!!", l_play_position, p_aout->p_sys->l_write_position);
+        intf_WarnMsg( 3, "aout: DirectX aout_Play buffer overflow: size %i, free %i !!!", i_size, l_buffer_free_length);
+        intf_WarnMsg( 3, "aout: DirectX aout_Play buffer overflow: writepos %i, readpos %i !!!", p_aout->p_sys->l_write_position, l_play_position);
         /*i_size = l_buffer_free_length;*/
+
+        /* Update the write pointer */
+        p_aout->p_sys->
l_write_position = l_notused;
+
+    }
+    else
+    {
+        intf_WarnMsg( 4, "aout: DirectX aout_Play buffer: size %i, free %i !!!"
+                      , i_size, l_buffer_free_length);
+        intf_WarnMsg( 4, "aout: DirectX aout_Play buffer: writepos %i, readpos %i !!!", p_aout->p_sys->l_write_position, l_play_position);
+
     }
 
     /* Before copying anything, we have to lock the buffer */
@@ -391,7 +382,7 @@
     }
     if( dsresult != DS_OK )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_Play can't lock buffer");
+        intf_WarnMsg( 3, "aout: DirectX aout_Play can't lock buffer");
         return;
     }
 
@@ -423,7 +414,7 @@
     }
     if( dsresult != DS_OK )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_Play can't play buffer");
+        intf_WarnMsg( 3, "aout: DirectX aout_Play can't play buffer");
         return;
     }
 
@@ -434,6 +425,9 @@
  *****************************************************************************/
 static void aout_Close( aout_thread_t *p_aout )
 {
+
+    intf_WarnMsg( 3, "aout: DirectX aout_Close ");
+
     /* make sure the buffer isn't playing */
     if( p_aout->p_sys->p_dsbuffer != NULL )
     {
@@ -461,6 +455,13 @@
         p_aout->p_sys->p_dsobject = NULL;
     }  
     
+    /* free DSOUND.DLL */
+    if( p_aout->p_sys->hdsound_dll != NULL )
+    {
+       FreeLibrary( p_aout->p_sys->hdsound_dll );
+       p_aout->p_sys->hdsound_dll = NULL;
+    }
+
     /* Close the Output. */
     if ( p_aout->p_sys != NULL )
     { 
@@ -470,8 +471,64 @@
 }
 
 /*****************************************************************************
- * windx_CreateSecondaryBuffer
+ * DirectxInitDSound
  *****************************************************************************
+ *****************************************************************************/
+static int DirectxInitDSound( aout_thread_t *p_aout )
+{
+    HRESULT (WINAPI *OurDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
+
+    p_aout->p_sys->hdsound_dll = LoadLibrary("DSOUND.DLL");
+    if( p_aout-
>p_sys->hdsound_dll == NULL )
+    {
+      intf_WarnMsg( 3, "aout: can't open DSOUND.DLL ");
+      return( 1 );
+    }
+
+    OurDirectSoundCreate = (void *)GetProcAddress( p_aout->p_sys->hdsound_dll,
+                                                   "DirectSoundCreate" );
+
+    if( OurDirectSoundCreate == NULL )
+    {
+      intf_WarnMsg( 3, "aout: GetProcAddress FAILED ");
+      FreeLibrary( p_aout->p_sys->hdsound_dll );
+      p_aout->p_sys->hdsound_dll = NULL;
+      return( 1 );
+    }
+
+    /* Create the direct sound object */
+    if( OurDirectSoundCreate(NULL, &p_aout->p_sys->p_dsobject, NULL) != DS_OK )
+    {
+        intf_WarnMsg( 3, "aout: can't create a direct sound device ");
+        p_aout->p_sys->p_dsobject = NULL;
+        FreeLibrary( p_aout->p_sys->hdsound_dll );
+        p_aout->p_sys->hdsound_dll = NULL;
+        return( 1 );
+    }
+
+    /* Set DirectSound Cooperative level, ie what control we want over Windows
+     * sound device. In our case, DSSCL_EXCLUSIVE means that we ca
n modify the
+     * settings of the primary buffer, but also that only the sound of our
+     * application will be hearable when it will have the focus.
+     * !!! (this is not really working as intended yet because to set the
+     * cooperative level you need the window handle of your application, and
+     * I don't know of any easy way to get it. Especially since we might play
+     * sound without any video, and so what window handle should we use ???
+     * The hack for now is to use the Desktop window handle - it seems to be
+     * working */
+    if( IDirectSound_SetCooperativeLevel(p_aout->p_sys->p_dsobject,
+                                         GetDesktopWindow(),
+                                         DSSCL_EXCLUSIVE) )
+    {
+        intf_WarnMsg( 3, "aout: can't set direct sound cooperative level ");
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * DirectxCreateSecondaryBuffer
+ ***************************************
**************************************
  * This function creates the buffer we'll use to play audio.
  * In DirectSound there are two kinds of buffers:
  * - the primary buffer: which is the actual buffer that the soundcard plays
@@ -481,7 +538,7 @@
  * Once you create a secondary buffer, you cannot change its format anymore so
  * you have to release the current and create another one.
  *****************************************************************************/
-static int windx_CreateSecondaryBuffer( aout_thread_t *p_aout )
+static int DirectxCreateSecondaryBuffer( aout_thread_t *p_aout )
 {
     WAVEFORMATEX waveformat;
     DSBUFFERDESC dsbdesc;
@@ -504,10 +561,6 @@
     dsbdesc.dwSize = sizeof(DSBUFFERDESC); 
     dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2/* Better position accuracy */
                     | DSBCAPS_GLOBALFOCUS;      /* Allows background playing */
-    /*              | DSBCAPS_CTRLPAN
-                    | DSBCAPS_CTRLVOLUME
-                    | DSBCAPS_CTRLFREQUENCY;
-    */

     dsbdesc.dwBufferBytes = waveformat.nAvgBytesPerSec * 4; /* 4 sec buffer */
     dsbdesc.lpwfxFormat = &waveformat; 
  
@@ -523,32 +576,12 @@
 
     /* backup the size of the secondary sound buffer */
     memset(&dsbcaps, 0, sizeof(DSBCAPS)); 
-    dsbcaps.dwSize = sizeof(DSBCAPS); 
+    dsbcaps.dwSize = sizeof(DSBCAPS);
     IDirectSoundBuffer_GetCaps( p_aout->p_sys->p_dsbuffer, &dsbcaps  );
     p_aout->p_sys->l_buffer_size = dsbcaps.dwBufferBytes;
     p_aout->p_sys->l_write_position = 0;
-    intf_WarnMsg( 3, "aout: WinDX WinDX_CreateSecondaryBuffer: %li",
+    intf_WarnMsg( 3, "aout: DirectX DirectxCreateSecondaryBuffer: %li",
                   p_aout->p_sys->l_buffer_size);
 
-    /* make sure the buffer isn't playing */
-    IDirectSoundBuffer_Stop( p_aout->p_sys->p_dsbuffer );
-
-    /* reset play position, just to be sure (and after some tests it seems
-     * indeed necessary */
-    dsresult = IDirectSoundBuffer_SetCurrentPosition(p_aout->p_sys->p_dsbuffer,
-                                 
                    0 );
-    if( dsresult == DSERR_BUFFERLOST )
-    {
-        IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer );
-        dsresult = IDirectSoundBuffer_SetCurrentPosition(
-                                                 p_aout->p_sys->p_dsbuffer,
-                                                 0 );
-    }
-    if( dsresult != DS_OK )
-    {
-        intf_WarnMsg( 3, "aout: WinDX CreateSecondary cannot wet current pos");
-    }
-
     return( 0 );
 }
-
Index: plugins/directx/vout_directx.c
===================================================================
RCS file: /var/cvs/videolan/vlc/plugins/directx/vout_directx.c,v
retrieving revision 1.3
diff -u -r1.3 vout_directx.c
--- plugins/directx/vout_directx.c	2001/06/08 20:03:15	1.3
+++ plugins/directx/vout_directx.c	2001/06/12 06:06:41
@@ -82,10 +82,11 @@
 typedef struct vout_sys_s
 {
 
-    LPDIRECTDRAW         p_ddobject;                    /* DirectDraw object */
-    LPDIRECTDRAWSURFACE  p_display;                        /* displ
ay device */
-    LPDIRECTDRAWSURFACE  p_overlay;                        /* overlay device */
-    LPDIRECTDRAWCLIPPER  p_clipper;                               /* clipper */
+    LPDIRECTDRAW2        p_ddobject;                    /* DirectDraw object */
+    LPDIRECTDRAWSURFACE3 p_display;                        /* Display device */
+    LPDIRECTDRAWSURFACE3 p_surface;    /* surface where we display the video */
+    LPDIRECTDRAWCLIPPER  p_clipper;             /* clipper used for blitting */
+    HINSTANCE            hddraw_dll;       /* handle of the opened ddraw dll */
     HBRUSH               hbrush;           /* window backgound brush (color) */
     HWND                 hwnd;                  /* Handle of the main window */
 
@@ -103,7 +104,7 @@
     boolean_t   b_cursor_autohidden;
     mtime_t     i_lastmoved;
 
-    char       *p_windx_buf[2];                        /* Buffer information */
+    char       *p_directx_buf[2];                      /* Buffer information */
 
 } vout_sys_t;
 
@@ -120,1
5 +121,15 @@
 static void vout_SetPalette( p_vout_thread_t p_vout, u16 *red, u16 *green,
                              u16 *blue, u16 *transp );
 
-static int  WinDXCreateWindow     ( vout_thread_t *p_vout );
-static int  WinDXInitDDraw        ( vout_thread_t *p_vout );
-static int  WinDXCreateDisplay    ( vout_thread_t *p_vout );
-static int  WinDXCreateYUVOverlay ( vout_thread_t *p_vout );
-static int  WinDXUpdateOverlay    ( vout_thread_t *p_vout );
-static void WinDXCloseDDraw       ( vout_thread_t *p_vout );
-static void WinDXCloseWindow      ( vout_thread_t *p_vout );
-static void WinDXCloseDisplay     ( vout_thread_t *p_vout );
-static void WinDXCloseYUVOverlay  ( vout_thread_t *p_vout );
+static int  DirectXCreateWindow   ( vout_thread_t *p_vout );
+static int  DirectXInitDDraw      ( vout_thread_t *p_vout );
+static int  DirectXCreateDisplay  ( vout_thread_t *p_vout );
+static int  DirectXCreateSurface  ( vout_thread_t *p_vout );
+static int  DirectXUpdateOverlay  ( vout_thread_t *p_vout );
+static v
oid DirectXCloseDDraw     ( vout_thread_t *p_vout );
+static void DirectXCloseWindow    ( vout_thread_t *p_vout );
+static void DirectXCloseDisplay   ( vout_thread_t *p_vout );
+static void DirectXCloseSurface   ( vout_thread_t *p_vout );
 
 /*****************************************************************************
  * Functions exported as capabilities. They are declared as static so that
@@ -154,11 +155,15 @@
  *****************************************************************************/
 static int vout_Probe( probedata_t *p_data )
 {
+
     if( TestMethod( VOUT_METHOD_VAR, "directx" ) )
     {
         return( 999 );
     }
 
+    /* Check that at least DirectX5 is installed on the computer */
+    /* Fixme */
+
     return( 400 );
 }
 
@@ -180,15 +185,16 @@
     /* Initialisations */
     p_vout->p_sys->p_ddobject = NULL;
     p_vout->p_sys->p_display = NULL;
-    p_vout->p_sys->p_overlay = NULL;
+    p_vout->p_sys->p_surface = NULL;
     p_vout->p_sys->p_clipper = NULL;
-    p_vout->p_sys->hbrush =
 INVALID_HANDLE_VALUE;
-    p_vout->p_sys->hwnd = INVALID_HANDLE_VALUE;
+    p_vout->p_sys->hbrush = NULL;
+    p_vout->p_sys->hwnd = NULL;
+    p_vout->p_sys->b_display_enabled = 0;
+    p_vout->b_need_render = 0;      /* by default try an YUV overlay display */
 
     p_vout->p_sys->b_cursor = 1; /* TODO should be done with a main_GetInt.. */
 
     p_vout->p_sys->b_cursor_autohidden = 0;
-    p_vout->p_sys->b_display_enabled = 0;
     p_vout->p_sys->i_lastmoved = mdate();
 
     p_vout->b_fullscreen = main_GetIntVariable( VOUT_FULLSCREEN_VAR,
@@ -207,7 +213,7 @@
     /* Create a window for the video */
     /* Creating a window under Windows also initializes the thread's event
      * message qeue */
-    if( WinDXCreateWindow( p_vout ) )
+    if( DirectXCreateWindow( p_vout ) )
     {
         intf_ErrMsg( "vout error: can't create window" );
         free( p_vout->p_sys );
@@ -215,20 +221,20 @@
     }
 
     /* Initialise DirectDraw */
-    if( WinDXInitDDraw( p_vout ) )
+    if( DirectXInitDDraw( p_vout
 ) )
     {
         intf_ErrMsg( "vout error: can't initialise DirectDraw" );
-        WinDXCloseWindow( p_vout );
+        DirectXCloseWindow( p_vout );
         free( p_vout->p_sys );
         return ( 1 );
     }
 
-    /* create the directx display */
-    if( WinDXCreateDisplay( p_vout ) )
+    /* Create the directx display */
+    if( DirectXCreateDisplay( p_vout ) )
     {
         intf_ErrMsg( "vout error: can't initialise DirectDraw" );
-        WinDXCloseDDraw( p_vout );
-        WinDXCloseWindow( p_vout );
+        DirectXCloseDDraw( p_vout );
+        DirectXCloseWindow( p_vout );
         free( p_vout->p_sys );
         return ( 1 );
     }
@@ -265,9 +271,9 @@
 static void vout_Destroy( vout_thread_t *p_vout )
 {
     intf_WarnMsg( 3, "vout: vout_Destroy" );
-    WinDXCloseDisplay( p_vout );
-    WinDXCloseDDraw( p_vout );
-    WinDXCloseWindow( p_vout );
+    DirectXCloseDisplay( p_vout );
+    DirectXCloseDDraw( p_vout );
+    DirectXCloseWindow( p_vout );
 
     if( p_vout->p_sys != NULL )
  
   {
@@ -297,17 +303,17 @@
             {
 
                 case WM_CLOSE:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_CLOSE" );
+                    intf_WarnMsg( 4, "vout: vout_Manage WM_CLOSE" );
                     p_vout->b_die = 1;
                     break;
 
                 case WM_QUIT:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_QUIT" );
+                    intf_WarnMsg( 4, "vout: vout_Manage WM_QUIT" );
                     p_main->p_intf->b_die = 1;
                     break;
 
                 case WM_MOVE:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_MOVE" );
+                    intf_WarnMsg( 3, "vout: vout_Manage WM_MOVE" );
                     if( !p_vout->b_need_render )
                     {
                         p_vout->i_changes |= VOUT_SIZE_CHANGE;
@@ -317,7 +323,7 @@
                     break;
 
                 case WM_APP:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_APP" );
+            
        intf_WarnMsg( 3, "vout: vout_Manage WM_APP" );
                     if( !p_vout->b_need_render )
                     {
                         p_vout->i_changes |= VOUT_SIZE_CHANGE;
@@ -327,18 +333,18 @@
                     break;
 
                 case WM_PAINT:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_PAINT" );
+                    intf_WarnMsg( 4, "vout: vout_Manage WM_PAINT" );
                     break;
 
                 case WM_ERASEBKGND:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_ERASEBKGND" );
+                    intf_WarnMsg( 4, "vout: vout_Manage WM_ERASEBKGND" );
                     break;
 
                 case WM_MOUSEMOVE:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_MOUSEMOVE" );
+                    intf_WarnMsg( 4, "vout: vout_Manage WM_MOUSEMOVE" );
                     if( p_vout->p_sys->b_cursor )
                     {
-                    if( p_vout->p_sys->b_cursor_autohidden )
+                      
  if( p_vout->p_sys->b_cursor_autohidden )
                         {
                             p_vout->p_sys->b_cursor_autohidden = 0;
                             p_vout->p_sys->i_lastmoved = mdate();
@@ -355,7 +361,7 @@
                     /* the key events are first processed here. The next
                      * message processed by this main message loop will be the
                      * char translation of the key event */
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_KEYDOWN" );
+                    intf_WarnMsg( 3, "vout: vout_Manage WM_KEYDOWN" );
                     switch( msg.wParam )
                     {
                         case VK_ESCAPE:
@@ -368,7 +374,7 @@
                     break;
 
                 case WM_CHAR:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_CHAR" );
+                    intf_WarnMsg( 3, "vout: vout_Manage WM_CHAR" );
                     switch( msg.wParam )
                     {
                         case 'q':
@@
 -376,11 +382,39 @@
                             p_main->p_intf->b_die = 1;
                             break;
 
-                        case 'f':
+                        case 'f':                    /* switch to fullscreen */
                         case 'F':
                             p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
                             break;
 
+                        case 'y':                      /* switch to hard YUV */
+                        case 'Y':
+                            p_vout->i_changes |= VOUT_YUV_CHANGE;
+                            break;
+                          
+                        case 'c':                        /* toggle grayscale */
+                        case 'C':
+                            p_vout->b_grayscale = ! p_vout->b_grayscale;
+                            p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE;
+                            break;
+                          
+                        case 'i':                             /* toggle 
info */
+                        case 'I':
+                            p_vout->b_info = ! p_vout->b_info;
+                            p_vout->i_changes |= VOUT_INFO_CHANGE;
+                            break;
+
+                        case 's':                          /* toggle scaling */
+                        case 'S':
+                            p_vout->b_scale = ! p_vout->b_scale;
+                            p_vout->i_changes |= VOUT_SCALE_CHANGE;
+                            break;
+
+                        case ' ':                        /* toggle interface */
+                            p_vout->b_interface = ! p_vout->b_interface;
+                            p_vout->i_changes |= VOUT_INTF_CHANGE;
+                            break;
+
                         case '0': network_ChannelJoin( 0 ); break;
                         case '1': network_ChannelJoin( 1 ); break;
                         case '2': network_ChannelJoin( 2 ); break;
@@ -403,7 +437,7 @@
                     }
 
            
     default:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM Default %i",
+                    intf_WarnMsg( 4, "vout: vout_Manage WM Default %i",
                                   msg.message );
                 break;
             }
@@ -430,12 +464,29 @@
      */
     if( p_vout->i_changes & VOUT_SIZE_CHANGE )
     {
-        intf_WarnMsg( 3, "vout: WinDX vout_Manage Size Change" );
-        WinDXUpdateOverlay( p_vout );
+        intf_WarnMsg( 3, "vout: vout_Manage Size Change" );
+        DirectXUpdateOverlay( p_vout );
         p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
     }
 
     /*
+     * YUV Change 
+     */
+    if( p_vout->i_changes & VOUT_YUV_CHANGE )
+    {
+        p_vout->b_need_render = ! p_vout->b_need_render;
+        
+        /* Need to reopen display */
+        DirectXCloseSurface( p_vout );
+        if( DirectXCreateSurface( p_vout ) )
+        {
+          intf_ErrMsg( "error: can't reopen display after YUV change" );
+          return( 1 );
+        }
+        p_vou
t->i_changes &= ~VOUT_YUV_CHANGE;
+    }
+
+    /*
      * Fullscreen change
      */
     if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
@@ -463,7 +514,6 @@
         }
 
         SetWindowPlacement( p_vout->p_sys->hwnd, &window_placement );
-        /*WinDXUpdateOverlay( p_vout );*/
 
         p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
     }
@@ -472,7 +522,7 @@
      * Pointer change
      */
     if( ! p_vout->p_sys->b_cursor_autohidden &&
-        ( mdate() - p_vout->p_sys->i_lastmoved > 2000000 ) )
+        ( mdate() - p_vout->p_sys->i_lastmoved > 5000000 ) )
     {
         /* Hide the mouse automatically */
         p_vout->p_sys->b_cursor_autohidden = 1;
@@ -517,22 +567,86 @@
     DDSURFACEDESC ddsd;
     HRESULT       dxresult;
     int           i;
-    int           i_image_width  = p_vout->p_rendered_pic->i_width;
-    int           i_image_height = p_vout->p_rendered_pic->i_height;
+    int           i_image_width;
+    int           i_image_height;
+
 
+    intf_WarnMsg( 5, "vout: vout_Disp
lay" );
 
     if( (p_vout->p_sys->p_display == NULL) )
     {
-        intf_WarnMsg( 3, "vout error: WinDX no display!!" );
+        intf_WarnMsg( 3, "vout error: vout_Display no display!!" );
         return;
     }
 
     /* The first time this function is called it enables the display */
     p_vout->p_sys->b_display_enabled = 1;
 
+    /* if the size of the decoded pictures has changed then we close the
+     * video surface (which doesn't have the right size anymore). */
+    i_image_width = ( p_vout->p_rendered_pic ) ?
+      p_vout->p_rendered_pic->i_width : p_vout->p_sys->i_image_width;
+    i_image_height = ( p_vout->p_rendered_pic ) ?
+      p_vout->p_rendered_pic->i_height : p_vout->p_sys->i_image_height;
+
+    if( p_vout->p_sys->i_image_width != i_image_width
+        || p_vout->p_sys->i_image_height != i_image_height )
+    {
+        intf_WarnMsg( 3, "vout: video surface size changed" );
+        p_vout->p_sys->i_image_width = i_image_width;
+        p_vout->p_sys->i_image_height = i_image_hei
ght;
+        DirectXCloseSurface( p_vout );
+    }
+
     if( p_vout->b_need_render )
     {
+        RECT  rect_window;
+        POINT point_window;
+  
         /* Nothing yet */
+        if( p_vout->p_sys->p_surface == NULL )
+        {
+            intf_WarnMsg( 3, "vout: no video surface, open one..." );
+            if( DirectXCreateSurface( p_vout ) )
+            {
+                intf_WarnMsg( 3, "vout: cannot open a new video surface !!" );
+                return;
+            }
+            /* Display the surface */
+            p_vout->p_sys->b_display_enabled = 1;
+        }
+
+        /* Now get the coordinates of the window. We don't actually want the
+         * window coordinates but these of the usable surface inside the window
+         * By specification GetClientRect will always set rect_window.left and
+         * rect_window.top to 0 because the Client area is always relative to
+         * the container window */
+        GetClientRect(p_vout->p_sys->hwnd, &rect_window);
+        
+
        point_window.x = 0;
+        point_window.y = 0;
+        ClientToScreen(p_vout->p_sys->hwnd, &point_window);
+        rect_window.left = point_window.x;
+        rect_window.top = point_window.y;
+        
+        point_window.x = rect_window.right;
+        point_window.y = rect_window.bottom;
+        ClientToScreen(p_vout->p_sys->hwnd, &point_window);
+        rect_window.right = point_window.x;
+        rect_window.bottom = point_window.y;
+
+        /* Blit video surface to display */
+        dxresult = IDirectDrawSurface3_Blt(p_vout->p_sys->p_display,
+                                           &rect_window,
+                                           p_vout->p_sys->p_surface,
+                                           NULL,
+                                           0, NULL );
+        if( dxresult != DD_OK )
+        {
+            intf_WarnMsg( 3, "vout: could not Blit the surface" );
+            return;
+        }
+
     }
     else
     {
@@ -541,48 +655,37 @@
          * render
     
     */
         /* TODO: support for streams other than 4:2:0 */
-
-        /* if the size of the decoded pictures has changed then we close the
-         * YUVOverlay (which doesn't have the right size anymore). */
-        if( p_vout->p_sys->i_image_width != i_image_width
-            || p_vout->p_sys->i_image_height != i_image_height )
-        {
-            intf_WarnMsg( 3, "vout: WinDX overlay size changed" );
-            p_vout->p_sys->i_image_width = i_image_width;
-            p_vout->p_sys->i_image_height = i_image_height;
-            WinDXCloseYUVOverlay( p_vout );
-        }
 
-        if( p_vout->p_sys->p_overlay == NULL )
+        if( p_vout->p_sys->p_surface == NULL )
         {
-            intf_WarnMsg( 3, "vout: WinDX no overlay, open one..." );
-            if( WinDXCreateYUVOverlay( p_vout ) )
+            intf_WarnMsg( 3, "vout: no video surface, open one..." );
+            if( DirectXCreateSurface( p_vout ) )
             {
-                intf_WarnMsg( 3, "vout: WinDX cannot open a
 new overlay !!" );
+                intf_WarnMsg( 3, "vout: cannot open a new video surface !!" );
                 return;
             }
             /* Display the Overlay */
             p_vout->p_sys->b_display_enabled = 1;
-            WinDXUpdateOverlay( p_vout );
+            DirectXUpdateOverlay( p_vout );
         }
 
         /* Lock the overlay surface */
         memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
         ddsd.dwSize = sizeof(DDSURFACEDESC);
-        dxresult = IDirectDrawSurface_Lock(p_vout->p_sys->p_overlay, NULL,
-                                           &ddsd, DDLOCK_NOSYSLOCK, NULL);
+        dxresult = IDirectDrawSurface3_Lock(p_vout->p_sys->p_surface, NULL,
+                                            &ddsd, DDLOCK_NOSYSLOCK, NULL);
         if ( dxresult == DDERR_SURFACELOST )
         {
             /* Your surface can be lost (thanks to windows) so be sure
              * to check this and restore it if needed */
-            dxresult = IDirectDrawSurface_Restore( p_vout->p
_sys->p_overlay );
-            dxresult = IDirectDrawSurface_Lock( p_vout->p_sys->p_overlay,
-                                                NULL, &ddsd, DDLOCK_NOSYSLOCK
-                                                | DDLOCK_WAIT, NULL);
+            dxresult = IDirectDrawSurface3_Restore( p_vout->p_sys->p_surface );
+            dxresult = IDirectDrawSurface3_Lock( p_vout->p_sys->p_surface,
+                                                 NULL, &ddsd, DDLOCK_NOSYSLOCK
+                                                 | DDLOCK_WAIT, NULL);
         }
         if( dxresult != DD_OK )
         {
-            intf_WarnMsg( 3, "vout: WinDX could not lock the surface" );
+            intf_WarnMsg( 3, "vout: could not lock the surface" );
             return;
         }
 
@@ -634,8 +737,8 @@
         }
 
         /* Unlock the Surface */
-        dxresult = IDirectDrawSurface_Unlock(p_vout->p_sys->p_overlay,
-                                             ddsd.lpSurface );
+        dxresult = IDirectDrawSurfac
e3_Unlock(p_vout->p_sys->p_surface,
+                                              ddsd.lpSurface );
 
     }
 
@@ -646,7 +749,7 @@
 
 
 /*****************************************************************************
- * WinDXEventProc: This is the window event processing function.
+ * DirectXEventProc: This is the window event processing function.
  *****************************************************************************
  * On Windows, when you create a window you have to attach an event processing
  * function to it. The aim of this function is to manage "Queued Messages" and
@@ -656,28 +759,30 @@
  * Nonqueued Messages are those that Windows will send directly to this
  * function (like WM_DESTROY, WM_WINDOWPOSCHANGED...)
  *****************************************************************************/
-long FAR PASCAL WinDXEventProc( HWND hwnd, UINT message,
-                                WPARAM wParam, LPARAM lParam )
+long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
+                    
              WPARAM wParam, LPARAM lParam )
 {
     switch( message )
     {
 
+#if 0
     case WM_ACTIVATE:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_ACTIVED" );
+        intf_WarnMsg( 4, "vout: WinProc WM_ACTIVED" );
         break;
 
     case WM_CREATE:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_CREATE" );
+        intf_WarnMsg( 4, "vout: WinProc WM_CREATE" );
         break;
 
     /* the user wants to close the window */
     case WM_CLOSE:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_CLOSE" );
+        intf_WarnMsg( 4, "vout: WinProc WM_CLOSE" );
         break;
+#endif
 
     /* the window has been closed so shut down everything now */
     case WM_DESTROY:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_DESTROY" );
+        intf_WarnMsg( 4, "vout: WinProc WM_DESTROY" );
         PostQuitMessage( 0 );
         break;
 
@@ -686,60 +791,64 @@
         {
             case SC_SCREENSAVE:                     /* catch the screensaver */
             case SC_MONITORPOWER:              
/* catch the monitor turn-off */
-            intf_WarnMsg( 3, "vout: WinDX WinProc WM_SYSCOMMAND" );
+            intf_WarnMsg( 3, "vout: WinProc WM_SYSCOMMAND" );
             return 0;                      /* this stops them from happening */
         }
         break;
 
+#if 0
     case WM_MOVE:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_MOVE" );
+        intf_WarnMsg( 4, "vout: WinProc WM_MOVE" );
         break;
 
     case WM_SIZE:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_SIZE" );
+        intf_WarnMsg( 4, "vout: WinProc WM_SIZE" );
         break;
 
     case WM_MOVING:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_MOVING" );
+        intf_WarnMsg( 4, "vout: WinProc WM_MOVING" );
         break;
 
     case WM_SIZING:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_SIZING" );
+        intf_WarnMsg( 4, "vout: WinProc WM_SIZING" );
         break;
+#endif
 
     case WM_WINDOWPOSCHANGED:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_WINDOWPOSCHANGED" );
+        intf_WarnMsg( 3
, "vout: WinProc WM_WINDOWPOSCHANGED" );
         PostMessage( NULL, WM_APP, 0, 0);
         break;
 
+#if 0
     case WM_WINDOWPOSCHANGING:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_WINDOWPOSCHANGING" );
+        intf_WarnMsg( 3, "vout: WinProc WM_WINDOWPOSCHANGING" );
         break;
 
     case WM_PAINT:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_PAINT" );
+        intf_WarnMsg( 4, "vout: WinProc WM_PAINT" );
         break;
 
     case WM_ERASEBKGND:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_ERASEBKGND" );
+        intf_WarnMsg( 4, "vout: WinProc WM_ERASEBKGND" );
         break;
 
     default:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM Default %i", message );
+        intf_WarnMsg( 4, "vout: WinProc WM Default %i", message );
         break;
+#endif
     }
 
     return DefWindowProc(hwnd, message, wParam, lParam);
 }
 
 /*****************************************************************************
- * WinDXCreateWindow: create a windows window where the video will play.
+ 
* DirectXCreateWindow: create a windows window where the video will play.
  *****************************************************************************
  * Before creating a direct draw surface, we need to create a window in which
  * the video will be displayed. This window will also allow us to capture the
  * events.
  *****************************************************************************/
-static int WinDXCreateWindow( vout_thread_t *p_vout )
+static int DirectXCreateWindow( vout_thread_t *p_vout )
 {
     HINSTANCE hInstance;
     WNDCLASS  wc;                                 /* window class components */
@@ -770,7 +879,7 @@
         if( colorkey == GetNearestColor( hdc, colorkey ) )
           break;
     }
-    intf_WarnMsg( 3, "vout: WinDXCreateWindow background color:%i", colorkey );
+    intf_WarnMsg(3,"vout: DirectXCreateWindow background color:%i", colorkey);
     ReleaseDC( p_vout->p_sys->hwnd, hdc );
 
     /* create the actual brush */  
@@ -779,7 +888,7 @@
 
     /* fill in the window
 class structure */
     wc.style         = 0;                               /* no special styles */
-    wc.lpfnWndProc   = (WNDPROC)WinDXEventProc;             /* event handler */
+    wc.lpfnWndProc   = (WNDPROC)DirectXEventProc;           /* event handler */
     wc.cbClsExtra    = 0;                             /* no extra class data */
     wc.cbWndExtra    = 0;                            /* no extra window data */
     wc.hInstance     = hInstance;                                /* instance */
@@ -791,7 +900,7 @@
 
     /* register the window class */
     if (!RegisterClass(&wc)) {
-        intf_WarnMsg( 3, "vout: WinDX register window FAILED" );
+        intf_WarnMsg( 3, "vout: DirectXCreateWindow register window FAILED" );
         return (1);
     }
 
@@ -820,7 +929,7 @@
                     NULL);                        /* no additional arguments */
 
     if (p_vout->p_sys->hwnd == NULL) {
-        intf_WarnMsg( 3, "vout: WinDX create window FAILED" );
+        intf_WarnMsg( 3, "vout: DirectXCrea
teWindow create window FAILED" );
         return (1);
     }
 
@@ -831,72 +940,106 @@
 }
 
 /*****************************************************************************
- * WinDXInitDDraw: Takes care of all the DirectDraw initialisations
+ * DirectXInitDDraw: Takes care of all the DirectDraw initialisations
  *****************************************************************************
  * This function initialise and allocate resources for DirectDraw.
  *****************************************************************************/
-static int WinDXInitDDraw( vout_thread_t *p_vout )
+static int DirectXInitDDraw( vout_thread_t *p_vout )
 {
-    HRESULT     dxresult;
-    DWORD       flags;
+    HRESULT    dxresult;
+    HRESULT    (WINAPI *OurDirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *);
+    LPDIRECTDRAW  p_ddobject;
 
-    intf_WarnMsg( 3, "vout: WinDX WinDXInitDDraw" );
+    intf_WarnMsg( 3, "vout: DirectXInitDDraw" );
 
-    /* Initialize DirectDraw */
-    dxresult = DirectDrawCreate( NULL, &p_v
out->p_sys->p_ddobject, NULL );
-    if( dxresult != DD_OK )
+    /* load direct draw DLL */
+    p_vout->p_sys->hddraw_dll = LoadLibrary("DDRAW.DLL");
+    if( p_vout->p_sys->hddraw_dll == NULL )
     {
-        intf_ErrMsg( "vout error: can't initialize Direct Draw" );
+        intf_WarnMsg( 3, "vout: DirectXInitDDraw failed loading ddraw.dll" );
         return( 1 );
     }
+      
+    OurDirectDrawCreate = 
+      (void *)GetProcAddress(p_vout->p_sys->hddraw_dll, "DirectDrawCreate");
+    if ( OurDirectDrawCreate == NULL )
+    {
+        intf_ErrMsg( "vout error: DirectXInitDDraw failed GetProcAddress" );
+        FreeLibrary( p_vout->p_sys->hddraw_dll );
+        p_vout->p_sys->hddraw_dll = NULL;
+        return( 1 );    
+    }
 
-    /* Set DirectDraw Cooperative level, ie what control we want over Windows
-       display */
-    if( p_vout->b_fullscreen )
+    /* Initialize DirectDraw now */
+    dxresult = OurDirectDrawCreate( NULL, &p_ddobject, NULL );
+    if( dxresult != DD_OK )
     {
-        
flags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN;
+        intf_ErrMsg( "vout error: DirectXInitDDraw can't initialize DDraw" );
+        p_vout->p_sys->p_ddobject = NULL;
+        FreeLibrary( p_vout->p_sys->hddraw_dll );
+        p_vout->p_sys->hddraw_dll = NULL;
+        return( 1 );
     }
-    else
+
+    /* Set DirectDraw Cooperative level, ie what control we want over Windows
+     * display */
+    dxresult = IDirectDraw_SetCooperativeLevel( p_ddobject,
+                                           p_vout->p_sys->hwnd, DDSCL_NORMAL );
+    if( dxresult != DD_OK )
     {
-        flags = DDSCL_NORMAL;
+        intf_ErrMsg( "vout error: can't set direct draw cooperative level." );
+        IDirectDraw_Release( p_ddobject );
+        p_vout->p_sys->p_ddobject = NULL;
+        FreeLibrary( p_vout->p_sys->hddraw_dll );
+        p_vout->p_sys->hddraw_dll = NULL;
+        return( 1 );
     }
 
-    dxresult = IDirectDraw_SetCooperativeLevel( p_vout->p_sys->p_ddobject,
-                                               
 p_vout->p_sys->hwnd, flags );
+    /* Get the IDirectDraw2 interface */
+    dxresult = IDirectDraw_QueryInterface( p_ddobject, &IID_IDirectDraw2,
+                                        (LPVOID *)&p_vout->p_sys->p_ddobject );
     if( dxresult != DD_OK )
     {
-        intf_ErrMsg( "vout error: can't set direct draw cooperative level." );
-        IDirectDraw_Release(p_vout->p_sys->p_ddobject);
+        intf_ErrMsg( "vout error: can't get IDirectDraw2 interface." );
+        IDirectDraw_Release( p_ddobject );
         p_vout->p_sys->p_ddobject = NULL;
+        FreeLibrary( p_vout->p_sys->hddraw_dll );
+        p_vout->p_sys->hddraw_dll = NULL;
         return( 1 );
     }
+    else
+    {
+        /* Release the unused interface */
+        IDirectDraw_Release( p_ddobject );
+    }
 
     return( 0 );
 }
 
 /*****************************************************************************
- * WinDXCreateDisplay: create the DirectDraw display.
+ * DirectXCreateDisplay: create the DirectDraw display.
  ********
*********************************************************************
  * Create and initialize display according to preferences specified in the vout
  * thread fields.
  *****************************************************************************/
-static int WinDXCreateDisplay( vout_thread_t *p_vout )
+static int DirectXCreateDisplay( vout_thread_t *p_vout )
 {
-    DDCAPS        ddcaps;
-    HRESULT       dxresult;
-    DDSURFACEDESC ddsd;
-    BOOL          bHasOverlay, bHasColorKey, bCanStretch;
+    HRESULT              dxresult;
+    DDSURFACEDESC        ddsd;
+    LPDIRECTDRAWSURFACE  p_display;
+
+    intf_WarnMsg( 3, "vout: DirectXCreateDisplay" );
 
-    /* Now create the primary surface. This surface is the displayed surface */
-    /* The following two steps are important! */
+    /* Now create the primary surface. This surface is what you actually see
+     * on your screen */
     memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
     ddsd.dwSize = sizeof(DDSURFACEDESC);
     ddsd.dwFlags = DDSD_CA
PS;
     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
 
-    dxresult = IDirectDraw_CreateSurface( p_vout->p_sys->p_ddobject,
-                                          &ddsd,
-                                          &p_vout->p_sys->p_display, NULL );
+    dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,
+                                           &ddsd,
+                                           &p_display, NULL );
     if( dxresult != DD_OK )
     {
         intf_ErrMsg( "vout error: can't create direct draw primary surface." );
@@ -904,57 +1047,74 @@
         return( 1 );
     }
 
-#if 0
-    /* Now create a clipper for our window.
-     * This clipper prevents us to modify by mistake anything on the screen
-     * (primary surface) which doesn't belong to our window */
-    dxresult = IDirectDraw_CreateClipper(p_vout->p_sys->p_ddobject, 0,
-                                         &p_vout->p_sys->p_clipper, NULL);
-    if( dxresult != DD_OK )
+    dxresult = IDirectDrawSurface_QueryIn
terface( p_display,
+                                         &IID_IDirectDrawSurface3,
+                                         (LPVOID *)&p_vout->p_sys->p_display );
+    if ( dxresult != DD_OK )
     {
-        intf_ErrMsg( "vout error: can't create clipper." );
-        IDirectDrawSurface_Release( p_vout->p_sys->p_display );
+        intf_ErrMsg( "vout error: can't get IDirectDrawSurface3 interface." );
+        IDirectDrawSurface_Release( p_display );
         p_vout->p_sys->p_display = NULL;
         return( 1 );
     }
-
-    dxresult = IDirectDrawClipper_SetHWnd(p_vout->p_sys->p_clipper, 0,
-                                              p_vout->p_sys->hwnd);
-    if( dxresult != DD_OK )
+    else
     {
-        intf_ErrMsg( "vout error: can't attach clipper to window." );
-        IDirectDrawSurface_Release( p_vout->p_sys->p_display );
-        p_vout->p_sys->p_display = NULL;
-        return( 1 );
+        /* Release the old interface */
+        IDirectDrawSurface_Release( p_display );
     }
 
- 
   dxresult = IDirectDrawSurface_SetClipper(p_vout->p_sys->p_display,
-                                              p_vout->p_sys->p_clipper);
-    if( dxresult != DD_OK )
+
+    /* Create a video surface. This function will try to create an
+     * YUV overlay first and if it can't it will create a simple RGB surface */
+    if( DirectXCreateSurface( p_vout ) )
     {
-        intf_ErrMsg( "vout error: can't attach clipper to surface." );
-        IDirectDrawSurface_Release( p_vout->p_sys->p_display );
+        intf_ErrMsg( "vout error: can't create a video surface." );
+        IDirectDrawSurface3_Release( p_vout->p_sys->p_display );
         p_vout->p_sys->p_display = NULL;
         return( 1 );
     }
-#endif
+      
+    return( 0 );
+}
+
+/*****************************************************************************
+ * DirectXCreateSurface: create an YUV overlay or RGB surface for the video.
+ *****************************************************************************
+ * The best method of display 
is with an YUV overlay because the YUV->RGB
+ * conversion is done in hardware, so we'll try to create this surface first.
+ * If we fail, we'll try to create a plain RGB surface.
+ * ( Maybe we could also try an RGB overlay surface, which could have hardware
+ * scaling and which would also be faster in window mode because you don't
+ * need to do any blitting to the main display...)
+ *****************************************************************************/
+static int DirectXCreateSurface( vout_thread_t *p_vout )
+{
+    HRESULT dxresult;
+    DDSURFACEDESC ddsd;
+    LPDIRECTDRAWSURFACE p_surface;
+    DDCAPS ddcaps;
+
+    intf_WarnMsg( 3, "vout: DirectXCreateSurface" );
 
+    /* Disable display */
+    p_vout->p_sys->b_display_enabled = 0;
+
+#if 1
     /* Probe the capabilities of the hardware */
-    /* This is just an indication of whever or not we'll support overlay,
+    /* This is just an indication of whether or not we'll support overlay,
      * but with this test we don't know if we suppo
rt YUV overlay */
     memset( &ddcaps, 0, sizeof( DDCAPS ));
     ddcaps.dwSize = sizeof(DDCAPS);
-    dxresult = IDirectDraw_GetCaps( p_vout->p_sys->p_ddobject,
-                                    &ddcaps, NULL );
+    dxresult = IDirectDraw2_GetCaps( p_vout->p_sys->p_ddobject,
+                                     &ddcaps, NULL );
     if(dxresult != DD_OK )
     {
-        intf_ErrMsg( "vout error: can't get caps." );
-        bHasOverlay  = FALSE;
-        bHasColorKey = FALSE;
-        bCanStretch  = FALSE;
+        intf_WarnMsg( 3,"vout error: can't get caps." );
     }
     else
     {
+        BOOL bHasOverlay, bHasColorKey, bCanStretch;
+
         /* Determine if the hardware supports overlay surfaces */
         bHasOverlay = ((ddcaps.dwCaps & DDCAPS_OVERLAY) ==
                        DDCAPS_OVERLAY) ? TRUE : FALSE;
@@ -964,59 +1124,154 @@
         /* Determine if the hardware supports scaling of the overlay surface */
         bCanStretch = ((ddcaps.dwCaps & DDCAPS_OVERLAYSTRETCH) ==
           
             DDCAPS_OVERLAYSTRETCH) ? TRUE : FALSE;
-        intf_WarnMsg( 3, "vout: WinDX Caps: overlay=%i colorkey=%i stretch=%i",
+        intf_WarnMsg( 3, "vout: Dx Caps: overlay=%i colorkey=%i stretch=%i",
                          bHasOverlay, bHasColorKey, bCanStretch );
+
+        if( !bHasOverlay ) p_vout->b_need_render = 1;
     }
+#endif
+
 
-    p_vout->p_sys->p_overlay = NULL;
-    if( bHasOverlay && bHasColorKey && bCanStretch )
+    /* Create the video surface */
+    if( !p_vout->b_need_render )
     {
-        if( !WinDXCreateYUVOverlay( p_vout ) )
+        /* Now try to create the YUV overlay surface.
+         * This overlay will be displayed on top of the primary surface.
+         * A color key is used to determine whether or not the overlay will be
+         * displayed, ie the overlay will be displayed in place of the primary
+         * surface wherever the primary surface will have this color.
+         * The video window has been created with a background of this color so
+         *
 the overlay will be only displayed on top of this window */
+
+        memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
+        ddsd.dwSize = sizeof(DDSURFACEDESC);
+        ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+        ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+        ddsd.ddpfPixelFormat.dwFourCC = mmioFOURCC('Y','V','1','2');
+#ifdef NONAMELESSUNION
+        ddsd.ddpfPixelFormat.u1.dwYUVBitCount = 16;
+#else
+        ddsd.ddpfPixelFormat.dwYUVBitCount = 16;
+#endif
+        ddsd.dwFlags = DDSD_CAPS |
+                       DDSD_HEIGHT |
+                       DDSD_WIDTH |
+                       DDSD_PIXELFORMAT;
+        ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
+        ddsd.dwHeight =  p_vout->p_sys->i_image_height;
+        ddsd.dwWidth =  p_vout->p_sys->i_image_width;
+
+        dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,
+                                               &ddsd, &p_surface, NULL );
+        if( dxresult == DD_OK )
         {
-   
        /* Overlay created successfully */
-           p_vout->b_need_render = 0;
+            intf_WarnMsg( 3,"vout: DirectX YUV overlay created successfully" );
         }
+        else
+        {
+            intf_ErrMsg( "vout error: can't create YUV overlay surface." );
+            p_vout->b_need_render = 1;
+        }
     }
 
-
-    /* Now do some initialisation for video_output */
     if( p_vout->b_need_render )
     {
-        /* if we want a valid pointer to the surface memory, we must lock
-         * the surface */
+        /* Now try to create a plain RGB surface. */
         memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
         ddsd.dwSize = sizeof(DDSURFACEDESC);
-        dxresult = IDirectDrawSurface_Lock(p_vout->p_sys->p_display,
-                                           NULL, &ddsd,
-                                           DDLOCK_NOSYSLOCK, NULL);
-        if ( dxresult == DDERR_SURFACELOST )
+        ddsd.dwFlags = DDSD_HEIGHT |
+                       DDSD_WIDTH |
+                  
     DDSD_CAPS;
+        ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+        ddsd.dwHeight =  p_vout->p_sys->i_image_height;
+        ddsd.dwWidth =  p_vout->p_sys->i_image_width;
+
+        dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,
+                                               &ddsd, &p_surface, NULL );
+        if( dxresult == DD_OK )
         {
-            /* Your surface can be lost so be sure
-             * to check this and restore it if needed */
-            dxresult = IDirectDrawSurface_Restore( p_vout->p_sys->p_display );
-            dxresult = IDirectDrawSurface_Lock( p_vout->p_sys->p_display,
-                                                NULL, &ddsd, DDLOCK_NOSYSLOCK
-                                                | DDLOCK_WAIT, NULL);
+            intf_WarnMsg( 3,"vout: DirectX RGB surface created successfully" );
         }
-        if( dxresult != DD_OK )
+        else
         {
-            intf_WarnMsg( 3, "vout: WinDX could not lock the surface" );
+     
       intf_ErrMsg( "vout error: can't create RGB surface." );
+            p_vout->p_sys->p_surface = NULL;
             return( 1 );
         }
+    }
+      
+    /* Now that the surface is created, try to get a newer DirectX interface */
+    dxresult = IDirectDrawSurface_QueryInterface( p_surface,
+                                         &IID_IDirectDrawSurface3,
+                                         (LPVOID *)&p_vout->p_sys->p_surface );
+    if ( dxresult != DD_OK )
+    {
+        intf_ErrMsg( "vout error: can't get IDirectDrawSurface3 interface." );
+        IDirectDrawSurface_Release( p_surface );
+        p_vout->p_sys->p_surface = NULL;
+        return( 1 );
+    }
+    else
+    {
+        /* Release the old interface */
+        IDirectDrawSurface_Release( p_surface );
+    }
+
+    if( p_vout->b_need_render )
+    {
+        /* Hide the overlay for now */
+        IDirectDrawSurface3_UpdateOverlay(p_vout->p_sys->p_surface,
+                                          NULL,
+                 
                         p_vout->p_sys->p_display,
+                                          NULL,
+                                          DDOVER_HIDE,
+                                          NULL);
+    }
 
-        /* Set the pointer to the surface memory */
-        p_vout->p_sys->p_windx_buf[ 0 ] = ddsd.lpSurface;
-        /* back buffer, none for now */
-        p_vout->p_sys->p_windx_buf[ 1 ] = ddsd.lpSurface;
 
+    /* From now on, do some initialisation for video_output */
 
-        /* Set thread information */
-        p_vout->i_width =           ddsd.dwWidth;
-        p_vout->i_height =          ddsd.dwHeight;
+    /* if we want a valid pointer to the surface memory, we must lock
+     * the surface */
+
+    memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
+    ddsd.dwSize = sizeof(DDSURFACEDESC);
+    dxresult = IDirectDrawSurface3_Lock( p_vout->p_sys->p_surface, NULL, &ddsd,
+                                         DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
+    if ( dxresult == DDERR_SURFACELOST
 )
+    {
+        /* Your surface can be lost so be sure
+         * to check this and restore it if needed */
+        dxresult = IDirectDrawSurface3_Restore( p_vout->p_sys->p_surface );
+        dxresult = IDirectDrawSurface3_Lock( p_vout->p_sys->p_surface,
+                                             NULL, &ddsd, DDLOCK_NOSYSLOCK
+                                             | DDLOCK_WAIT, NULL);
+    }
+    if( dxresult != DD_OK )
+    {
+        intf_ErrMsg( "vout: DirectXCreateDisplay could not lock the surface" );
+        return( 1 );
+    }
 
+    /* Set the pointer to the surface memory */
+    p_vout->p_sys->p_directx_buf[ 0 ] = ddsd.lpSurface;
+    /* back buffer, none for now */
+    p_vout->p_sys->p_directx_buf[ 1 ] = ddsd.lpSurface;
+
+    /* Set thread information */
+    p_vout->i_width =  ddsd.dwWidth;
+    p_vout->i_height = ddsd.dwHeight;
 #ifdef NONAMELESSUNION
-        p_vout->i_bytes_per_line =  ddsd.u1.lPitch;
+    p_vout->i_bytes_per_line =  ddsd.u1.lPitch;
+#else
+    p_vout->i_byt
es_per_line =  ddsd.lPitch;
+#endif /* NONAMELESSUNION */
+
 
+    if( p_vout->b_need_render )
+    {
+        /* For an RGB surface we need to fill in some more info */
+#ifdef NONAMELESSUNION
         p_vout->i_screen_depth =    ddsd.ddpfPixelFormat.u1.dwRGBBitCount;
         p_vout->i_bytes_per_pixel = ddsd.ddpfPixelFormat.u1.dwRGBBitCount/8;
 
@@ -1024,8 +1279,6 @@
         p_vout->i_green_mask =      ddsd.ddpfPixelFormat.u3.dwGBitMask;
         p_vout->i_blue_mask =       ddsd.ddpfPixelFormat.u4.dwBBitMask;
 #else
-        p_vout->i_bytes_per_line =  ddsd.lPitch;
-
         p_vout->i_screen_depth =    ddsd.ddpfPixelFormat.dwRGBBitCount;
         p_vout->i_bytes_per_pixel = ddsd.ddpfPixelFormat.dwRGBBitCount/8;
 
@@ -1034,144 +1287,42 @@
         p_vout->i_blue_mask =       ddsd.ddpfPixelFormat.dwBBitMask;
 
 #endif /* NONAMELESSUNION */
-
-        /* Unlock the Surface */
-        dxresult = IDirectDrawSurface_Unlock(p_vout->p_sys->p_display,
-                                             ddsd.lpSurface )
;
-        /* FIXME: palette in 8bpp ?? */
-        /* Set and initialize buffers */
-        p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_windx_buf[ 0 ],
-                                 p_vout->p_sys->p_windx_buf[ 1 ] );
-    }
-    else
-    {
-        /* Lock the surface */
-        memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
-        ddsd.dwSize = sizeof(DDSURFACEDESC);
-        dxresult = IDirectDrawSurface_Lock(p_vout->p_sys->p_overlay,
-                                          NULL, &ddsd, DDLOCK_NOSYSLOCK, NULL);
-        if ( dxresult == DDERR_SURFACELOST )
-        {
-            /* Your surface can be lost (thanks to windows) so be sure
-             * to check this every time you want to do something with
-             * it */
-            dxresult = IDirectDrawSurface_Restore(
-                                           p_vout->p_sys->p_overlay );
-            dxresult = IDirectDrawSurface_Lock( p_vout->p_sys->p_overlay
-                        , NULL, &ddsd,DDLOCK_NOSYSLOCK| DDLOCK_WAIT, N
ULL);
-        }
-        if( dxresult != DD_OK )
-        {
-            intf_WarnMsg( 3, "vout: WinDX could not lock the surface" );
-            return( 1 );
-        }
-
-        p_vout->p_sys->p_windx_buf[ 0 ] = ddsd.lpSurface;
-        p_vout->p_sys->p_windx_buf[ 1 ] = ddsd.lpSurface;
-
-        /* Set thread information */
-        p_vout->i_width =           ddsd.dwWidth;
-        p_vout->i_height =          ddsd.dwHeight;
-#ifdef NONAMELESSUNION
-        p_vout->i_bytes_per_line =  ddsd.u1.lPitch;
-#else
-        p_vout->i_bytes_per_line =  ddsd.lPitch;
-#endif /* NONAMELESSUNION */
-
-        /* Unlock the Surface */
-        dxresult = IDirectDrawSurface_Unlock(p_vout->p_sys->p_overlay,
-                                             ddsd.lpSurface );
-
-        p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_windx_buf[ 0 ],
-                                 p_vout->p_sys->p_windx_buf[ 1 ] );
     }
-
-    return( 0 );
-}
-
-/***************************************************************************
**
- * WinDXCreateYUVOveraly: create an YUV overlay surface for the video.
- *****************************************************************************
- * The best method of display is with an YUV overlay because the YUV->RGB
- * conversion is done in hardware.
- * This function will try to create an YUV overlay.
- *****************************************************************************/
-static int WinDXCreateYUVOverlay( vout_thread_t *p_vout )
-{
-    HRESULT dxresult;
-    DDSURFACEDESC ddsd;
-
-    /* Now create the overlay surface. This overlay will be displayed on
-     * top of the primary surface.
-     * A color key is used to determine whether or not the overlay will be
-     * displayed, ie the overlay will be displayed in place of the primary
-     * surface wherever the primary surface will have this color.
-     * The video window has been created with a background of this color so
-     * the overlay will be only displayed on top of this window */
 
-    memset( &ddsd, 0, sizeof( DDSUR
FACEDESC ));
-    ddsd.dwSize = sizeof(DDSURFACEDESC);
-    ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
-    ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
-    ddsd.ddpfPixelFormat.dwFourCC = mmioFOURCC('Y','V','1','2');
-#ifdef NONAMELESSUNION
-    ddsd.ddpfPixelFormat.u1.dwYUVBitCount = 16;
-#else
-    ddsd.ddpfPixelFormat.dwYUVBitCount = 16;
-#endif
+    /* Unlock the Surface */
+    dxresult = IDirectDrawSurface3_Unlock(p_vout->p_sys->p_surface,
+                                          ddsd.lpSurface );
+
+    /* Set and initialize buffers */
+    p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_directx_buf[ 0 ],
+                           p_vout->p_sys->p_directx_buf[ 1 ] );
 
-    ddsd.dwSize = sizeof(DDSURFACEDESC);
-    ddsd.dwFlags = DDSD_CAPS |
-                   DDSD_HEIGHT |
-                   DDSD_WIDTH |
-                   DDSD_PIXELFORMAT;
-    ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
-    ddsd.dwHeight =  p_vout->p_sys->i_image_height;
-    ddsd.dwWidth =  p_vou
t->p_sys->i_image_width;
-
-    dxresult = IDirectDraw_CreateSurface( p_vout->p_sys->p_ddobject,
-                                          &ddsd,
-                                          &p_vout->p_sys->p_overlay, NULL );
-    if( dxresult != DD_OK )
-    {
-        intf_ErrMsg( "vout error: can't create overlay surface." );
-        p_vout->p_sys->p_overlay = NULL;
-    }
-    else
-    {
-        intf_WarnMsg( 3, "vout: WinDX YUV overlay created successfully" );
-    }
-    /* Hide the overlay for now */
-    IDirectDrawSurface_UpdateOverlay(p_vout->p_sys->p_overlay,
-                                     NULL,
-                                     p_vout->p_sys->p_display,
-                                     NULL,
-                                     DDOVER_HIDE,
-                                     NULL);
 
     return ( 0 );
 }
 
+
 /*****************************************************************************
- * WinDXUpdateOverlay: Move or resize overlay surface on video display.
+ * DirectXUpdat
eOverlay: Move or resize overlay surface on video display.
  *****************************************************************************
  * This function is used to move or resize an overlay surface on the screen.
  * Ususally the overlay is moved by the user and thus, by a move or resize
  * event (in vout_Manage).
  *****************************************************************************/
-static int WinDXUpdateOverlay( vout_thread_t *p_vout )
+static int DirectXUpdateOverlay( vout_thread_t *p_vout )
 {
     DDOVERLAYFX     ddofx;
-    RECT            rect_window, rect_image;
+    RECT            rect_window, rect_window_backup, rect_image;
     POINT           point_window;
     DWORD           dwFlags;
     HRESULT         dxresult;
     DWORD           dw_colorkey;
     DDPIXELFORMAT   pixel_format;
+    DDSURFACEDESC   ddsd;
 
-    if( p_vout->p_sys->p_overlay == NULL || p_vout->b_need_render)
+    if( p_vout->p_sys->p_surface == NULL || p_vout->b_need_render )
     {
-        intf_WarnMsg( 3, "
vout: WinDX no overlay !!" );
+        intf_WarnMsg( 3, "vout: DirectXUpdateOverlay no overlay !!" );
         return( 0 );
     }
 
@@ -1292,16 +1443,65 @@
 
     /* It seems we can't feed the UpdateOverlay directdraw function with
      * negative values so we have to clip the computed rectangles */
-    /* FIXME */
+    memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
+    ddsd.dwSize = sizeof(DDSURFACEDESC);
+    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
+    IDirectDraw2_GetDisplayMode( p_vout->p_sys->p_ddobject, &ddsd );
+
+    rect_window_backup = rect_window;
 
+    /* Clip the destination window */
+    rect_window.left = (rect_window.left < 0) ? 0 : rect_window.left;
+    rect_window.right = (rect_window.right < 0) ? 0 : rect_window.right;
+    rect_window.top = (rect_window.top < 0) ? 0 : rect_window.top;
+    rect_window.bottom = (rect_window.bottom < 0) ? 0 : rect_window.bottom;
+
+    rect_window.left = (rect_window.left > ddsd.dwWidth) ? ddsd.dwWidth
+      : rect_window.left;
+    rect_window.right 
= (rect_window.right > ddsd.dwWidth) ? ddsd.dwWidth
+      : rect_window.right;
+    rect_window.top = (rect_window.top > ddsd.dwHeight) ? ddsd.dwHeight
+      : rect_window.top;
+    rect_window.bottom = (rect_window.bottom > ddsd.dwHeight) ? ddsd.dwHeight
+      : rect_window.bottom;
+
+    intf_WarnMsg( 3, "vout: DirectXUpdateOverlay window coords: %i,%i,%i,%i",
+                  rect_window.left, rect_window.top,
+                  rect_window.right, rect_window.bottom);
+
+    /* Clip the source image */
+    rect_image.left = ( rect_window.left == rect_window_backup.left ) ? 0
+      : labs(rect_window_backup.left - rect_window.left) *
+      p_vout->p_rendered_pic->i_width /
+      (rect_window_backup.right - rect_window_backup.left);
+    rect_image.right = ( rect_window.right == rect_window_backup.right ) ?
+      p_vout->p_rendered_pic->i_width
+      : p_vout->p_rendered_pic->i_width -
+      labs(rect_window_backup.right - rect_window.right) *
+      p_vout->p_rendered_pic->i_width /
+      (rect
_window_backup.right - rect_window_backup.left);
+    rect_image.top = ( rect_window.top == rect_window_backup.top ) ? 0
+      : labs(rect_window_backup.top - rect_window.top) *
+      p_vout->p_rendered_pic->i_height /
+      (rect_window_backup.bottom - rect_window_backup.top);
+    rect_image.bottom = ( rect_window.bottom == rect_window_backup.bottom ) ?
+      p_vout->p_rendered_pic->i_height
+      : p_vout->p_rendered_pic->i_height -
+      labs(rect_window_backup.bottom - rect_window.bottom) *
+      p_vout->p_rendered_pic->i_height /
+      (rect_window_backup.bottom - rect_window_backup.top);
+
+    intf_WarnMsg( 3, "vout: DirectXUpdateOverlay image coords: %i,%i,%i,%i",
+                  rect_image.left, rect_image.top,
+                  rect_image.right, rect_image.bottom);
 
     /* compute the colorkey pixel value from the RGB value we've got */
     memset( &pixel_format, 0, sizeof( DDPIXELFORMAT ));
     pixel_format.dwSize = sizeof( DDPIXELFORMAT );
-    dxresult = IDirectDrawSurface_GetPix
elFormat( p_vout->p_sys->p_display,
-                                                  &pixel_format );
+    dxresult = IDirectDrawSurface3_GetPixelFormat( p_vout->p_sys->p_display,
+                                                   &pixel_format );
     if( dxresult != DD_OK )
-        intf_WarnMsg( 3, "vout: WinDX GetPixelFormat failed !!" );
+        intf_WarnMsg( 3, "vout: DirectXUpdateOverlay GetPixelFormat failed" );
     dw_colorkey = (DWORD)p_vout->p_sys->i_colorkey;
 #ifdef NONAMELESSUNION
     dw_colorkey = (DWORD)((( dw_colorkey * pixel_format.u2.dwRBitMask) / 255)
@@ -1319,34 +1519,35 @@
 
     dwFlags = DDOVER_KEYDESTOVERRIDE | DDOVER_SHOW;
 
-    dxresult = IDirectDrawSurface_UpdateOverlay(p_vout->p_sys->p_overlay,
-                                                NULL,    /*&rect_image,*/
-                                                p_vout->p_sys->p_display,
-                                                &rect_window,
-                                                dwFlags,
-            
                                    &ddofx);
+    dxresult = IDirectDrawSurface3_UpdateOverlay(p_vout->p_sys->p_surface,
+                                                 &rect_image,
+                                                 p_vout->p_sys->p_display,
+                                                 &rect_window,
+                                                 dwFlags,
+                                                 &ddofx);
     if(dxresult != DD_OK)
     {
-        intf_WarnMsg( 3, "vout: WinDX can't move or resize overlay" );
+        intf_WarnMsg( 3,
+          "vout: DirectXUpdateOverlay can't move or resize overlay" );
     }
 
     return ( 0 );
 }
 
 /*****************************************************************************
- * WinDXCloseWindow: close the window created by WinDXCreateWindow
+ * DirectXCloseWindow: close the window created by DirectXCreateWindow
  *****************************************************************************
- * This function returns all resources alloc
ated by WinDXCreateWindow.
+ * This function returns all resources allocated by DirectXCreateWindow.
  *****************************************************************************/
-static void WinDXCloseWindow( vout_thread_t *p_vout )
+static void DirectXCloseWindow( vout_thread_t *p_vout )
 {
     HINSTANCE hInstance;
 
-    intf_WarnMsg( 3, "vout: WinDXCloseWindow" );
-    if( p_vout->p_sys->hwnd != INVALID_HANDLE_VALUE )
+    intf_WarnMsg( 3, "vout: DirectXCloseWindow" );
+    if( p_vout->p_sys->hwnd != NULL )
     {
         DestroyWindow( p_vout->p_sys->hwnd);
-        p_vout->p_sys->hwnd = INVALID_HANDLE_VALUE;
+        p_vout->p_sys->hwnd = NULL;
     }
 
     hInstance = GetModuleHandle(NULL);
@@ -1354,74 +1555,77 @@
                      hInstance );          /* handle to application instance */
 
     /* free window background brush */
-    if( p_vout->p_sys->hwnd != INVALID_HANDLE_VALUE )
+    if( p_vout->p_sys->hwnd != NULL )
     {
         DeleteObject( p_vout->p_sys->hbrush );
-        p_vout
->p_sys->hbrush = INVALID_HANDLE_VALUE;
+        p_vout->p_sys->hbrush = NULL;
     }
 }
 
 /*****************************************************************************
- * WinDXCloseDDraw: Release the DDraw object allocated by WinDXInitDDraw
+ * DirectXCloseDDraw: Release the DDraw object allocated by DirectXInitDDraw
  *****************************************************************************
- * This function returns all resources allocated by WinDXInitDDraw.
+ * This function returns all resources allocated by DirectXInitDDraw.
  *****************************************************************************/
-static void WinDXCloseDDraw( vout_thread_t *p_vout )
+static void DirectXCloseDDraw( vout_thread_t *p_vout )
 {
-    intf_WarnMsg(3, "vout: WinDXCloseDDraw" );
+    intf_WarnMsg(3, "vout: DirectXCloseDDraw" );
     if( p_vout->p_sys->p_ddobject != NULL )
     {
-        IDirectDraw_Release(p_vout->p_sys->p_ddobject);
+        IDirectDraw2_Release(p_vout->p_sys->p_ddobject);
         p_vout->p_sys
->p_ddobject = NULL;
     }
+
+    if( p_vout->p_sys->hddraw_dll != NULL )
+    {
+        FreeLibrary( p_vout->p_sys->hddraw_dll );
+        p_vout->p_sys->hddraw_dll = NULL;
+    }
 }
 
 /*****************************************************************************
- * WinDXCloseDisplay: close and reset DirectX device
+ * DirectXCloseDisplay: close and reset the DirectX display device
  *****************************************************************************
- * This function returns all resources allocated by WinDXCreateDisplay and
- * restore the original state of the device.
+ * This function returns all resources allocated by DirectXCreateDisplay.
  *****************************************************************************/
-static void WinDXCloseDisplay( vout_thread_t *p_vout )
+static void DirectXCloseDisplay( vout_thread_t *p_vout )
 {
-    intf_WarnMsg( 3, "vout: WinDXCloseDisplay" );
+    intf_WarnMsg( 3, "vout: DirectXCloseDisplay" );
     if( p_vout->p_sys->p_display != NULL )
     {
-   
     if( p_vout->p_sys->p_overlay != NULL )
-        {
-            intf_WarnMsg( 3, "vout: WinDXCloseDisplay overlay" );
-            IDirectDraw_Release( p_vout->p_sys->p_overlay );
-            p_vout->p_sys->p_overlay = NULL;
-        }
-
-        if( p_vout->p_sys->p_clipper != NULL )
-        {
-            intf_WarnMsg( 3, "vout: WinDXCloseDisplay clipper" );
-            IDirectDraw_Release( p_vout->p_sys->p_clipper );
-            p_vout->p_sys->p_clipper = NULL;
-        }
+        DirectXCloseSurface( p_vout );
 
-        intf_WarnMsg( 3, "vout: WinDXCloseDisplay display" );
-        IDirectDraw_Release( p_vout->p_sys->p_display );
+        intf_WarnMsg( 3, "vout: DirectXCloseDisplay display" );
+        IDirectDraw2_Release( p_vout->p_sys->p_display );
         p_vout->p_sys->p_display = NULL;
     }
 }
 
 /*****************************************************************************
- * WinDXCloseYUVOverlay: close the overlay surface
+ * DirectXCloseSurface: close the YUV overlay or RGB surface.
  *****************************************************************************
- * This function returns all resources allocated by the overlay surface.
+ * This function returns all resources allocated by the surface.
  * We also call this function when the decoded picture change its dimensions
  * (in that case we close the overlay surface and reopen another with the
  * right dimensions).
  *****************************************************************************/
-static void WinDXCloseYUVOverlay( vout_thread_t *p_vout )
+static void DirectXCloseSurface( vout_thread_t *p_vout )
 {
-    intf_WarnMsg( 3, "vout: WinDXCloseYUVOverlay" );
-    if( p_vout->p_sys->p_overlay != NULL )
+    intf_WarnMsg( 3, "vout: DirectXCloseSurface" );
+    if( p_vout->p_sys->p_surface != NULL )
+    {
+        intf_WarnMsg( 3, "vout: DirectXCloseSurface surface" );
+        IDirectDraw2_Release( p_vout->p_sys->p_surface );
+        p_vout->p_sys->p_surface = NULL;
+    }
+
+    if( p_vout->p_sys->p_clipper != NULL )
     {

-        IDirectDraw_Release( p_vout->p_sys->p_overlay );
-        p_vout->p_sys->p_overlay = NULL;
+        intf_WarnMsg( 3, "vout: DirectXCloseSurface clipper" );
+        IDirectDraw2_Release( p_vout->p_sys->p_clipper );
+        p_vout->p_sys->p_clipper = NULL;
     }
+
+    /* Disable any display */
     p_vout->p_sys->b_display_enabled = 0;
 }
Index: src/interface/main.c
===================================================================
RCS file: /var/cvs/videolan/vlc/src/interface/main.c,v
retrieving revision 1.100
diff -u -r1.100 main.c
--- src/interface/main.c	2001/06/12 00:30:41	1.100
+++ src/interface/main.c	2001/06/12 06:06:42
@@ -916,7 +916,9 @@
 
     i_illegal = 1;
     
+#ifndef WIN32
     sigrelse( i_signal );
+#endif
     longjmp( env, 1 );
 }
 
Index: src/video_output/video_output.c
===================================================================
RCS file: /var/cvs/videolan/vlc/src/video_output/video_output.c,v
retrieving revision 1.131
diff -u -r1.131 video_output.c
--- src/video_outp
ut/video_output.c	2001/05/31 03:57:54	1.131
+++ src/video_output/video_output.c	2001/06/12 06:06:43
@@ -979,6 +979,7 @@
     while( (!p_vout->b_die) && (!p_vout->b_error) )
     {
         /* Initialize loop variables */
+        p_vout->p_rendered_pic = NULL;
         p_pic =         NULL;
         p_subpic =      NULL;
         p_ephemer =     NULL;






More information about the vlc-devel mailing list