]> git.sesse.net Git - vlc/commitdiff
* DirectX video output plugin now uses triple buffering for YUV overlay. This
authorGildas Bazin <gbazin@videolan.org>
Tue, 23 Apr 2002 22:07:05 +0000 (22:07 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 23 Apr 2002 22:07:05 +0000 (22:07 +0000)
  improves the video quality a lot (no tearing) without affecting performance.
  (I knew double buffering sucked but I just discovered why triple buffering
   is better: you don't have to wait for the vsync to flip the buffers).

* Fixed the DirectX video output for non-overlay modes. It was only working
  in RGB16 before.

* Fixed the mouse autohidding feature in the DirectX plugin
 (at least partially).

* Fixed the spu decoder to take the pitch of the destination picture into
  account when rendering the subtitles (Implemented only for the YUV modes).

plugins/directx/vout_directx.c
plugins/directx/vout_directx.h
plugins/directx/vout_events.c
plugins/spudec/spu_decoder.c

index c7ea2596306c0cd254ffd753b18d91d3f374711e..f84246dc89120906ed8f899c979ba38c7ce5859b 100644 (file)
@@ -2,7 +2,7 @@
  * vout_directx.c: Windows DirectX video output display method
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: vout_directx.c,v 1.30 2002/04/05 01:05:22 gbazin Exp $
+ * $Id: vout_directx.c,v 1.31 2002/04/23 22:07:05 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
  *
  * If YUV overlay is not supported this plugin will use RGB offscreen video
  * surfaces that will be blitted onto the primary surface (display) to
- * effectively display the pictures. this fallback method enables us to display
- * video in window mode.
- * Another fallback method (which isn't implemented) would be take the
- * exclusive control of the screen so we could spare the blitting process and
- * decode directly to video memory. This should theoretically allow for better
- * performance (although on my system it is actually slower) but this is
- * restricted to fullscreen video.
+ * effectively display the pictures. This fallback method also enables us to
+ * display video in window mode.
  * 
  *****************************************************************************/
 #include <errno.h>                                                 /* ENOMEM */
@@ -85,7 +80,7 @@ static void DirectXCloseDDraw     ( vout_thread_t *p_vout );
 static int  DirectXCreateDisplay  ( vout_thread_t *p_vout );
 static void DirectXCloseDisplay   ( vout_thread_t *p_vout );
 static int  DirectXCreateSurface  ( vout_thread_t *p_vout,
-                                    LPDIRECTDRAWSURFACE3 *, int, int );
+                                    LPDIRECTDRAWSURFACE3 *, int, int, int );
 static void DirectXCloseSurface   ( vout_thread_t *p_vout,
                                     LPDIRECTDRAWSURFACE3 );
 static int  DirectXCreateClipper  ( vout_thread_t *p_vout );
@@ -135,9 +130,7 @@ static int vout_Create( vout_thread_t *p_vout )
     SetRectEmpty( &p_vout->p_sys->rect_display );
     p_vout->p_sys->b_using_overlay = !config_GetIntVariable( "nooverlay" );
 
-    p_vout->p_sys->b_cursor = 1;
-
-    p_vout->p_sys->b_cursor_autohidden = 0;
+    p_vout->p_sys->b_cursor_hidden = 0;
     p_vout->p_sys->i_lastmoved = mdate();
 
     /* Set main window's size */
@@ -194,7 +187,7 @@ static int vout_Create( vout_thread_t *p_vout )
         p_vout->p_sys->b_event_thread_die = 1;
         /* we need to be sure DirectXEventThread won't stay stuck in
          * GetMessage, so we send a fake message */
-        PostMessage( p_vout->p_sys->hwnd, WM_CHAR, (WPARAM)'^', 0);
+        PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0);
         vlc_thread_join( p_vout->p_sys->event_thread_id );
 
         return ( 1 );
@@ -210,19 +203,12 @@ static int vout_Create( vout_thread_t *p_vout )
         p_vout->p_sys->b_event_thread_die = 1;
         /* we need to be sure DirectXEventThread won't stay stuck in
          * GetMessage, so we send a fake message */
-        PostMessage( p_vout->p_sys->hwnd, WM_CHAR, (WPARAM)'^', 0);
+        PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0);
         vlc_thread_join( p_vout->p_sys->event_thread_id );
 
         return ( 1 );
     }
 
