Commit 69c174d7 authored by Gildas Bazin's avatar Gildas Bazin

* DirectX video output plugin now uses triple buffering for YUV overlay. This
  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).
parent 4b22a291
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vout_directx.c: Windows DirectX video output display method * vout_directx.c: Windows DirectX video output display method
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -30,13 +30,8 @@ ...@@ -30,13 +30,8 @@
* *
* If YUV overlay is not supported this plugin will use RGB offscreen video * If YUV overlay is not supported this plugin will use RGB offscreen video
* surfaces that will be blitted onto the primary surface (display) to * surfaces that will be blitted onto the primary surface (display) to
* effectively display the pictures. this fallback method enables us to display * effectively display the pictures. This fallback method also enables us to
* video in window mode. * 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.
* *
*****************************************************************************/ *****************************************************************************/
#include <errno.h> /* ENOMEM */ #include <errno.h> /* ENOMEM */
...@@ -85,7 +80,7 @@ static void DirectXCloseDDraw ( vout_thread_t *p_vout ); ...@@ -85,7 +80,7 @@ static void DirectXCloseDDraw ( vout_thread_t *p_vout );
static int DirectXCreateDisplay ( vout_thread_t *p_vout ); static int DirectXCreateDisplay ( vout_thread_t *p_vout );
static void DirectXCloseDisplay ( vout_thread_t *p_vout ); static void DirectXCloseDisplay ( vout_thread_t *p_vout );
static int DirectXCreateSurface ( 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, static void DirectXCloseSurface ( vout_thread_t *p_vout,
LPDIRECTDRAWSURFACE3 ); LPDIRECTDRAWSURFACE3 );
static int DirectXCreateClipper ( vout_thread_t *p_vout ); static int DirectXCreateClipper ( vout_thread_t *p_vout );
...@@ -135,9 +130,7 @@ static int vout_Create( 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 ); SetRectEmpty( &p_vout->p_sys->rect_display );
p_vout->p_sys->b_using_overlay = !config_GetIntVariable( "nooverlay" ); p_vout->p_sys->b_using_overlay = !config_GetIntVariable( "nooverlay" );
p_vout->p_sys->b_cursor = 1; p_vout->p_sys->b_cursor_hidden = 0;
p_vout->p_sys->b_cursor_autohidden = 0;
p_vout->p_sys->i_lastmoved = mdate(); p_vout->p_sys->i_lastmoved = mdate();
/* Set main window's size */ /* Set main window's size */
...@@ -194,7 +187,7 @@ static int vout_Create( vout_thread_t *p_vout ) ...@@ -194,7 +187,7 @@ static int vout_Create( vout_thread_t *p_vout )
p_vout->p_sys->b_event_thread_die = 1; p_vout->p_sys->b_event_thread_die = 1;
/* we need to be sure DirectXEventThread won't stay stuck in /* we need to be sure DirectXEventThread won't stay stuck in
* GetMessage, so we send a fake message */ * 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 ); vlc_thread_join( p_vout->p_sys->event_thread_id );
return ( 1 ); return ( 1 );
...@@ -210,19 +203,12 @@ static int vout_Create( vout_thread_t *p_vout ) ...@@ -210,19 +203,12 @@ static int vout_Create( vout_thread_t *p_vout )
p_vout->p_sys->b_event_thread_die = 1; p_vout->p_sys->b_event_thread_die = 1;
/* we need to be sure DirectXEventThread won't stay stuck in /* we need to be sure DirectXEventThread won't stay stuck in
* GetMessage, so we send a fake message */ * 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 ); vlc_thread_join( p_vout->p_sys->event_thread_id );
return ( 1 ); 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 ); return( 0 );
} }
...@@ -284,7 +270,7 @@ static void vout_Destroy( vout_thread_t *p_vout ) ...@@ -284,7 +270,7 @@ static void vout_Destroy( vout_thread_t *p_vout )
if( p_vout->p_sys->i_event_thread_status == THREAD_READY && if( p_vout->p_sys->i_event_thread_status == THREAD_READY &&
p_vout->p_sys->hwnd ) 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 ); vlc_thread_join( p_vout->p_sys->event_thread_id );
} }
...@@ -377,28 +363,14 @@ static int vout_Manage( vout_thread_t *p_vout ) ...@@ -377,28 +363,14 @@ static int vout_Manage( vout_thread_t *p_vout )
/* /*
* Pointer change * Pointer change
*/ */
if( ! p_vout->p_sys->b_cursor_autohidden && if( (!p_vout->p_sys->b_cursor_hidden) &&
( mdate() - p_vout->p_sys->i_lastmoved > 5000000 ) ) ( (mdate() - p_vout->p_sys->i_lastmoved) > 5000000 ) )
{ {
/* Hide the mouse automatically */ /* Hide the mouse automatically */
p_vout->p_sys->b_cursor_autohidden = 1; p_vout->p_sys->b_cursor_hidden = 1;
ShowCursor( FALSE ); 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 */ /* Check if the event thread is still running */
if( p_vout->p_sys->b_event_thread_die ) if( p_vout->p_sys->b_event_thread_die )
return 1; /* exit */ return 1; /* exit */
...@@ -469,8 +441,10 @@ static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -469,8 +441,10 @@ static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
else /* using overlay */ else /* using overlay */
{ {
#if 0 /* Flip the overlay buffers if we are using back buffers */
/* Flip the overlay 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, dxresult = IDirectDrawSurface3_Flip( p_pic->p_sys->p_front_surface,
NULL, DDFLIP_WAIT ); NULL, DDFLIP_WAIT );
if ( dxresult == DDERR_SURFACELOST ) if ( dxresult == DDERR_SURFACELOST )
...@@ -488,7 +462,6 @@ static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -488,7 +462,6 @@ static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
if( dxresult != DD_OK ) if( dxresult != DD_OK )
intf_WarnMsg( 8, "vout: couldn't flip overlay surface" ); intf_WarnMsg( 8, "vout: couldn't flip overlay surface" );
#endif
if( !DirectXGetSurfaceDesc( p_pic ) ) if( !DirectXGetSurfaceDesc( p_pic ) )
{ {
...@@ -727,7 +700,8 @@ static int DirectXCreateClipper( vout_thread_t *p_vout ) ...@@ -727,7 +700,8 @@ static int DirectXCreateClipper( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static int DirectXCreateSurface( vout_thread_t *p_vout, static int DirectXCreateSurface( vout_thread_t *p_vout,
LPDIRECTDRAWSURFACE3 *pp_surface_final, LPDIRECTDRAWSURFACE3 *pp_surface_final,
int i_chroma, int b_overlay ) int i_chroma, int b_overlay,
int i_backbuffers )
{ {
HRESULT dxresult; HRESULT dxresult;
LPDIRECTDRAWSURFACE p_surface; LPDIRECTDRAWSURFACE p_surface;
...@@ -754,15 +728,15 @@ static int DirectXCreateSurface( vout_thread_t *p_vout, ...@@ -754,15 +728,15 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
ddsd.dwFlags = DDSD_CAPS | ddsd.dwFlags = DDSD_CAPS |
DDSD_HEIGHT | DDSD_HEIGHT |
DDSD_WIDTH | DDSD_WIDTH |
//DDSD_BACKBUFFERCOUNT |
DDSD_PIXELFORMAT; DDSD_PIXELFORMAT;
ddsd.dwFlags |= (i_backbuffers ? DDSD_BACKBUFFERCOUNT : 0);
ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY |
//DDSCAPS_COMPLEX |
//DDSCAPS_FLIP |
DDSCAPS_VIDEOMEMORY; DDSCAPS_VIDEOMEMORY;
ddsd.ddsCaps.dwCaps |= (i_backbuffers ? DDSCAPS_COMPLEX | DDSCAPS_FLIP
: 0 );
ddsd.dwHeight = p_vout->render.i_height; ddsd.dwHeight = p_vout->render.i_height;
ddsd.dwWidth = p_vout->render.i_width; 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, dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,
&ddsd, &ddsd,
...@@ -942,54 +916,62 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -942,54 +916,62 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
int i; int i;
LPDIRECTDRAWSURFACE3 p_surface; 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" ); intf_WarnMsg( 3, "vout: NewPictureVec" );
I_OUTPUTPICTURES = 0; I_OUTPUTPICTURES = 0;
/* chroma asked for */ /* Choose the chroma we will try first. */
p_vout->output.i_chroma = p_vout->render.i_chroma; switch( p_vout->render.i_chroma )
{
/* hack */ case FOURCC_YUY2:
#if 1 case FOURCC_YUNV:
if( p_vout->render.i_chroma == FOURCC_I420 ) p_vout->output.i_chroma = FOURCC_YUY2;
p_vout->output.i_chroma = FOURCC_YV12; break;
#endif 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. /* First we try to use an YUV overlay surface.
* It looks like with most hardware it's not possible to create several * The overlay surface that we create won't be used to decode directly
* overlay surfaces, and even if it was I bet it would be slower anyway to * into it because accessing video memory directly is way to slow (remember
* use them as direct buffers because they usually reside in video memory * that pictures are decoded macroblock per macroblock). Instead the video
* which is quite slow. * will be decoded in picture buffers in system memory which will then be
* So the overlay surface (with a back-buffer) that we create won't be used * memcpy() to the overlay surface. */
* to decode directly into it but instead picture buffers in system memory
* will be blitted to it. */
if( p_vout->p_sys->b_using_overlay ) if( p_vout->p_sys->b_using_overlay )
{ {
if( DirectXCreateSurface( p_vout, &p_surface, p_vout->output.i_chroma, boolean_t b_result_ok;
p_vout->p_sys->b_using_overlay ) )
/* 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; DDSCAPS dds_caps;
picture_t front_pic;
picture_sys_t front_pic_sys;
front_pic.p_sys = &front_pic_sys;
/* Allocate internal structure */ /* Allocate internal structure */
p_pic[0].p_sys = malloc( sizeof( picture_sys_t ) ); 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, ...@@ -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; p_pic[0].p_sys->p_front_surface = p_surface;
/* Get the back buffer */ /* Get the back buffer */
memset( &dds_caps, 0, sizeof( DDSCAPS )); memset( &dds_caps, 0, sizeof( DDSCAPS ) );
dds_caps.dwCaps = DDSCAPS_BACKBUFFER; dds_caps.dwCaps = DDSCAPS_BACKBUFFER;
if( DD_OK != IDirectDrawSurface3_GetAttachedSurface( if( DD_OK != IDirectDrawSurface3_GetAttachedSurface(
p_surface, &dds_caps, p_surface, &dds_caps,
...@@ -1016,7 +998,21 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -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 ); DirectXUpdateOverlay( p_vout );
I_OUTPUTPICTURES = 1; I_OUTPUTPICTURES = 1;
} }
...@@ -1028,17 +1024,14 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1028,17 +1024,14 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
* surface (display) so they can be displayed */ * surface (display) so they can be displayed */
if( !p_vout->p_sys->b_using_overlay ) if( !p_vout->p_sys->b_using_overlay )
{ {
/* FixMe */ DDPIXELFORMAT ddpfPixelFormat;
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;
for( i = 0; i < i_num_pics; i++ ) for( i = 0; i < i_num_pics; i++ )
{ {
if( DirectXCreateSurface( p_vout, &p_surface, if( DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma, 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 */ /* Allocate internal structure */
p_pic[i].p_sys = malloc( sizeof( picture_sys_t ) ); 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, ...@@ -1056,6 +1049,32 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
} }
else break; 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, ...@@ -1131,6 +1150,34 @@ static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,
switch( p_vout->output.i_chroma ) 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: case FOURCC_YV12:
p_pic->Y_PIXELS = p_pic->p_sys->ddsd.lpSurface; 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, ...@@ -1156,81 +1203,6 @@ static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,
p_pic->i_planes = 3; p_pic->i_planes = 3;
break; 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: default:
/* Not supported */ /* Not supported */
return 0; return 0;
...@@ -1302,14 +1274,14 @@ static void DirectXGetDDrawCaps( vout_thread_t *p_vout ) ...@@ -1302,14 +1274,14 @@ static void DirectXGetDDrawCaps( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static int DirectXGetSurfaceDesc( picture_t *p_pic ) static int DirectXGetSurfaceDesc( picture_t *p_pic )
{ {
HRESULT dxresult; HRESULT dxresult;
/* Lock the surface to get a valid pointer to the picture buffer */ /* Lock the surface to get a valid pointer to the picture buffer */
memset( &p_pic->p_sys->ddsd, 0, sizeof( DDSURFACEDESC )); memset( &p_pic->p_sys->ddsd, 0, sizeof( DDSURFACEDESC ));
p_pic->p_sys->ddsd.dwSize = sizeof(DDSURFACEDESC); p_pic->p_sys->ddsd.dwSize = sizeof(DDSURFACEDESC);
dxresult = IDirectDrawSurface3_Lock( p_pic->p_sys->p_surface, dxresult = IDirectDrawSurface3_Lock( p_pic->p_sys->p_surface,
NULL, &p_pic->p_sys->ddsd, NULL, &p_pic->p_sys->ddsd,
DDLOCK_NOSYSLOCK, DDLOCK_NOSYSLOCK | DDLOCK_WAIT,
NULL ); NULL );
if ( dxresult == DDERR_SURFACELOST ) if ( dxresult == DDERR_SURFACELOST )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vout_directx.h: Windows DirectX video output header file * vout_directx.h: Windows DirectX video output header file
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * 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> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -62,12 +62,11 @@ typedef struct vout_sys_s ...@@ -62,12 +62,11 @@ typedef struct vout_sys_s
int i_rgb_colorkey; /* colorkey in RGB used by the overlay */ int i_rgb_colorkey; /* colorkey in RGB used by the overlay */
int i_colorkey; /* colorkey 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 */ /* Mouse */
volatile boolean_t b_cursor_hidden;
boolean_t b_cursor_autohidden; volatile mtime_t i_lastmoved;
mtime_t i_lastmoved;
vlc_thread_t event_thread_id; /* event thread */ vlc_thread_t event_thread_id; /* event thread */
vlc_mutex_t event_thread_lock; /* lock for the event thread */ vlc_mutex_t event_thread_lock; /* lock for the event thread */
...@@ -101,3 +100,8 @@ typedef struct picture_sys_s ...@@ -101,3 +100,8 @@ typedef struct picture_sys_s
*****************************************************************************/ *****************************************************************************/
void DirectXEventThread ( vout_thread_t *p_vout ); void DirectXEventThread ( vout_thread_t *p_vout );
void DirectXUpdateOverlay( vout_thread_t *p_vout ); void DirectXUpdateOverlay( vout_thread_t *p_vout );
/*****************************************************************************
* Constants
*****************************************************************************/
#define WM_VLC_HIDE_MOUSE WM_APP
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vout_events.c: Windows DirectX video output events handler * vout_events.c: Windows DirectX video output events handler
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -66,7 +66,8 @@ static long FAR PASCAL DirectXEventProc ( HWND hwnd, UINT message, ...@@ -66,7 +66,8 @@ static long FAR PASCAL DirectXEventProc ( HWND hwnd, UINT message,
*****************************************************************************/ *****************************************************************************/
void DirectXEventThread( vout_thread_t *p_vout ) void DirectXEventThread( vout_thread_t *p_vout )
{ {
MSG msg; MSG msg;
POINT old_mouse_pos;
/* Initialisation */ /* Initialisation */
...@@ -99,28 +100,39 @@ void DirectXEventThread( vout_thread_t *p_vout ) ...@@ -99,28 +100,39 @@ void DirectXEventThread( vout_thread_t *p_vout )
switch( msg.message ) switch( msg.message )
{ {
case WM_NCMOUSEMOVE:
case WM_MOUSEMOVE: 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->b_cursor_hidden = 0;
p_vout->p_sys->i_lastmoved = mdate();
ShowCursor( TRUE ); 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; break;
case WM_RBUTTONUP: case WM_RBUTTONUP:
intf_WarnMsg( 4, "vout: vout_Manage WM_RBUTTONUP" );
p_main->p_intf->b_menu_change = 1; p_main->p_intf->b_menu_change = 1;
break; 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: case WM_KEYDOWN:
/* the key events are first processed here. The next /* the key events are first processed here. The next
* message processed by this main message loop will be the * message processed by this main message loop will be the
...@@ -138,7 +150,6 @@ void DirectXEventThread( vout_thread_t *p_vout ) ...@@ -138,7 +150,6 @@ void DirectXEventThread( vout_thread_t *p_vout )
break; break;
case WM_CHAR: case WM_CHAR:
intf_WarnMsg( 3, "vout: vout_Manage WM_CHAR" );
switch( msg.wParam ) switch( msg.wParam )
{ {
case 'q': case 'q':
...@@ -193,10 +204,6 @@ void DirectXEventThread( vout_thread_t *p_vout ) ...@@ -193,10 +204,6 @@ void DirectXEventThread( vout_thread_t *p_vout )
default: default:
/* Messages we don't handle directly are dispatched to the /* Messages we don't handle directly are dispatched to the
* window procedure */ * window procedure */
#if 0
intf_WarnMsg( 5, "vout: vout_Manage unhandled message",
msg.message );
#endif
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
break; break;
...@@ -291,7 +298,7 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -291,7 +298,7 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
/* fill in the window class structure */ /* fill in the window class structure */
wc.cbSize = sizeof(WNDCLASSEX); wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0; /* no special styles */ wc.style = CS_DBLCLKS; /* style: dbl click */
wc.lpfnWndProc = (WNDPROC)DirectXEventProc; /* event handler */ wc.lpfnWndProc = (WNDPROC)DirectXEventProc; /* event handler */
wc.cbClsExtra = 0; /* no extra class data */ wc.cbClsExtra = 0; /* no extra class data */
wc.cbWndExtra = 0; /* no extra window data */ wc.cbWndExtra = 0; /* no extra window data */
...@@ -499,12 +506,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message, ...@@ -499,12 +506,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
GetClientRect( hwnd, &rect_window ); GetClientRect( hwnd, &rect_window );
p_vout->p_sys->i_window_width = rect_window.right; p_vout->p_sys->i_window_width = rect_window.right;
p_vout->p_sys->i_window_height = rect_window.bottom; 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 ); DirectXUpdateRects( p_vout );
if( p_vout->p_sys->b_using_overlay && if( p_vout->p_sys->b_using_overlay &&
...@@ -518,14 +519,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message, ...@@ -518,14 +519,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
} }
break; 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 */ /* the user wants to close the window */
case WM_CLOSE: case WM_CLOSE:
intf_WarnMsg( 4, "vout: WinProc WM_CLOSE" ); intf_WarnMsg( 4, "vout: WinProc WM_CLOSE" );
...@@ -552,12 +545,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message, ...@@ -552,12 +545,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
} }
break; break;
#if 0
case WM_PAINT:
intf_WarnMsg( 4, "vout: WinProc WM_PAINT" );
break;
#endif
case WM_ERASEBKGND: case WM_ERASEBKGND:
p_vout = (vout_thread_t *)GetWindowLong( hwnd, GWL_USERDATA ); p_vout = (vout_thread_t *)GetWindowLong( hwnd, GWL_USERDATA );
if( !p_vout->p_sys->b_using_overlay ) if( !p_vout->p_sys->b_using_overlay )
...@@ -580,11 +567,9 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message, ...@@ -580,11 +567,9 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
} }
break; break;
#if 0
default: default:
intf_WarnMsg( 4, "vout: WinProc WM Default %i", message ); //intf_WarnMsg( 4, "vout: WinProc WM Default %i", message );
break; break;
#endif
} }
return DefWindowProc(hwnd, message, wParam, lParam); return DefWindowProc(hwnd, message, wParam, lParam);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* spu_decoder.c : spu decoder thread * spu_decoder.c : spu decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -832,13 +832,13 @@ static void RenderSPU( const vout_thread_t *p_vout, picture_t *p_pic, ...@@ -832,13 +832,13 @@ static void RenderSPU( const vout_thread_t *p_vout, picture_t *p_pic,
case FOURCC_IYUV: case FOURCC_IYUV:
case FOURCC_YV12: case FOURCC_YV12:
p_dest = p_pic->p->p_pixels + p_spu->i_x + p_spu->i_width p_dest = p_pic->Y_PIXELS + p_spu->i_x + p_spu->i_width
+ p_vout->output.i_width * ( p_spu->i_y + p_spu->i_height ); + p_pic->Y_PITCH * ( p_spu->i_y + p_spu->i_height );
/* Draw until we reach the bottom of the subtitle */ /* 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 ;
i_y -= p_vout->output.i_width ) i_y -= p_pic->Y_PITCH )
{ {
/* Draw until we reach the end of the line */ /* Draw until we reach the end of the line */
for( i_x = p_spu->i_width ; i_x ; ) for( i_x = p_spu->i_width ; i_x ; )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment