summaryrefslogtreecommitdiff
path: root/src/video_out/video_out_directx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_out/video_out_directx.c')
-rw-r--r--src/video_out/video_out_directx.c115
1 files changed, 78 insertions, 37 deletions
diff --git a/src/video_out/video_out_directx.c b/src/video_out/video_out_directx.c
index f1136eab0..dda8664ee 100644
--- a/src/video_out/video_out_directx.c
+++ b/src/video_out/video_out_directx.c
@@ -117,7 +117,8 @@ typedef struct {
yuv2rgb_t *yuv2rgb; /* used for format conversion */
int mode; /* rgb mode */
int bytespp; /* rgb bits per pixel */
-
+ DDPIXELFORMAT primary_pixel_format;
+ DDSURFACEDESC ddsd; /* set by Lock(), used during display_frame */
alphablend_t alphablend_extra_data;
} win32_driver_t;
@@ -367,8 +368,9 @@ static boolean CreateSecondary( win32_driver_t * win32_driver, int width, int he
lprintf("CreateSecondary() - Falling back to back buffer same as primary\n");
lprintf("CreateSecondary() - act_format = (NATIVE) %d\n", IMGFMT_NATIVE);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
+ ddsd.ddpfPixelFormat = win32_driver->primary_pixel_format;
win32_driver->act_format = IMGFMT_NATIVE;
if( IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->secondary, 0 ) == DD_OK )
@@ -429,6 +431,10 @@ static boolean CheckPixelFormat( win32_driver_t * win32_driver )
Error( 0, "IDirectDrawSurface_GetPixelFormat ( CheckPixelFormat ) : error 0x%lx", result );
return 0;
}
+
+ /* store pixel format for CreateSecondary */
+
+ win32_driver->primary_pixel_format = ddpf;
/* TODO : support paletized video modes */
@@ -478,6 +484,7 @@ static boolean CheckPixelFormat( win32_driver_t * win32_driver )
win32_driver->mode = MODE_15_BGR;
}
+ lprintf("win32 mode: %u\n", win32_driver->mode);
return TRUE;
}
@@ -755,23 +762,22 @@ static boolean DisplayFrame( win32_driver_t * win32_driver )
/* Lock our back buffer to update its contents. */
-static void * Lock( void * surface )
+static void * Lock( win32_driver_t * win32_driver, void * surface )
{
LPDIRECTDRAWSURFACE lock_surface = ( LPDIRECTDRAWSURFACE ) surface;
- DDSURFACEDESC ddsd;
HRESULT result;
if( !surface )
return 0;
- memset( &ddsd, 0, sizeof( ddsd ) );
- ddsd.dwSize = sizeof( ddsd );
+ memset( &win32_driver->ddsd, 0, sizeof( win32_driver->ddsd ) );
+ win32_driver->ddsd.dwSize = sizeof( win32_driver->ddsd );
- result = IDirectDrawSurface_Lock( lock_surface, 0, &ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
+ result = IDirectDrawSurface_Lock( lock_surface, 0, &win32_driver->ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
if( result == DDERR_SURFACELOST )
{
IDirectDrawSurface_Restore( lock_surface );
- result = IDirectDrawSurface_Lock( lock_surface, 0, &ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
+ result = IDirectDrawSurface_Lock( lock_surface, 0, &win32_driver->ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
if( result != DD_OK )
return 0;
@@ -786,7 +792,7 @@ static void * Lock( void * surface )
}
}
- return ddsd.lpSurface;
+ return win32_driver->ddsd.lpSurface;
}
/* Unlock our back buffer to prepair for display. */
@@ -946,8 +952,6 @@ static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame
{
win32_driver_t *win32_driver = ( win32_driver_t * ) vo_driver;
win32_frame_t *win32_frame = ( win32_frame_t * ) vo_frame;
- int offset;
- int size;
/* if the required width, height or format has changed
@@ -966,7 +970,7 @@ static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame
/* lock our surface to update its contents */
- win32_driver->contents = Lock( win32_driver->secondary );
+ win32_driver->contents = Lock( win32_driver, win32_driver->secondary );
/* surface unavailable, skip frame render */
@@ -1051,37 +1055,47 @@ static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame
/* the actual format is identical to our
* stream format. we just need to copy it */
- switch(win32_frame->format)
+ int line;
+ uint8_t * src;
+ vo_frame_t * frame = vo_frame;
+ uint8_t * dst = (uint8_t *)win32_driver->contents;
+
+ switch(win32_frame->format)
{
- case XINE_IMGFMT_YV12:
- {
- vo_frame_t *frame;
- uint8_t *img;
-
- frame = vo_frame;
- img = (uint8_t *)win32_driver->contents;
-
- offset = 0;
- size = frame->pitches[0] * frame->height;
- xine_fast_memcpy( img+offset, frame->base[0], size);
-
- offset += size;
- size = frame->pitches[2]* frame->height / 2;
- xine_fast_memcpy( img+offset, frame->base[2], size);
-
- offset += size;
- size = frame->pitches[1] * frame->height / 2;
- xine_fast_memcpy( img+offset, frame->base[1], size);
- }
+ case XINE_IMGFMT_YV12:
+ src = frame->base[0];
+ for (line = 0; line < frame->height ; line++){
+ xine_fast_memcpy( dst, src, frame->width);
+ src += vo_frame->pitches[0];
+ dst += win32_driver->ddsd.lPitch;
+ }
+
+ src = frame->base[2];
+ for (line = 0; line < frame->height/2 ; line++){
+ xine_fast_memcpy( dst, src, frame->width/2);
+ src += vo_frame->pitches[2];
+ dst += win32_driver->ddsd.lPitch/2;
+ }
+
+ src = frame->base[1];
+ for (line = 0; line < frame->height/2 ; line++){
+ xine_fast_memcpy( dst, src, frame->width/2);
+ src += vo_frame->pitches[1];
+ dst += win32_driver->ddsd.lPitch/2;
+ }
break;
+
case XINE_IMGFMT_YUY2:
- xine_fast_memcpy( win32_driver->contents, win32_frame->vo_frame.base[0], win32_frame->vo_frame.pitches[0] * win32_frame->vo_frame.height * 2);
- break;
default:
- xine_fast_memcpy( win32_driver->contents, win32_frame->vo_frame.base[0], win32_frame->vo_frame.pitches[0] * win32_frame->vo_frame.height * 2);
+ src = frame->base[0];
+ for (line = 0; line < frame->height ; line++){
+ xine_fast_memcpy( dst, src, frame->width*2);
+ src += vo_frame->pitches[0];
+ dst += win32_driver->ddsd.lPitch;
+ }
break;
}
- }
+ }
/* unlock the surface */
@@ -1143,10 +1157,37 @@ static int win32_gui_data_exchange( vo_driver_t * vo_driver, int data_type, void
switch( data_type )
{
+
case GUI_WIN32_MOVED_OR_RESIZED:
UpdateRect( win32_driver->win32_visual );
DisplayFrame( win32_driver );
break;
+
+ case XINE_GUI_SEND_DRAWABLE_CHANGED:
+ {
+ HRESULT result;
+ HWND newWndHnd = (HWND) data;
+
+ /* set cooperative level */
+ result = IDirectDraw_SetCooperativeLevel( win32_driver->ddobj, newWndHnd, DDSCL_NORMAL );
+ if( result != DD_OK )
+ {
+ Error( 0, "SetCooperativeLevel : error 0x%lx", result );
+ return 0;
+ }
+ /* associate our clipper with new window */
+ result = IDirectDrawClipper_SetHWnd( win32_driver->ddclipper, 0, newWndHnd );
+ if( result != DD_OK )
+ {
+ Error( 0, "ddclipper->SetHWnd : error 0x%lx", result );
+ return 0;
+ }
+ /* store our objects in our visual struct */
+ win32_driver->win32_visual->WndHnd = newWndHnd;
+ /* update video area and redraw current frame */
+ UdateRect( win32_driver->win32_visual );
+ DisplayFrame( win32_driver );
+ break;
}
return 0;