-    /* Attach the current thread input queue to the events thread qeue.
-     * This allows us to hide or show the cursor in vout_Manage() */
-    ShowCursor( TRUE ); ShowCursor( FALSE );           /* create input queue */
-    AttachThreadInput( GetCurrentThreadId(),
-                       GetWindowThreadProcessId( p_vout->p_sys->hwnd, NULL ),
-                       1 );
-
     return( 0 );
 }
 
@@ -284,7 +270,7 @@ static void vout_Destroy( vout_thread_t *p_vout )
     if( p_vout->p_sys->i_event_thread_status == THREAD_READY &&
         p_vout->p_sys->hwnd )
     {
-        PostMessage( p_vout->p_sys->hwnd, WM_CHAR, (WPARAM)'^', 0);
+        PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0);
         vlc_thread_join( p_vout->p_sys->event_thread_id );
     }
 
@@ -377,28 +363,14 @@ static int vout_Manage( vout_thread_t *p_vout )
     /*
      * Pointer change
      */
-    if( ! p_vout->p_sys->b_cursor_autohidden &&
-        ( mdate() - p_vout->p_sys->i_lastmoved > 5000000 ) )
+    if( (!p_vout->p_sys->b_cursor_hidden) &&
+        ( (mdate() - p_vout->p_sys->i_lastmoved) > 5000000 ) )
     {
         /* Hide the mouse automatically */
-        p_vout->p_sys->b_cursor_autohidden = 1;
-        ShowCursor( FALSE );
+        p_vout->p_sys->b_cursor_hidden = 1;
+        PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
     }
 
-#if 0
-    if( p_vout->i_changes & VOUT_CURSOR_CHANGE
-        || p_vout->p_sys->i_changes & VOUT_CURSOR_CHANGE )
-    {
-        p_vout->p_sys->b_cursor = ! p_vout->p_sys->b_cursor;
-
-        ShowCursor( p_vout->p_sys->b_cursor &&
-                     ! p_vout->p_sys->b_cursor_autohidden );
-
-        p_vout->i_changes &= ~VOUT_CURSOR_CHANGE;
-        p_vout->p_sys->i_changes &= ~VOUT_CURSOR_CHANGE;
-    }
-#endif
-
     /* Check if the event thread is still running */
     if( p_vout->p_sys->b_event_thread_die )
         return 1; /* exit */
@@ -469,8 +441,10 @@ static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
     else /* using overlay */
     {
 
-#if 0
-        /* Flip the overlay buffers */
+        /* Flip the overlay buffers if we are using back buffers */
+        if( p_pic->p_sys->p_front_surface == p_pic->p_sys->p_surface )
+        return;
+
         dxresult = IDirectDrawSurface3_Flip( p_pic->p_sys->p_front_surface,
                                              NULL, DDFLIP_WAIT );
         if ( dxresult == DDERR_SURFACELOST )
@@ -488,7 +462,6 @@ 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" );
-#endif
 
         if( !DirectXGetSurfaceDesc( p_pic ) )
         {
@@ -727,7 +700,8 @@ static int DirectXCreateClipper( vout_thread_t *p_vout )
  *****************************************************************************/
 static int DirectXCreateSurface( vout_thread_t *p_vout,
                                  LPDIRECTDRAWSURFACE3 *pp_surface_final,
-                                 int i_chroma, int b_overlay )
+                                 int i_chroma, int b_overlay,
+                                 int i_backbuffers )
 {
     HRESULT dxresult;
     LPDIRECTDRAWSURFACE p_surface;
@@ -754,15 +728,15 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
         ddsd.dwFlags = DDSD_CAPS |
                        DDSD_HEIGHT |
                        DDSD_WIDTH |
-                     //DDSD_BACKBUFFERCOUNT |
                        DDSD_PIXELFORMAT;
+        ddsd.dwFlags |= (i_backbuffers ? DDSD_BACKBUFFERCOUNT : 0);
         ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY |
-                            //DDSCAPS_COMPLEX |
-                            //DDSCAPS_FLIP |
                               DDSCAPS_VIDEOMEMORY;
+        ddsd.ddsCaps.dwCaps |= (i_backbuffers ? DDSCAPS_COMPLEX | DDSCAPS_FLIP
+                                : 0 );
         ddsd.dwHeight = p_vout->render.i_height;
         ddsd.dwWidth = p_vout->render.i_width;
-        ddsd.dwBackBufferCount = 1;                       /* One back buffer */
+        ddsd.dwBackBufferCount = i_backbuffers;
 
         dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,
                                                &ddsd,
@@ -942,54 +916,62 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
     int i;
     LPDIRECTDRAWSURFACE3 p_surface;
 
-#if 0
-    /* We couldn't use an YUV overlay so we need to indicate to video_output
-     * which format we are falling back to */
-    switch( )
-    {
-        case 8: /* FIXME: set the palette */
-            p_vout->output.i_chroma = FOURCC_RGB2; break;
-        case 15:
-            p_vout->output.i_chroma = FOURCC_RV15; break;
-        case 16:
-            p_vout->output.i_chroma = FOURCC_RV16; break;
-        case 24:
-            p_vout->output.i_chroma = FOURCC_RV24; break;
-        case 32:
-            p_vout->output.i_chroma = FOURCC_RV32; break;
-        default:
-            intf_ErrMsg( "vout error: unknown screen depth" );
-            return( 0 );
-    }
-#endif
-
     intf_WarnMsg( 3, "vout: NewPictureVec" );
 
     I_OUTPUTPICTURES = 0;
 
-    /* chroma asked for */
-    p_vout->output.i_chroma = p_vout->render.i_chroma;
-
-    /* hack */
-#if 1
-    if( p_vout->render.i_chroma == FOURCC_I420 )
-        p_vout->output.i_chroma = FOURCC_YV12;
-#endif
+    /* Choose the chroma we will try first. */
+    switch( p_vout->render.i_chroma )
+    {
+        case FOURCC_YUY2:
+        case FOURCC_YUNV:
+            p_vout->output.i_chroma = FOURCC_YUY2;
+            break;
+        case FOURCC_UYVY:
+        case FOURCC_UYNV:
+        case FOURCC_Y422:
+            p_vout->output.i_chroma = FOURCC_UYVY;
+            break;
+        case FOURCC_YVYU:
+            p_vout->output.i_chroma = FOURCC_YVYU;
+            break;
+        case FOURCC_YV12:
+        case FOURCC_I420:
+        case FOURCC_IYUV:
+        default:
+            p_vout->output.i_chroma = FOURCC_YV12;
+            break;
+    }
 
-    /* First we try to create an overlay surface.
-     * It looks like with most hardware it's not possible to create several
-     * overlay surfaces, and even if it was I bet it would be slower anyway to
-     * use them as direct buffers because they usually reside in video memory
-     * which is quite slow.
-     * So the overlay surface (with a back-buffer) that we create won't be used
-     * to decode directly into it but instead picture buffers in system memory
-     * will be blitted to it. */
+    /* First we try to use an YUV overlay surface.
+     * The overlay surface that we create won't be used to decode directly
+     * into it because accessing video memory directly is way to slow (remember
+     * that pictures are decoded macroblock per macroblock). Instead the video
+     * will be decoded in picture buffers in system memory which will then be
+     * memcpy() to the overlay surface. */
     if( p_vout->p_sys->b_using_overlay )
     {
-        if( DirectXCreateSurface( p_vout, &p_surface, p_vout->output.i_chroma,
-                                  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). */
+        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 )
+            b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
+                                                p_vout->output.i_chroma,
+                                                p_vout->p_sys->b_using_overlay,
+                                                0 /* number of backbuffers */);
+
+        if( b_result_ok )
         {
             DDSCAPS dds_caps;
+            picture_t front_pic;
+            picture_sys_t front_pic_sys;
+            front_pic.p_sys = &front_pic_sys;
 
             /* Allocate internal structure */
             p_pic[0].p_sys = malloc( sizeof( picture_sys_t ) );
@@ -1003,7 +985,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
             p_pic[0].p_sys->p_front_surface = p_surface;
 
             /* Get the back buffer */
-            memset( &dds_caps, 0, sizeof( DDSCAPS ));
+            memset( &dds_caps, 0, sizeof( DDSCAPS ) );
             dds_caps.dwCaps = DDSCAPS_BACKBUFFER;
             if( DD_OK != IDirectDrawSurface3_GetAttachedSurface(
                                                 p_surface, &dds_caps,
@@ -1016,7 +998,21 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
             }
 
 
-            p_vout->p_sys->p_current_surface= p_pic[0].p_sys->p_front_surface;
+            p_vout->p_sys->p_current_surface = front_pic.p_sys->p_surface =
+                p_pic[0].p_sys->p_front_surface;
+
+            /* reset the front buffer memory */
+            if( DirectXGetSurfaceDesc( &front_pic ) &&
+                UpdatePictureStruct( p_vout, &front_pic,
+                                     p_vout->output.i_chroma ) )
+            {
+                int j;
+                for( j = 0; j < front_pic.i_planes; j++ )
+                    memset( front_pic.p[j].p_pixels, 127,
+                            front_pic.p[j].i_lines * front_pic.p[j].i_pitch
+                            * front_pic.p[j].i_pixel_bytes );
+            }
+
             DirectXUpdateOverlay( p_vout );
             I_OUTPUTPICTURES = 1;
         }
@@ -1028,17 +1024,14 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
      * surface (display) so they can be displayed */
     if( !p_vout->p_sys->b_using_overlay )
     {
-        /* FixMe */
-        p_vout->output.i_chroma = FOURCC_RV16;
-        p_vout->output.i_rmask  = 0x001f;
-        p_vout->output.i_gmask  = 0x03e0;
-        p_vout->output.i_bmask  = 0x7c00;
+        DDPIXELFORMAT ddpfPixelFormat;
 
         for( i = 0; i < i_num_pics; i++ )
         {
             if( DirectXCreateSurface( p_vout, &p_surface,
                                       p_vout->output.i_chroma,
-                                      p_vout->p_sys->b_using_overlay ) )
+                                      p_vout->p_sys->b_using_overlay,
+                                      0 /* no back buffers */ ) )
             {
                 /* Allocate internal structure */
                 p_pic[i].p_sys = malloc( sizeof( picture_sys_t ) );
@@ -1056,6 +1049,32 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
             }
             else break;
         }
+
+        /* 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 );
+        switch( ddpfPixelFormat.dwRGBBitCount )
+        {
+            case 8: /* FIXME: set the palette */
+                p_vout->output.i_chroma = FOURCC_RGB2; break;
+            case 15:
+                p_vout->output.i_chroma = FOURCC_RV15; break;
+            case 16:
+                p_vout->output.i_chroma = FOURCC_RV16; break;
+            case 24:
+                p_vout->output.i_chroma = FOURCC_RV24; break;
+            case 32:
+                p_vout->output.i_chroma = FOURCC_RV32; break;
+            default:
+                intf_ErrMsg( "vout error: unknown screen depth" );
+                return( 0 );
+        }
+        p_vout->output.i_rmask = ddpfPixelFormat.dwRBitMask;
+        p_vout->output.i_gmask = ddpfPixelFormat.dwGBitMask;
+        p_vout->output.i_bmask = ddpfPixelFormat.dwBBitMask;
+
     }
 
 
@@ -1131,6 +1150,34 @@ static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,
     switch( p_vout->output.i_chroma )
     {
 
+        case FOURCC_RGB2:
+        case FOURCC_RV15:
+        case FOURCC_RV16:
+        case FOURCC_RV24:
+        case FOURCC_RV32:
+            p_pic->p->p_pixels = p_pic->p_sys->ddsd.lpSurface;
+            p_pic->p->i_lines = p_vout->output.i_height;
+            p_pic->p->i_pitch = p_pic->p_sys->ddsd.lPitch;
+            p_pic->p->b_margin = 0;
+            p_pic->i_planes = 1;
+            switch( p_vout->output.i_chroma )
+            {
+                case FOURCC_RGB2:
+                    p_pic->p->i_pixel_bytes = 1;
+                    break;
+                case FOURCC_RV15:
+                case FOURCC_RV16:
+                    p_pic->p->i_pixel_bytes = 2;
+                    break;
+                case FOURCC_RV24:
+                case FOURCC_RV32:
+                    p_pic->p->i_pixel_bytes = 4;
+                    break;
+                default:
+                    return( -1 );
+            }
+            break;
+
         case FOURCC_YV12:
 
             p_pic->Y_PIXELS = p_pic->p_sys->ddsd.lpSurface;
@@ -1156,81 +1203,6 @@ static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,
             p_pic->i_planes = 3;
             break;
 
-        case FOURCC_RV16:
-
-            p_pic->p->p_pixels = p_pic->p_sys->ddsd.lpSurface;
-            p_pic->p->i_lines = p_vout->output.i_height;
-            p_pic->p->i_pitch = p_pic->p_sys->ddsd.lPitch;
-            p_pic->p->i_pixel_bytes = 2;
-            p_pic->p->b_margin = 0;
-
-            p_pic->i_planes = 1;
-            break;
-
-        case FOURCC_RV15:
-
-            p_pic->p->p_pixels = p_pic->p_sys->ddsd.lpSurface;
-            p_pic->p->i_lines = p_vout->output.i_height;
-            p_pic->p->i_pitch = p_pic->p_sys->ddsd.lPitch;
-            p_pic->p->i_pixel_bytes = 2;
-            p_pic->p->b_margin = 0;
-
-            p_pic->i_planes = 1;
-            break;
-
-        case FOURCC_I420:
-
-            p_pic->Y_PIXELS = p_pic->p_sys->ddsd.lpSurface;
-            p_pic->p[Y_PLANE].i_lines = p_vout->output.i_height;
-            p_pic->p[Y_PLANE].i_pitch = p_pic->p_sys->ddsd.lPitch;
-            p_pic->p[Y_PLANE].i_pixel_bytes = 1;
-            p_pic->p[Y_PLANE].b_margin = 0;
-
-            p_pic->U_PIXELS = p_pic->Y_PIXELS
-              + p_pic->p[Y_PLANE].i_lines * p_pic->p[Y_PLANE].i_pitch;
-            p_pic->p[U_PLANE].i_lines = p_vout->output.i_height / 2;
-            p_pic->p[U_PLANE].i_pitch = p_pic->p[Y_PLANE].i_pitch / 2;
-            p_pic->p[U_PLANE].i_pixel_bytes = 1;
-            p_pic->p[U_PLANE].b_margin = 0;
-
-            p_pic->V_PIXELS = p_pic->U_PIXELS
-              + p_pic->p[U_PLANE].i_lines * p_pic->p[U_PLANE].i_pitch;
-            p_pic->p[V_PLANE].i_lines = p_vout->output.i_height / 2;
-            p_pic->p[V_PLANE].i_pitch = p_pic->p[Y_PLANE].i_pitch / 2;
-            p_pic->p[V_PLANE].i_pixel_bytes = 1;
-            p_pic->p[V_PLANE].b_margin = 0;
-
-            p_pic->i_planes = 3;
-            break;
-
-#if 0
-        case FOURCC_Y211:
-
-            p_pic->p->p_pixels = p_pic->p_sys->p_image->data
-                                  + p_pic->p_sys->p_image->offsets[0];
-            p_pic->p->i_lines = p_vout->output.i_height;
-            /* XXX: this just looks so plain wrong... check it out ! */
-            p_pic->p->i_pitch = p_pic->p_sys->p_image->pitches[0] / 4;
-            p_pic->p->i_pixel_bytes = 4;
-            p_pic->p->b_margin = 0;
-
-            p_pic->i_planes = 1;
-            break;
-
-        case FOURCC_YUY2:
-        case FOURCC_UYVY:
-
-            p_pic->p->p_pixels = p_pic->p_sys->p_image->data
-                                  + p_pic->p_sys->p_image->offsets[0];
-            p_pic->p->i_lines = p_vout->output.i_height;
-            p_pic->p->i_pitch = p_pic->p_sys->p_image->pitches[0];
-            p_pic->p->i_pixel_bytes = 4;
-            p_pic->p->b_margin = 0;
-
-            p_pic->i_planes = 1;
-            break;
-#endif
-
         default:
             /* Not supported */
             return 0;
@@ -1302,14 +1274,14 @@ static void DirectXGetDDrawCaps( vout_thread_t *p_vout )
  *****************************************************************************/
 static int DirectXGetSurfaceDesc( picture_t *p_pic )
 {
-    HRESULT         dxresult;
+    HRESULT dxresult;
 
     /* Lock the surface to get a valid pointer to the picture buffer */
     memset( &p_pic->p_sys->ddsd, 0, sizeof( DDSURFACEDESC ));
     p_pic->p_sys->ddsd.dwSize = sizeof(DDSURFACEDESC);
     dxresult = IDirectDrawSurface3_Lock( p_pic->p_sys->p_surface,
                                          NULL, &p_pic->p_sys->ddsd,
-                                         DDLOCK_NOSYSLOCK,
+                                         DDLOCK_NOSYSLOCK | DDLOCK_WAIT,
                                          NULL );
     if ( dxresult == DDERR_SURFACELOST )
     {
index abe7ba97e345626212f99969e03a42427119d2a7..fc58806d18b49ae86872e13f9e7bdad2dbee96b7 100644 (file)
@@ -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.4 2002/04/02 06:31:23 gbazin Exp $
+ * $Id: vout_directx.h,v 1.5 2002/04/23 22:07:05 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -62,12 +62,11 @@ typedef struct vout_sys_s
     int          i_rgb_colorkey;      /* colorkey in RGB used by the overlay */
     int          i_colorkey;                 /* colorkey used by the overlay */
  
-    boolean_t    b_cursor;
+    volatile u16 i_changes;             /* changes made to the video display */
 
-    u16          i_changes;             /* changes made to the video display */
-
-    boolean_t    b_cursor_autohidden;
-    mtime_t      i_lastmoved;
+    /* Mouse */
+    volatile boolean_t b_cursor_hidden;
+    volatile mtime_t   i_lastmoved;
 
     vlc_thread_t event_thread_id;                            /* event thread */
     vlc_mutex_t  event_thread_lock;             /* lock for the event thread */
@@ -101,3 +100,8 @@ typedef struct picture_sys_s
  *****************************************************************************/
 void DirectXEventThread ( vout_thread_t *p_vout );
 void DirectXUpdateOverlay( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * Constants
+ *****************************************************************************/
+#define WM_VLC_HIDE_MOUSE WM_APP
index 0b13b0985a26194578e3fea194b9b0f7e43401b3..06a642d17677392ed8d26997bbd752ef7ba9d34a 100644 (file)
@@ -2,7 +2,7 @@
  * vout_events.c: Windows DirectX video output events handler
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: vout_events.c,v 1.13 2002/04/02 06:31:23 gbazin Exp $
+ * $Id: vout_events.c,v 1.14 2002/04/23 22:07:05 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -66,7 +66,8 @@ static long FAR PASCAL DirectXEventProc ( HWND hwnd, UINT message,
  *****************************************************************************/
 void DirectXEventThread( vout_thread_t *p_vout )
 {
-    MSG             msg;
+    MSG msg;
+    POINT old_mouse_pos;
 
     /* Initialisation */
 
@@ -99,28 +100,39 @@ void DirectXEventThread( vout_thread_t *p_vout )
         switch( msg.message )
         {
 
+        case WM_NCMOUSEMOVE:
         case WM_MOUSEMOVE:
-            if( p_vout->p_sys->b_cursor )
+            if( (abs(GET_X_LPARAM(msg.lParam) - old_mouse_pos.x) > 2 ||
+                (abs(GET_Y_LPARAM(msg.lParam) - old_mouse_pos.y)) > 2 ) )
             {
-                if( p_vout->p_sys->b_cursor_autohidden )
+                GetCursorPos( &old_mouse_pos );
+                p_vout->p_sys->i_lastmoved = mdate();
+
+                if( p_vout->p_sys->b_cursor_hidden )
                 {
-                    p_vout->p_sys->b_cursor_autohidden = 0;
-                    p_vout->p_sys->i_lastmoved = mdate();
+                    p_vout->p_sys->b_cursor_hidden = 0;
                     ShowCursor( TRUE );
                 }
-                else
-                {
-                    p_vout->p_sys->i_lastmoved = mdate();
-                }
             }
-            DispatchMessage(&msg);
+            break;
+
+        case WM_VLC_HIDE_MOUSE:
+            GetCursorPos( &old_mouse_pos );
+            ShowCursor( FALSE );
             break;
 
         case WM_RBUTTONUP:
-            intf_WarnMsg( 4, "vout: vout_Manage WM_RBUTTONUP" );
             p_main->p_intf->b_menu_change = 1;
             break;
 
+        case WM_LBUTTONDOWN:
+            p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
+            break;
+
+        case WM_LBUTTONDBLCLK:
+            p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
+            break;
+
         case WM_KEYDOWN:
             /* the key events are first processed here. The next
              * message processed by this main message loop will be the
@@ -138,7 +150,6 @@ void DirectXEventThread( vout_thread_t *p_vout )
             break;
 
         case WM_CHAR:
-            intf_WarnMsg( 3, "vout: vout_Manage WM_CHAR" );
             switch( msg.wParam )
             {
             case 'q':
@@ -193,10 +204,6 @@ void DirectXEventThread( vout_thread_t *p_vout )
         default:
             /* Messages we don't handle directly are dispatched to the
              * window procedure */
-#if 0
-            intf_WarnMsg( 5, "vout: vout_Manage unhandled message",
-                          msg.message );
-#endif
             TranslateMessage(&msg);
             DispatchMessage(&msg);
             break;
@@ -291,7 +298,7 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
 
     /* fill in the window class structure */
     wc.cbSize        = sizeof(WNDCLASSEX);
-    wc.style         = 0;                               /* no special styles */
+    wc.style         = CS_DBLCLKS;                       /* style: dbl click */
     wc.lpfnWndProc   = (WNDPROC)DirectXEventProc;           /* event handler */
     wc.cbClsExtra    = 0;                             /* no extra class data */
     wc.cbWndExtra    = 0;                            /* no extra window data */
@@ -499,12 +506,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
         GetClientRect( hwnd, &rect_window );
         p_vout->p_sys->i_window_width = rect_window.right;
         p_vout->p_sys->i_window_height = rect_window.bottom;
-#if 0
-        intf_WarnMsg( 3, "vout: WinProc WM_WINDOWPOSCHANGED %i,%i,%i,%i",
-                      p_vout->p_sys->i_window_x, p_vout->p_sys->i_window_y,
-                      p_vout->p_sys->i_window_width,
-                      p_vout->p_sys->i_window_height );
-#endif
 
         DirectXUpdateRects( p_vout );
         if( p_vout->p_sys->b_using_overlay &&
@@ -518,14 +519,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
         }
         break;
 
-    case WM_ACTIVATE:
-        intf_WarnMsg( 4, "vout: WinProc WM_ACTIVATE" );
-        break;
-
-    case WM_CREATE:
-        intf_WarnMsg( 4, "vout: WinProc WM_CREATE" );
-        break;
-
     /* the user wants to close the window */
     case WM_CLOSE:
         intf_WarnMsg( 4, "vout: WinProc WM_CLOSE" );
@@ -552,12 +545,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
         }
         break;
 
-#if 0
-    case WM_PAINT:
-        intf_WarnMsg( 4, "vout: WinProc WM_PAINT" );
-        break;
-#endif
-
     case WM_ERASEBKGND:
         p_vout = (vout_thread_t *)GetWindowLong( hwnd, GWL_USERDATA );
         if( !p_vout->p_sys->b_using_overlay )
@@ -580,11 +567,9 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
         }
         break;
 
-#if 0
     default:
-        intf_WarnMsg( 4, "vout: WinProc WM Default %i", message );
+        //intf_WarnMsg( 4, "vout: WinProc WM Default %i", message );
         break;
-#endif
     }
 
     return DefWindowProc(hwnd, message, wParam, lParam);
index 8ec9c1956d391c78a1993a6d5eb667bf7859bb08..b0c0a7838de4bcd99d53bcdae2e45318f4326251 100644 (file)
@@ -2,7 +2,7 @@
  * spu_decoder.c : spu decoder thread
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: spu_decoder.c,v 1.16 2002/04/23 20:58:23 sam Exp $
+ * $Id: spu_decoder.c,v 1.17 2002/04/23 22:07:05 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -832,13 +832,13 @@ static void RenderSPU( const vout_thread_t *p_vout, picture_t *p_pic,
     case FOURCC_IYUV:
     case FOURCC_YV12:
 
-    p_dest = p_pic->p->p_pixels + p_spu->i_x + p_spu->i_width
-              + p_vout->output.i_width * ( p_spu->i_y + p_spu->i_height );
+    p_dest = p_pic->Y_PIXELS + p_spu->i_x + p_spu->i_width
+              + p_pic->Y_PITCH * ( p_spu->i_y + p_spu->i_height );
 
     /* Draw until we reach the bottom of the subtitle */
-    for( i_y = p_spu->i_height * p_vout->output.i_width ;
+    for( i_y = p_spu->i_height * p_pic->Y_PITCH ;
          i_y ;
-         i_y -= p_vout->output.i_width )
+         i_y -= p_pic->Y_PITCH )
     {
         /* Draw until we reach the end of the line */
         for( i_x = p_spu->i_width ; i_x ; )