[PATCH] Mingw fixes and experimental vo directx

"Sascha Sommer" <[email protected]>
Newsgroups gmane.comp.video.mplayer.g2.devel
Message-ID <014201c35ab6$68e82d60$856254d9@oemcomputer>
Attached are some fixes for better mingw support. They are mainly backported
from main cvs.
The other patch, which, imho shouldn't be applied, contains a directx driver
for libvo2.
When all patches are applied mplayer should be compileable without network
support.
However the timer is still broken and the directx vo and the win32_helper
are missing some important features.

Sascha

_______________________________________________
MPlayer-G2-dev mailing list
[email protected]
http://mplayerhq.hu/mailman/listinfo/mplayer-g2-dev
experimentalvodirectxg2.diff (application/octet-stream, 31 KB)
diff -Naur --strip-trailing-cr g2arpi/libvo2/vo_directx.c g2/libvo2/vo_directx.c
--- g2arpi/libvo2/vo_directx.c	1970-01-01 01:00:00.000000000 +0100
+++ g2/libvo2/vo_directx.c	2003-08-04 17:28:56.000000000 +0200
@@ -0,0 +1,586 @@
+
+#include <windows.h>
+#include <windowsx.h>
+#include <ddraw.h>
+#include <dvp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#include "video_out.h"
+#include "video/vfcap.h"
+#include "video/img_format.h"
+  
+#define MAX_BUFFERS 4
+  
+  
+#if 1
+#define  DIRECTXLPDIRECTDRAWSURFACE LPDIRECTDRAWSURFACE7
+#define  DIRECTXLPDIRECTDRAW LPDIRECTDRAW7
+#define  DIRECTXDDSURFACEDESC DDSURFACEDESC2
+static const GUID directx_guid ={0x15e65ec0,0x3b9c,0x11d2,{0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b }}; /*IID_IDirectDraw7*/
+#else
+#define  DIRECTXLPDIRECTDRAWSURFACE LPDIRECTDRAWSURFACE
+#define  DIRECTXLPDIRECTDRAW LPDIRECTDRAW2
+#define  DIRECTXDDSURFACEDESC DDSURFACEDESC
+static const GUID directx_guid ={0xB3A6F3E0,0x2B43,0x11CF,{0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56}}; /*IID_IDirectDraw2*/ 
+#endif
+
+
+static struct config_data_s {
+    int overlay;
+} config_defaults = {
+    1
+};
+
+static config_t config_format[] = {
+    {"overlay", &config_defaults.overlay, CONF_TYPE_FLAG, 0, 0, 1, NULL, "enable/disable overlay usage"},
+    { NULL,}
+};
+
+static const DDPIXELFORMAT directx_pixelformats[] = {                                                                         
+	{sizeof(DDPIXELFORMAT),DDPF_FOURCC,MAKEFOURCC('Y','V','1','2'),0,0,0,0,0},
+	{sizeof(DDPIXELFORMAT),DDPF_FOURCC,MAKEFOURCC('I','4','2','0'),0,0,0,0,0},
+	{sizeof(DDPIXELFORMAT),DDPF_FOURCC,MAKEFOURCC('I','Y','U','V'),0,0,0,0,0},
+    {sizeof(DDPIXELFORMAT),DDPF_FOURCC,MAKEFOURCC('Y','V','U','9'),0,0,0,0,0},
+	{sizeof(DDPIXELFORMAT),DDPF_FOURCC,MAKEFOURCC('Y','U','Y','2'),0,0,0,0,0},
+	{sizeof(DDPIXELFORMAT),DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0},
+	{sizeof(DDPIXELFORMAT),DDPF_RGB,IMGFMT_RGB15,16,0x0000001F,0x000003E0,0x00007C00,0},
+	{sizeof(DDPIXELFORMAT),DDPF_RGB,IMGFMT_BGR15,16,0x00007C00,0x000003E0,0x0000001F,0},   
+	{sizeof(DDPIXELFORMAT),DDPF_RGB,IMGFMT_RGB16,16,0x0000F800,0x000007E0,0x0000001F,0},
+	{sizeof(DDPIXELFORMAT),DDPF_RGB,IMGFMT_BGR16,16,0x0000001F,0x000007E0,0x0000F800,0},  
+    {sizeof(DDPIXELFORMAT),DDPF_RGB,IMGFMT_RGB24,24,0x000000FF,0x0000FF00,0x00FF0000,0},   
+    {sizeof(DDPIXELFORMAT),DDPF_RGB,IMGFMT_BGR24,24,0x00FF0000,0x0000FF00,0x000000FF,0},  
+    {sizeof(DDPIXELFORMAT),DDPF_RGB,IMGFMT_RGB32,32,0x000000FF,0x0000FF00,0x00FF0000,0},  
+    {sizeof(DDPIXELFORMAT),DDPF_RGB,IMGFMT_BGR32,32,0x00FF0000,0x0000FF00,0x000000FF,0}   
+};
+#define NUM_DIRECTX_PIXELFORMATS (sizeof(directx_pixelformats) / sizeof(directx_pixelformats[0]))
+
+struct vo_priv_s {
+    HMODULE ddrawdll;
+    DIRECTXLPDIRECTDRAW  ddraw;
+    DIRECTXLPDIRECTDRAWSURFACE  primarysurface;
+    DIRECTXLPDIRECTDRAWSURFACE  overlaysurface;
+    DIRECTXLPDIRECTDRAWSURFACE  backsurface;
+    DWORD colorkey;
+    DDCAPS caps;
+    unsigned int primarypixelformat;
+    unsigned int primarycanoverlay;
+    int backsurfacememorytype;
+    int w,h;
+    unsigned int format;
+    LPDIRECTDRAWCLIPPER  clipper;
+    int overlay;
+    HWND window;
+    RECT screenposition; //screenposition usually in the client rect of the window;
+    COLORREF window_color;  
+};
+
+struct vo_buffer_priv_s {
+    DIRECTXLPDIRECTDRAWSURFACE surface;
+    DIRECTXDDSURFACEDESC sfdesc;
+};
+
+
+
+
+
+static int Directx_CreatePrimarySurface(vo_instance_t* vo)
+{
+    DIRECTXDDSURFACEDESC   sfdesc;
+    DDPIXELFORMAT   sfformat;
+    int i;
+    if(vo->priv->primarysurface)vo->priv->primarysurface->lpVtbl->Release(vo->priv->primarysurface);
+	vo->priv->primarysurface=NULL;
+	ZeroMemory(&sfdesc, sizeof(DIRECTXDDSURFACEDESC));
+    sfdesc.dwSize = sizeof(DIRECTXDDSURFACEDESC);
+    sfdesc.dwFlags = DDSD_CAPS;
+    sfdesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+    if(vo->priv->ddraw->lpVtbl->CreateSurface(vo->priv->ddraw,&sfdesc, &vo->priv->primarysurface, NULL )){
+    	mp_msg(MSGT_VO, MSGL_ERR,"vo_directx: unable to create primary surface\n");
+        return 1;
+    }
+    /*find out the pixelformat of the primarysurface*/
+    memset( &sfformat, 0, sizeof( DDPIXELFORMAT ));
+    sfformat.dwSize = sizeof( DDPIXELFORMAT );
+    vo->priv->primarysurface->lpVtbl->GetPixelFormat(vo->priv->primarysurface, &sfformat);
+    for(i=0;i<NUM_DIRECTX_PIXELFORMATS;i++){
+        if((directx_pixelformats[i].dwRGBBitCount==sfformat.dwRGBBitCount)&&(directx_pixelformats[i].dwRBitMask==sfformat.dwRBitMask)&&(directx_pixelformats[i].dwGBitMask==sfformat.dwGBitMask)){
+            vo->priv->primarypixelformat=directx_pixelformats[i].dwFourCC;       
+        }
+    }
+    mp_msg(MSGT_VO,MSGL_V,"vo_directx: primary pixelfomat is %s \n",vo_format_name(vo->priv->primarypixelformat));    
+    return 0;
+}
+
+static void free_buffers(vo_instance_t* vo){
+  int i;
+  if(!vo->buffers)return;
+  for(i=0;i<vo->num_buffers;i++){
+      vo->buffers[i].priv->surface->lpVtbl->Release(vo->buffers[i].priv->surface);
+      free(vo->buffers[i].priv);
+  }
+  free(vo->buffers);
+  vo->buffers=NULL;
+  vo->num_buffers=0;
+}
+
+static HRESULT WINAPI EnumSurfacesCallback2(DIRECTXLPDIRECTDRAWSURFACE sf,DIRECTXDDSURFACEDESC *sfdesc, LPVOID context){
+    *((DIRECTXLPDIRECTDRAWSURFACE*)context) = sf;
+    return DDENUMRET_OK;
+}
+
+/*Returns the number of backbuffers*/
+static int Directx_CreateOverlayBuffers(vo_instance_t* vo,int width,int height,int backbuffercount,unsigned int format){
+    DIRECTXDDSURFACEDESC   sfdesc;
+    HRESULT              result=DD_OK;
+	int i;
+    free_buffers(vo);
+ 	memset(&sfdesc,0,sizeof(DIRECTXDDSURFACEDESC));
+    sfdesc.dwSize = sizeof(DIRECTXDDSURFACEDESC);
+    sfdesc.dwWidth=width;
+    sfdesc.dwHeight=height;
+    for(i=0;i<NUM_DIRECTX_PIXELFORMATS;i++)
+        if(directx_pixelformats[i].dwFourCC==format)sfdesc.ddpfPixelFormat=directx_pixelformats[i];    
+    vo->buffer_flags=VO_BUFFER_FLAG_VIDEORAM|VO_BUFFER_FLAG_VISIBLE;
+    while(backbuffercount >= 0){
+      sfdesc.ddsCaps.dwCaps=DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY;
+      sfdesc.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
+      if(backbuffercount){
+        sfdesc.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX;
+        sfdesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
+        sfdesc.dwBackBufferCount=backbuffercount;
+      }
+      if(!(result=vo->priv->ddraw->lpVtbl->CreateSurface(vo->priv->ddraw,&sfdesc, &vo->priv->overlaysurface,NULL))){
+        DIRECTXLPDIRECTDRAWSURFACE sf=vo->priv->overlaysurface;  
+        mp_msg(MSGT_VO,MSGL_DBG2,"vo_directx: create %s overlay was successfull\n",vo_format_name(format));
+        if(format==vo->priv->primarypixelformat)vo->priv->primarycanoverlay=1;
+        vo->num_buffers=backbuffercount+1;       
+        vo->buffers=calloc(sizeof(vo_buffer_t),vo->num_buffers);
+        for(i=0;i<vo->num_buffers;i++){       
+            if(!vo->buffers[i].priv)vo->buffers[i].priv=calloc(sizeof(struct vo_buffer_priv_s),1);
+            ZeroMemory(&vo->buffers[i].priv->sfdesc,sizeof(DIRECTXDDSURFACEDESC));
+            vo->buffers[i].priv->sfdesc.dwSize=sizeof(DIRECTXDDSURFACEDESC);
+            vo->buffers[i].priv->surface=sf;
+            sf->lpVtbl->EnumAttachedSurfaces(sf,(LPVOID)&sf, EnumSurfacesCallback2);
+        }           
+        return 1;
+      }
+      --backbuffercount;
+    }
+    mp_msg(MSGT_VO,MSGL_DBG2,"directx: create %s overlay failed: %s (error %x)\n",vo_format_name(format),(result==DDERR_INVALIDPIXELFORMAT)?"invalid pixelformat":" ",result);
+    /*catch some general errors that make it useless to querry for other overlay formats*/
+    if((result==DDERR_OUTOFCAPS) && !backbuffercount){
+       vo->priv->overlay=0;
+       mp_msg(MSGT_VO,MSGL_DBG2,"directx: overlay is already in use by another application\n");
+    }
+    else if(result==DDERR_NOOVERLAYHW){
+        vo->priv->overlay=0;
+        mp_msg(MSGT_VO,MSGL_DBG2,"directx: overlay is not available in this display mode\n");
+    }       
+#if 0
+    else {
+        char *reason="unknown error";
+   	    switch(result){
+	      case DDERR_INCOMPATIBLEPRIMARY:
+			 reason="incompatible primary surface";
+             break;
+		  case DDERR_INVALIDCAPS:
+			 reason="invalid caps";
+             break;
+	      case DDERR_INVALIDOBJECT:
+		     reason="invalid object";
+             break;
+	      case DDERR_INVALIDPARAMS:
+		      reason="invalid parameters";
+              break;
+	      case DDERR_NODIRECTDRAWHW:
+		      reason="no directdraw hardware";
+              break;
+	      case DDERR_NOEMULATION:
+		      reason="cant emulate";
+              break;
+	      case DDERR_NOFLIPHW:
+		      reason="hardware can't do flip";
+              break;
+	      case DDERR_OUTOFMEMORY:
+		      reason="not enough system memory";
+              break;
+	      case DDERR_UNSUPPORTEDMODE:
+			  reason="unsupported mode";
+              break;  
+		  case DDERR_OUTOFVIDEOMEMORY:
+			  reason="not enough video memory";
+              break;
+	    }
+        mp_msg(MSGT_VO,MSGL_INFO,"%s\n",reason);       
+    }        
+#endif
+	return 0;		
+}
+
+static int Directx_CreateBackbuffers(vo_instance_t *vo,int width,int height,int count,DWORD memorytype){
+    HRESULT result;
+    DIRECTXDDSURFACEDESC   sfdesc;
+    DIRECTXLPDIRECTDRAWSURFACE sf;
+    int i;
+    free_buffers(vo);
+    ZeroMemory(&sfdesc, sizeof(DIRECTXDDSURFACEDESC));
+    sfdesc.dwSize = sizeof(DIRECTXDDSURFACEDESC);
+    sfdesc.ddsCaps.dwCaps= DDSCAPS_OFFSCREENPLAIN | memorytype;
+    sfdesc.dwFlags= DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+    sfdesc.dwWidth=width;
+    sfdesc.dwHeight=height;
+    vo->buffer_flags=VO_BUFFER_FLAG_VISIBLE;
+    if(vo->priv->backsurfacememorytype==DDSCAPS_VIDEOMEMORY)
+	    vo->buffer_flags |=VO_BUFFER_FLAG_VIDEORAM;
+    
+    vo->buffers=calloc(count,sizeof(vo_buffer_t));
+    for(i=0;i<count;i++){
+        if((result=vo->priv->ddraw->lpVtbl->CreateSurface(vo->priv->ddraw, &sfdesc, &sf, 0 ))){
+	       	mp_msg(MSGT_VO, MSGL_DBG2,"directx: create %s backbuffer in %s memory failed (error %x)\n",vo_format_name(vo->priv->primarypixelformat),(memorytype==DDSCAPS_SYSTEMMEMORY)?"system":"video",result);
+		    return 0;
+	    }
+        else {
+             ++vo->num_buffers;
+             if(!vo->buffers[i].priv)vo->buffers[i].priv=calloc(sizeof(struct vo_buffer_priv_s),1);
+             ZeroMemory(&vo->buffers[i].priv->sfdesc,sizeof(DIRECTXDDSURFACEDESC));
+             vo->buffers[i].priv->sfdesc.dwSize=sizeof(DIRECTXDDSURFACEDESC);   
+             vo->buffers[i].priv->surface = sf;
+             mp_msg(MSGT_VO, MSGL_DBG2,"directx: create %s backbuffer in %s memory was successfull\n",vo_format_name(vo->priv->primarypixelformat),(memorytype==DDSCAPS_SYSTEMMEMORY)?"system":"video");
+             vo->priv->backsurfacememorytype=memorytype;
+        }       
+    }
+    return 1;
+} 
+
+static void Directx_SetColorkey(vo_instance_t* vo){
+    HDC                    hdc;
+    if(!vo->priv->primarysurface->lpVtbl->GetDC(vo->priv->primarysurface,&hdc)){
+        DIRECTXDDSURFACEDESC   sfdesc;
+        COLORREF rgbT=GetPixel(hdc, 0, 0);     
+        ZeroMemory(&sfdesc, sizeof(DIRECTXDDSURFACEDESC));
+        sfdesc.dwSize = sizeof(DIRECTXDDSURFACEDESC);
+        vo->priv->colorkey = CLR_INVALID;
+        SetPixel(hdc, 0, 0, vo->priv->window_color);  
+        vo->priv->primarysurface->lpVtbl->ReleaseDC(vo->priv->primarysurface,hdc);   
+        vo->priv->primarysurface->lpVtbl->Lock(vo->priv->primarysurface,NULL,&sfdesc,DDLOCK_WAIT,NULL);       
+        vo->priv->colorkey = *(DWORD *)sfdesc.lpSurface;                
+        if(sfdesc.ddpfPixelFormat.dwRGBBitCount < 32)
+            vo->priv->colorkey &= (1 << sfdesc.ddpfPixelFormat.dwRGBBitCount) - 1;  
+        vo->priv->primarysurface->lpVtbl->Unlock(vo->priv->primarysurface,NULL); 
+        vo->priv->primarysurface->lpVtbl->GetDC(vo->priv->primarysurface,&hdc); 
+        SetPixel(hdc, 0, 0, rgbT);
+        vo->priv->primarysurface->lpVtbl->ReleaseDC(vo->priv->primarysurface,hdc); 
+    }
+    else mp_msg(MSGT_VO,MSGL_INFO,"directx: unable to set colorkey\n");
+}
+
+static int control(struct vo_instance_s* vo,int request, void *data, ...){
+    switch(request){
+    case VOCTRL_SET_WINDOW:
+	    vo->priv->window=*((HWND*)data);
+        if(!vo->priv->overlay){
+           /*release the old clipper and create a new one for nonoverlay mode*/
+           if(vo->priv->clipper)vo->priv->clipper->lpVtbl->Release(vo->priv->clipper);
+            vo->priv->clipper=NULL;       
+	        if((vo->priv->ddraw->lpVtbl->CreateClipper(vo->priv->ddraw, 0, &vo->priv->clipper,NULL))||
+                (vo->priv->clipper->lpVtbl->SetHWnd(vo->priv->clipper, 0, vo->priv->window))||
+                (vo->priv->primarysurface->lpVtbl->SetClipper(vo->priv->primarysurface,vo->priv->clipper))){
+                mp_msg(MSGT_VO,MSGL_ERR,"vo_directx: unable to create clipper\n");
+                return VO_FALSE;
+            }
+        }
+        vo->priv->window_color = RGB(0,0,16);   
+        Directx_SetColorkey(vo);
+        return VO_TRUE;
+    case VOCTRL_RESIZE_DEST:
+	    vo->priv->screenposition.left = ((int*)data)[0];
+	    vo->priv->screenposition.top =((int*)data)[1];
+	    vo->priv->screenposition.right =  vo->priv->screenposition.left + ((int*)data)[2];
+	    vo->priv->screenposition.bottom = vo->priv->screenposition.top + ((int*)data)[3];
+        if(vo->config_count && vo->priv->overlay){
+            HRESULT result;
+            DDOVERLAYFX ovfx;
+            RECT rs;
+            unsigned int stretch1000 = vo->priv->caps.dwMinOverlayStretch>1000 ? vo->priv->caps.dwMinOverlayStretch : 1000;
+            rs.top=0;       
+            rs.left=0;        
+            //   if((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) && capsDrv.dwAlignBoundarySrc)
+	        //		rs.left = (rs.left + capsDrv.dwAlignBoundarySrc / 2) & -(signed)(capsDrv.dwAlignBoundarySrc);
+            //    if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) && capsDrv.dwAlignSizeSrc)
+	        //		rs.right = rs.left + ((rs.right - rs.left + capsDrv.dwAlignSizeSrc / 2) & -(signed) (capsDrv.dwAlignSizeSrc));
+            rs.bottom=vo->buffer_h;
+            rs.right=vo->buffer_w; 
+            vo->priv->screenposition.right = ((vo->w+vo->priv->screenposition.left)*stretch1000+999)/1000;
+            vo->priv->screenposition.bottom = (vo->h+vo->priv->screenposition.top)*stretch1000/1000;
+            ZeroMemory(&ovfx, sizeof(DDOVERLAYFX));
+            ovfx.dwSize = sizeof(DDOVERLAYFX);
+	        ovfx.dckDestColorkey.dwColorSpaceLowValue = vo->priv->colorkey; 
+            ovfx.dckDestColorkey.dwColorSpaceHighValue = vo->priv->colorkey; 
+            if((result=vo->priv->overlaysurface->lpVtbl->UpdateOverlay(vo->priv->overlaysurface,&rs, vo->priv->primarysurface, &vo->priv->screenposition, DDOVER_SHOW | DDOVER_DDFX| DDOVER_KEYDESTOVERRIDE, &ovfx)))
+            mp_msg(MSGT_VO,MSGL_ERR,"unable to show overlay %x\n",result);
+        }
+        mp_msg(MSGT_VO,MSGL_V,"vo_directx: control RESIZE_DEST: %d;%d %dx%d  \n",vo->priv->screenposition.top,vo->priv->screenposition.top,vo->priv->screenposition.right - vo->priv->screenposition.left,vo->priv->screenposition.bottom - vo->priv->screenposition.top);
+	    return VO_TRUE;
+    }
+    return VO_NOTIMPL;
+}
+
+static unsigned int query_format(struct vo_instance_s* vo,unsigned int format, int width, int height){
+    width=640;
+    height=280;
+    /*check image formats */
+    /*try if format can be used for overlay (best solution as it allows colorspace conversion in hw)*/
+    if(vo->priv->overlay && Directx_CreateOverlayBuffers(vo,width,height,0,format)){
+        free_buffers(vo);       
+        return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_HWSCALE_UP|VFCAP_HWSCALE_DOWN;
+    }
+    /*if format is equal to the one of the primary surface we can use a backbuffer*/
+    if(format==vo->priv->primarypixelformat){
+        /*if we can create this surface in video memory the chance is bigger that we can do some kind of hardware scaling*/ 
+        /*whereas creating a back surface in system memory should always be possible*/       
+        if(Directx_CreateBackbuffers(vo,width,height,1,DDSCAPS_VIDEOMEMORY)||Directx_CreateBackbuffers(vo,width,height,1,DDSCAPS_SYSTEMMEMORY)){
+            free_buffers(vo);       
+            return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_HWSCALE_UP|VFCAP_HWSCALE_DOWN;
+        }       
+     }       
+    return 0;
+}
+
+
+
+static void uninit(struct vo_instance_s* vo){
+    if(vo->config_count)
+	  free_buffers(vo);
+	if(vo->priv->clipper)vo->priv->clipper->lpVtbl->Release(vo->priv->clipper);
+    if(vo->priv->primarysurface)vo->priv->primarysurface->lpVtbl->Release(vo->priv->primarysurface);
+	if(vo->priv->ddraw)vo->priv->ddraw->lpVtbl->Release(vo->priv->ddraw);
+    FreeLibrary(vo->priv->ddrawdll);
+    free(vo->priv); vo->priv=NULL;
+    free(vo);
+}
+
+
+
+
+
+
+
+
+static int config(struct vo_instance_s* vo,int width, int height, int d_width, int d_height,
+	unsigned int format){
+
+    /*no window given*/
+    if(!vo->priv->window)return VO_FALSE;
+       
+    if(vo->config_count){
+	    // free old buffers if w/h/fmt changed!
+	    if(vo->buffer_w!=width || vo->buffer_h!=height || vo->format!=format)
+            free_buffers(vo);
+	}
+    
+    if((format==vo->priv->primarypixelformat) && !vo->priv->primarycanoverlay)vo->priv->overlay=0;
+    vo->w=d_width; vo->h=d_height;
+    vo->buffer_w=width; vo->buffer_h=height; vo->format=format;
+    
+    if(!vo->buffers){
+      if(vo->priv->overlay)Directx_CreateOverlayBuffers(vo,vo->buffer_w,vo->buffer_h,MAX_BUFFERS-1,format);
+      else Directx_CreateBackbuffers(vo,vo->buffer_w,vo->buffer_h,MAX_BUFFERS,vo->priv->backsurfacememorytype);
+    }
+    
+    if(!vo->num_buffers)return VO_FALSE;
+
+#if 0
+    {   
+    int i;
+    for(i=0;i<vo->num_buffers;i++){
+        mp_msg(MSGT_VO,MSGL_V,"buffer[%i] surface %x status %i\n",i,vo->buffers[i].priv->surface,vo->buffers[i].status);
+        mp_msg(MSGT_VO,MSGL_V,"planes %x %x %x %x   strides %i %i %i %i\n",vo->buffers[i].planes[0],vo->buffers[i].planes[1],vo->buffers[i].planes[2],vo->buffers[i].planes[3],
+                                                                                                            vo->buffers[i].stride[0],vo->buffers[i].stride[1],vo->buffers[i].stride[2],vo->buffers[i].stride[3]);    
+    }       
+    }
+#endif
+      
+    
+    if(vo->priv->overlay){
+        HRESULT result;
+        DDOVERLAYFX ovfx;
+        RECT rs;
+        unsigned int stretch1000 = vo->priv->caps.dwMinOverlayStretch>1000 ? vo->priv->caps.dwMinOverlayStretch : 1000;
+        rs.top=0;       
+        rs.left=0;        
+        //   if((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) && capsDrv.dwAlignBoundarySrc)
+	    //		rs.left = (rs.left + capsDrv.dwAlignBoundarySrc / 2) & -(signed)(capsDrv.dwAlignBoundarySrc);
+        //    if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) && capsDrv.dwAlignSizeSrc)
+	    //		rs.right = rs.left + ((rs.right - rs.left + capsDrv.dwAlignSizeSrc / 2) & -(signed) (capsDrv.dwAlignSizeSrc));
+        rs.bottom=vo->buffer_h;
+        rs.right=vo->buffer_w; 
+        vo->priv->screenposition.right = ((vo->w+vo->priv->screenposition.left)*stretch1000+999)/1000;
+        vo->priv->screenposition.bottom = (vo->h+vo->priv->screenposition.top)*stretch1000/1000;
+        ZeroMemory(&ovfx, sizeof(DDOVERLAYFX));
+        ovfx.dwSize = sizeof(DDOVERLAYFX);
+	    ovfx.dckDestColorkey.dwColorSpaceLowValue = vo->priv->colorkey; 
+        ovfx.dckDestColorkey.dwColorSpaceHighValue = vo->priv->colorkey; 
+        if((result=vo->priv->overlaysurface->lpVtbl->UpdateOverlay(vo->priv->overlaysurface,&rs, vo->priv->primarysurface, &vo->priv->screenposition, DDOVER_SHOW | DDOVER_DDFX| DDOVER_KEYDESTOVERRIDE, &ovfx)))
+        mp_msg(MSGT_VO,MSGL_ERR,"unable to show overlay %x\n",result);
+    }
+      
+    
+    vo->priv->ddraw->lpVtbl->GetCaps(vo->priv->ddraw,&vo->priv->caps, NULL);
+ 
+    
+    
+    return VO_TRUE;
+}
+
+
+static int frame_start(struct vo_instance_s* vo, vo_buffer_t* buffer){
+    HRESULT result;
+    if((result=buffer->priv->surface->lpVtbl->Lock(buffer->priv->surface,NULL,&buffer->priv->sfdesc,DDLOCK_WAIT,NULL))){
+        if(result==DDERR_SURFACELOST){
+            mp_msg(MSGT_VO,MSGL_WARN,"vo_directx: restoring surfaces\n");
+            vo->priv->ddraw->lpVtbl->RestoreAllSurfaces(vo->priv->ddraw);       
+            result=buffer->priv->surface->lpVtbl->Lock(buffer->priv->surface,NULL,&buffer->priv->sfdesc,DDLOCK_WAIT,NULL);
+        }
+    }       
+    if(result){
+        mp_msg(MSGT_VO,MSGL_ERR,"vo_directx: unable to  lock buffer (%x)\n",result);
+        return VO_FALSE;
+    }
+    buffer->planes[0]=buffer->priv->sfdesc.lpSurface;
+    buffer->stride[0]=buffer->priv->sfdesc.lPitch;
+    if(vo->format==IMGFMT_YV12){
+        buffer->stride[1]=buffer->stride[2]=buffer->priv->sfdesc.lPitch/2;
+        buffer->planes[1]=buffer->planes[0]+buffer->stride[0] * vo->buffer_h;
+        buffer->planes[2]=buffer->planes[1]+buffer->stride[1] * vo->buffer_h/2;
+    }
+    else if(vo->format==IMGFMT_I420 || vo->format==IMGFMT_IYUV){
+        buffer->stride[1]=buffer->stride[2]=buffer->priv->sfdesc.lPitch/2;
+        buffer->planes[2]=buffer->planes[0]+buffer->stride[0] * vo->buffer_h;
+        buffer->planes[1]=buffer->planes[2]+buffer->stride[1] * vo->buffer_h/2;
+    }
+    else if(vo->format==IMGFMT_YVU9){
+        buffer->stride[1]=buffer->stride[2]=buffer->priv->sfdesc.lPitch/4;
+        buffer->planes[1]=buffer->planes[0]+buffer->stride[0] * vo->buffer_h;
+        buffer->planes[2]=buffer->planes[1]+buffer->stride[1] * vo->buffer_h/4;
+    }       
+  
+#if 0
+    printf("frame_start: buffer 0x%x planes[0] 0x%x stride[0] %i\n",buffer,buffer->planes[0],buffer->stride[0]);
+    printf("planes[1] 0x%x stride[1] %i\n",buffer->planes[1],buffer->stride[1]);
+    printf("planes[2] 0x%x stride[2] %i\n",buffer->planes[2],buffer->stride[2]);
+    printf("planes[3] 0x%x stride[3] %i\n",buffer->planes[3],buffer->stride[3]);
+#endif
+    return VO_TRUE;
+}
+
+static int frame_done(struct vo_instance_s* vo, vo_buffer_t*buffer){
+    if(buffer->priv->surface->lpVtbl->Unlock(buffer->priv->surface,NULL)){
+        mp_msg(MSGT_VO,MSGL_ERR,"vo_directx: unable to unlock buffer\n");
+        return VO_FALSE;
+    }       
+    buffer->planes[0]=buffer->planes[1]=buffer->planes[2]=buffer->planes[3]=NULL;
+    return VO_TRUE;
+}
+
+static void show_frame(struct vo_instance_s* vo, vo_buffer_t* buffer,unsigned int time_pos){
+    HRESULT result;
+	if(!vo->priv->overlay){
+        DDBLTFX  ddbltfx;
+        /*use the the "NOTEARING" option*/
+	    memset( &ddbltfx, 0, sizeof(DDBLTFX) );
+        ddbltfx.dwSize = sizeof(DDBLTFX);
+        ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
+        if((result=buffer->priv->surface->lpVtbl->PageLock(buffer->priv->surface,0)))mp_msg(MSGT_VO,MSGL_WARN,"page locking failed %x\n",result);  //DMA
+        if((result=vo->priv->primarysurface->lpVtbl->Blt(vo->priv->primarysurface,&vo->priv->screenposition, buffer->priv->surface, NULL, DDBLT_WAIT, &ddbltfx)))mp_msg(MSGT_VO,MSGL_ERR,"can't blit %x\n",result);
+        if((result=buffer->priv->surface->lpVtbl->PageUnlock(buffer->priv->surface,0)))mp_msg(MSGT_VO,MSGL_WARN,"page unlocking failed %x\n",result);
+        return;       
+    }
+	/*we have an overlay backsurface, flip it*/
+    if(buffer->priv->surface != vo->priv->overlaysurface){
+        if((result=vo->priv->overlaysurface->lpVtbl->Flip(vo->priv->overlaysurface,buffer->priv->surface,DDFLIP_WAIT)))
+            mp_msg(MSGT_VO,MSGL_ERR,"vo_directx: unable to flip backsurface (%x)\n",result);
+    }
+}
+
+static vo_instance_t* preinit(struct config_data_s* args,void* x11_display){
+    vo_instance_t* vo;
+ 
+    HRESULT    (WINAPI *DirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *);
+    HMODULE ddrawdll;
+    LPDIRECTDRAW   ddraw;  
+    DIRECTXLPDIRECTDRAW ddrawnew;
+   
+    /*init direct draw*/
+    if(!(ddrawdll = LoadLibraryA("ddraw.dll"))){
+        mp_msg(MSGT_VO, MSGL_ERR,"vo_directx: unable to find directx\n" );
+        return NULL;
+    }
+    DirectDrawCreate = (void *)GetProcAddress(ddrawdll, "DirectDrawCreate");
+    if(!DirectDrawCreate || DirectDrawCreate( NULL, &ddraw, NULL )){
+        mp_msg(MSGT_VO, MSGL_ERR,"vo_directx: invalid directx dlls\n");
+        FreeLibrary(ddrawdll);
+  	    return NULL;
+    }
+    if(ddraw->lpVtbl->QueryInterface(ddraw, &directx_guid, (void **)&ddrawnew)){
+        mp_msg(MSGT_VO, MSGL_ERR,"vo_directx: invalid directx version\n");
+	 	FreeLibrary(ddrawdll);
+        return NULL;
+    }
+    ddraw->lpVtbl->Release(ddraw);
+    if(ddrawnew->lpVtbl->SetCooperativeLevel(ddrawnew, NULL, DDSCL_NORMAL)){
+        mp_msg(MSGT_VO, MSGL_ERR,"vo_directx: unable to set cooperativelevel\n");
+        FreeLibrary(ddrawdll);		
+        return NULL;
+    }
+    
+    /*setup vo*/   
+    vo=calloc(sizeof(vo_instance_t),1);
+    vo->priv=calloc(sizeof(struct vo_priv_s),1);
+    vo->priv->ddraw=ddrawnew;
+    vo->priv->ddrawdll=ddrawdll;
+    
+    /*parse args*/
+    vo->priv->overlay=args->overlay;
+    
+    /*check for general overlay support*/
+    ZeroMemory(&vo->priv->caps, sizeof(DDCAPS));
+    vo->priv->caps.dwSize = sizeof(DDCAPS);
+    if(!vo->priv->overlay || vo->priv->ddraw->lpVtbl->GetCaps(vo->priv->ddraw,&vo->priv->caps, NULL) || !(vo->priv->caps.dwCaps &DDCAPS_OVERLAY)){
+        mp_msg(MSGT_VO, MSGL_INFO ,"vo_directx: overlay support not available\n");
+        vo->priv->overlay=0;       
+    }
+    
+  
+    if(vo->priv->caps.dwFXCaps & DDFXCAPS_OVERLAYMIRRORLEFTRIGHT)mp_msg(MSGT_VO, MSGL_V ,"can mirror left right\n"); 
+    if(vo->priv->caps.dwFXCaps & DDFXCAPS_OVERLAYMIRRORUPDOWN )mp_msg(MSGT_VO, MSGL_V ,"can mirror up down\n");
+    
+    if(Directx_CreatePrimarySurface(vo))return NULL;
+        
+    
+    // functions:
+    vo->query_format=query_format;
+    vo->control=control;
+    vo->config=config;
+    vo->frame_start=frame_start;
+    vo->frame_done=frame_done;  
+    vo->show_frame=show_frame;
+    vo->uninit=uninit;
+    return vo;
+}
+
+vo_info_t vo_driver_directx = {
+    MODULE_TYPE_VO, MODULE_VERSION,
+    preinit,
+    "directx",
+    "Directx Direct Draw YUV/RGB/BGR renderer",
+    "Sascha Sommer <[email protected]>",
+    "Sascha Sommer <[email protected]>",
+    NULL,
+    0, 
+    config_format,&config_defaults, sizeof(struct config_data_s)
+};
diff -Naur --strip-trailing-cr g2arpi/libvo2/win32_helper.c g2/libvo2/win32_helper.c
--- g2arpi/libvo2/win32_helper.c	1970-01-01 01:00:00.000000000 +0100
+++ g2/libvo2/win32_helper.c	2003-08-04 19:20:26.000000000 +0200
@@ -0,0 +1,153 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <windows.h>
+
+#include "mp_msg.h"
+#include "help_mp.h"
+#include "video_out.h"
+
+static COLORREF window_color = RGB(0,0,16); 
+
+static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    struct vo_instance_s* vo = (struct vo_instance_s*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
+	switch (message)
+    {
+		case WM_DESTROY:
+		    PostQuitMessage(0);
+			return 0;
+		case WM_WINDOWPOSCHANGED:
+             if(vo){        
+             int tmp[4];
+              
+              RECT rd;
+              POINT pt;       
+              GetClientRect(hWnd,&rd);
+              pt.x=0;pt.y=0;
+              ClientToScreen(hWnd,&pt);       
+              tmp[0]=pt.x;
+              tmp[1]=pt.y;
+              tmp[2]=rd.right-rd.left;
+              tmp[3]=rd.bottom-rd.top;       
+              vo->control(vo,VOCTRL_RESIZE_DEST,tmp);
+              return 0;       
+             }       
+
+ 
+ 
+    }
+	return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+
+static HWND win32_window(int w,int h){
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+	HICON mplayericon=NULL;
+    HWND window;
+    char exedir[MAX_PATH];
+    WNDCLASS   wc;
+    /*load icon from the main app*/
+    if(GetModuleFileName(NULL,exedir,MAX_PATH)){
+         mplayericon = ExtractIcon( hInstance, exedir, 0 );
+  	}
+    if(!mplayericon)mplayericon=LoadIcon(NULL,IDI_APPLICATION);
+    wc.style         =  CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc   =  WndProc;
+    wc.cbClsExtra    =    0;
+    wc.cbWndExtra    =  0;
+    wc.hInstance     =  hInstance;
+    wc.hCursor       =  LoadCursor(NULL,IDC_ARROW);
+    wc.hIcon         =  mplayericon;
+    wc.hbrBackground =  CreateSolidBrush(window_color);
+    wc.lpszClassName =  "Mplayer - Movieplayer for Linux";
+    wc.lpszMenuName  =  NULL;
+    RegisterClass(&wc);
+    window = CreateWindow("MPlayer - Movieplayer for Linux",
+                        "MPlayer G2",
+                        WS_OVERLAPPEDWINDOW| WS_SIZEBOX,
+                        /*CW_USEDEFAULT*/50,                   //position x 
+                        /*CW_USEDEFAULT*/50,                   //position y
+                        w,                             //width
+                        h,                             //height 
+                        NULL,
+                        NULL,
+                        hInstance,
+                        NULL);
+   ShowWindow(window,SW_SHOW);
+   return window;
+}
+
+static void win32_event_callback(struct vo_instance_s* vo,
+        int type, unsigned int flags, int x, int y){
+    HWND vo_window;       
+    switch(type){
+    case VO_EVENT_CONFIG:
+	// this event is generated by vf_vo2.c
+	mp_msg(MSGT_CPLAYER,MSGL_V,"vo-event: configured to %d x %d\n",x,y);
+    vo_window=win32_window(x,y);
+    SetWindowLongPtr(vo_window,GWLP_USERDATA,(DWORD)vo);
+	vo->control(vo,VOCTRL_SET_WINDOW,&vo_window);
+    { /*get screenposition from the window client area*/
+            POINT           point_window;
+            RECT rd;       
+            int tmp[4];
+            GetClientRect(vo_window,&rd);       
+            point_window.x=point_window.y=0;
+            ClientToScreen(vo_window,&point_window);  
+            tmp[0]=point_window.x;
+            tmp[1]=point_window.y;
+            tmp[2]=rd.right-rd.left;
+            tmp[3]=rd.bottom-rd.top;       
+            vo->control(vo,VOCTRL_RESIZE_DEST,tmp);
+                       
+            
+        }       
+                 
+
+    
+    
+    
+	break;
+    // events generated by vo_x11_check_events():
+    case VO_EVENT_EXPOSE:
+    case VO_EVENT_MOVE: {
+	int tmp[4];
+	mp_msg(MSGT_CPLAYER,MSGL_V,"vo-event: moved to %d x %d\n",x,y);
+// dont do that, we're moving the window, not the picture inside the window!
+//	tmp[2]=tmp[3]=-1; tmp[0]=x; tmp[1]=y;
+// ok, instead we should call VOCTRL_RESIZE_DEST with all -1 to update coords
+// (required for overlays subvos where window moves require overlay config)
+	tmp[0]=tmp[1]=tmp[2]=tmp[3]=-1;
+	vo->control(vo,VOCTRL_RESIZE_DEST,tmp);
+	break;
+    }
+    default:
+	vo_default_event_callback(vo,type,flags,x,y);
+    }
+}
+
+static void win32_check_event(struct vo_instance_s* vo){
+    MSG msg;
+    while (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
+    {
+		TranslateMessage(&msg);
+        DispatchMessage(&msg);
+    }
+
+
+}
+
+vo_instance_t*  vo_x11_init_best(config_modlist_t* vo_list){
+    vo_instance_t* vo;
+    if(!(vo=vo2_init_best(vo_list,NULL))){
+        mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_ErrorInitializingVODevice);
+        return NULL;
+    }
+    vo->check_events=win32_check_event; // poll X11 events
+    vo->event_callback=win32_event_callback; // do window handling
+    return vo;
+}
mingwfixes.diff (application/octet-stream, 14.8 KB)
diff -Naur --strip-trailing-cr g2arpi/Makefile g2/Makefile
--- g2arpi/Makefile	2003-07-10 22:54:14.000000000 +0200
+++ g2/Makefile	2003-08-04 17:40:16.000000000 +0200
@@ -79,10 +79,10 @@
 	$(CC) $(OBJS) test-codecs.o osdep/cpudetect.o -o test-codecs $(CODECS_DEPS) $(STREAM_DEPS) $(PLAYER_DEPS) $(EXTRA_LIB) $(CDPARANOIA_LIB) osdep/libosdep.a $(SMBCLIENT_LIB) $(AO_LIBS) $(VO_LIBS) $(THEORA_LIB) $(VORBIS_LIB) $(I18NLIBS) -lm
 
 test-play: $(OBJS) $(CODECS_DEPS) $(STREAM_DEPS) $(PLAYER_DEPS) osdep/libosdep.a test-play.o input/libinput.a 
-	$(CC) $(OBJS) test-play.o -o test-play $(CODECS_DEPS) $(STREAM_DEPS) $(PLAYER_DEPS) input/libinput.a osdep/libosdep.a $(EXTRA_LIB) $(CDPARANOIA_LIB)  $(SMBCLIENT_LIB) $(AO_LIBS) $(VO_LIBS) $(TERMCAP_LIB) $(LIRC_LIB) $(THEORA_LIB) $(VORBIS_LIB) $(I18NLIBS) -lm
+	$(CC) $(OBJS) test-play.o -o test-play $(CODECS_DEPS) $(STREAM_DEPS) $(PLAYER_DEPS) input/libinput.a osdep/libosdep.a $(EXTRA_LIB) $(CDPARANOIA_LIB)  $(SMBCLIENT_LIB) $(AO_LIBS) $(VO_LIBS) $(TERMCAP_LIB) $(LIRC_LIB) $(THEORA_LIB) $(VORBIS_LIB) $(I18NLIBS) $(WIN32_LIB) -lm
 
 test-input: test-input.o input/libinput.a osdep/libosdep.a mp_msg.o get_path.o
-	$(CC) test-input.o -o test-input input/libinput.a osdep/libosdep.a mp_msg.o get_path.o $(EXTRA_LIB) $(TERMCAP_LIB) $(LIRC_LIB) $(I18NLIBS) $(MACOSX_FRAMEWORKS)
+	$(CC) test-input.o -o test-input input/libinput.a osdep/libosdep.a mp_msg.o get_path.o $(EXTRA_LIB) $(TERMCAP_LIB) $(LIRC_LIB) $(I18NLIBS) $(MACOSX_FRAMEWORKS) $(WIN32_LIB)
 
 
 .c.o:
diff -Naur --strip-trailing-cr g2arpi/libao2/ao_win32.c g2/libao2/ao_win32.c
--- g2arpi/libao2/ao_win32.c	2003-03-23 01:00:26.000000000 +0100
+++ g2/libao2/ao_win32.c	2003-08-04 14:22:08.000000000 +0200
@@ -27,7 +27,7 @@
 #include "audio_out.h"
 #include "audio_out_internal.h"
 #include "../mp_msg.h"
-#include "../libvo/fastmemcpy.h"
+#include "../fastmemcpy.h"
 
 #define SAMPLESIZE   1024
 #define BUFFER_SIZE  4096
@@ -242,7 +242,7 @@
 {
 	return write_waveOutBuffer(data,len);
 }
-int previous = 0;
+
 // return: delay in seconds between first and last sample in buffer
 static float get_delay()
 {
diff -Naur --strip-trailing-cr g2arpi/libvo2/Makefile g2/libvo2/Makefile
--- g2arpi/libvo2/Makefile	2003-07-24 00:12:26.000000000 +0200
+++ g2/libvo2/Makefile	2003-08-04 14:53:04.000000000 +0200
@@ -3,7 +3,7 @@
 
 LIBNAME = libvo2.a
 
-SRCS=vo_null.c vo_fbdev.c vo_x11.c vo_xv.c vo_mga.c vo_tdfx_vid.c vo_xover.c video_out.c event.c x11_helper.c # vo_pgm.c vo_md5.c
+SRCS=vo_null.c vo_directx.c video_out.c event.c win32_helper.c # vo_pgm.c vo_md5.c
 OBJS=$(SRCS:.c=.o)
 
 ifeq ($(VIDIX),yes)
diff -Naur --strip-trailing-cr g2arpi/libvo2/video_out.c g2/libvo2/video_out.c
--- g2arpi/libvo2/video_out.c	2003-07-24 21:47:42.000000000 +0200
+++ g2/libvo2/video_out.c	2003-08-04 14:58:58.000000000 +0200
@@ -13,6 +13,7 @@
 #include "mp_msg.h"
 #include "help_mp.h"
 
+extern vo_info_t vo_driver_directx;
 extern vo_info_t vo_driver_fbdev;
 extern vo_info_t vo_driver_mga;
 extern vo_info_t vo_driver_x11;
@@ -22,12 +23,25 @@
 extern vo_info_t vo_driver_xover;
 
 vo_info_t* video_out_drivers[] = {
+#ifdef HAVE_DIRECTX
+    &vo_driver_directx,
+#endif
+#ifdef HAVE_FBDEV
     &vo_driver_fbdev,
+#endif
+#ifdef HAVE_MGA
     &vo_driver_mga,
+#endif
+#ifdef HAVE_TDFX_VID
     &vo_driver_tdfx_vid,
+#endif
+#ifdef HAVE_X11
     &vo_driver_x11,
+#ifdef HAVE_XV
     &vo_driver_xv,
+#endif
     &vo_driver_xover,
+#endif
     &vo_driver_null,
     NULL
 };
diff -Naur --strip-trailing-cr g2arpi/osdep/Makefile g2/osdep/Makefile
--- g2arpi/osdep/Makefile	2003-05-10 01:24:14.000000000 +0200
+++ g2/osdep/Makefile	2003-08-02 12:16:42.000000000 +0200
@@ -3,7 +3,7 @@
 
 LIBNAME = libosdep.a
 
-SRCS=shmem.c cpudetect.c aclib.c
+SRCS=cpudetect.c aclib.c
 
 getch = getch2.c
 timer = timer-lx.c
@@ -16,6 +16,9 @@
 ifeq ($(TARGET_MINGW32),yes)
 timer = timer-win.c
 getch = getch2-win.c
+SRCS += gettimeofday.c strsep.c vsscanf.c
+else
+SRCS += shmem.c
 endif
 SRCS += $(timer)
 SRCS += $(getch)
diff -Naur --strip-trailing-cr g2arpi/osdep/cpudetect.c g2/osdep/cpudetect.c
--- g2arpi/osdep/cpudetect.c	2003-02-09 20:33:28.000000000 +0100
+++ g2/osdep/cpudetect.c	2003-07-19 14:18:36.000000000 +0200
@@ -29,6 +29,10 @@
 #include <signal.h>
 #endif
 
+#ifdef WIN32
+#include <windows.h>
+#endif
+
 //#define X86_FXSR_MAGIC
 /* Thanks to the FreeBSD project for some of this cpuid code, and 
  * help understanding how to use it.  Thanks to the Mesa 
@@ -163,7 +167,7 @@
 #endif
 
 		/* FIXME: Does SSE2 need more OS support, too? */
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(WIN32)
 		if (caps->hasSSE)
 			check_os_katmai_support();
 		if (!caps->hasSSE)
@@ -293,6 +297,19 @@
 }
 #endif /* __linux__ && _POSIX_SOURCE && X86_FXSR_MAGIC */
 
+#ifdef WIN32
+LONG CALLBACK win32_sig_handler_sse(EXCEPTION_POINTERS* ep)
+{
+   if(ep->ExceptionRecord->ExceptionCode==EXCEPTION_ILLEGAL_INSTRUCTION){
+      mp_msg(MSGT_CPUDETECT,MSGL_V, "SIGILL, " );
+      ep->ContextRecord->Eip +=3;
+      gCpuCaps.hasSSE=0;       
+	  return EXCEPTION_CONTINUE_EXECUTION;
+   }
+   return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif /* WIN32 */
+
 /* If we're running on a processor that can do SSE, let's see if we
  * are allowed to or not.  This will catch 2.4.0 or later kernels that
  * haven't been configured for a Pentium III but are running on one,
@@ -343,6 +360,16 @@
    gCpuCaps.hasSSE = 0;
    mp_msg(MSGT_CPUDETECT,MSGL_WARN, "No OS support for SSE, disabling to be safe.\n" );
 #endif
+#elif defined(WIN32)
+   LPTOP_LEVEL_EXCEPTION_FILTER exc_fil;
+   if ( gCpuCaps.hasSSE ) {
+      mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE... " );
+      exc_fil = SetUnhandledExceptionFilter(win32_sig_handler_sse);
+      __asm __volatile ("xorps %xmm0, %xmm0");
+      SetUnhandledExceptionFilter(exc_fil);
+      if ( gCpuCaps.hasSSE ) mp_msg(MSGT_CPUDETECT,MSGL_V, "yes.\n" );
+      else mp_msg(MSGT_CPUDETECT,MSGL_V, "no!\n" );
+   }
 #elif defined(__linux__)
 #if defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC)
    struct sigaction saved_sigill;
diff -Naur --strip-trailing-cr g2arpi/osdep/getch2-win.c g2/osdep/getch2-win.c
--- g2arpi/osdep/getch2-win.c	2003-03-30 23:20:04.000000000 +0200
+++ g2/osdep/getch2-win.c	2003-06-01 14:33:32.000000000 +0200
@@ -14,11 +14,13 @@
 }
 
 static HANDLE stdin;
+static int getch2_status=0;
 
 int getch2(int time){
 	INPUT_RECORD eventbuffer[128];
     DWORD retval;
    	int i=0;
+    if(!getch2_status)return -1;    
     /*check if there are input events*/
 	if(!GetNumberOfConsoleInputEvents(stdin,&retval))
 	{
@@ -72,9 +74,11 @@
 						return KEY_RIGHT;
 					case VK_DOWN:
 						return KEY_DOWN;
+                    case VK_SHIFT:
+                        continue;              
 					}
 					/*check for function keys*/
-        			if(eventbuffer[i].Event.KeyEvent.wVirtualKeyCode >= 0x70)
+        			if(0x87 >= eventbuffer[i].Event.KeyEvent.wVirtualKeyCode >= 0x70)
 						return (KEY_F + 1 + eventbuffer[i].Event.KeyEvent.wVirtualKeyCode - 0x70);
  						
 					/*only characters should be remaining*/
@@ -95,11 +99,16 @@
 	return -1;
 }
 
-static int getch2_status=0;
 
 void getch2_enable(){
-	stdin = GetStdHandle(STD_INPUT_HANDLE);
-    getch2_status=1;
+	DWORD retval;
+    stdin = GetStdHandle(STD_INPUT_HANDLE);
+   	if(!GetNumberOfConsoleInputEvents(stdin,&retval))
+	{
+		printf("getch2: %i can't get number of input events  [disabling console input]\n",GetLastError());
+		getch2_status = 0;
+	}
+    else getch2_status=1;
 }
 
 void getch2_disable(){
diff -Naur --strip-trailing-cr g2arpi/osdep/gettimeofday.c g2/osdep/gettimeofday.c
--- g2arpi/osdep/gettimeofday.c	1970-01-01 01:00:00.000000000 +0100
+++ g2/osdep/gettimeofday.c	2003-04-04 22:40:58.000000000 +0200
@@ -0,0 +1,12 @@
+#include "../config.h"
+
+#ifndef HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#include <sys/timeb.h>
+void gettimeofday(struct timeval* t,void* timezone)
+{       struct timeb timebuffer;
+        ftime( &timebuffer );
+        t->tv_sec=timebuffer.time;
+        t->tv_usec=1000*timebuffer.millitm;
+}
+#endif
diff -Naur --strip-trailing-cr g2arpi/osdep/strsep.c g2/osdep/strsep.c
--- g2arpi/osdep/strsep.c	1970-01-01 01:00:00.000000000 +0100
+++ g2/osdep/strsep.c	2002-03-29 22:24:36.000000000 +0100
@@ -0,0 +1,42 @@
+/* strsep implementation for systems that do not have it in libc */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../config.h"
+
+#ifndef HAVE_STRSEP
+char *strsep(char **stringp, const char *delim) {
+  char *begin, *end;
+
+  begin = *stringp;
+  if(begin == NULL)
+    return NULL;
+
+  if(delim[0] == '\0' || delim[1] == '\0') {
+    char ch = delim[0];
+
+    if(ch == '\0')
+      end = NULL;
+    else {
+      if(*begin == ch)
+        end = begin;
+      else if(*begin == '\0')
+        end = NULL;
+      else
+        end = strchr(begin + 1, ch);
+    }
+  }
+  else
+    end = strpbrk(begin, delim);
+
+  if(end) {
+    *end++ = '\0';
+    *stringp = end;
+  }
+  else
+    *stringp = NULL;
+ 
+  return begin;
+}
+#endif
diff -Naur --strip-trailing-cr g2arpi/osdep/timer-win.c g2/osdep/timer-win.c
--- g2arpi/osdep/timer-win.c	2003-07-30 01:51:00.000000000 +0200
+++ g2/osdep/timer-win.c	2003-08-04 20:08:18.000000000 +0200
@@ -3,6 +3,7 @@
 #include <windows.h>
 #include <mmsystem.h>
 #include <sys/time.h>
+#include "../mp_msg.h"
 
 static LARGE_INTEGER qwTimerFrequency;
 static LARGE_INTEGER qwTimerStart;
@@ -41,6 +42,25 @@
 }
 
 
+
+void sleep_accurate2(unsigned int time_pos){
+    int time_frame;
+    int softsleep=1;
+    //usec_sleep(time_pos/1000);
+    if(softsleep){
+
+	    if(((int)(time_pos-GetTimer())) < 0)
+		mp_msg(MSGT_AVSYNC, MSGL_V, "Warning! Softsleep underflow!\n");
+	    while (((int)(time_pos-GetTimer())) > 0) { } // burn the CPU
+    }
+}
+
+
+
+
+
+
+
 // Returns current time in milliseconds
 unsigned int GetTimerMS()
 {
diff -Naur --strip-trailing-cr g2arpi/osdep/vsscanf.c g2/osdep/vsscanf.c
--- g2arpi/osdep/vsscanf.c	1970-01-01 01:00:00.000000000 +0100
+++ g2/osdep/vsscanf.c	2002-11-26 19:53:00.000000000 +0100
@@ -0,0 +1,20 @@
+#include "../config.h"
+
+#ifndef	HAVE_VSSCANF
+/* system has no vsscanf.  try to provide one */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+int
+vsscanf(const char *str, const char *format, va_list ap)
+{
+    /* XXX: can this be implemented in a more portable way? */
+    long p1 = va_arg(ap, long);
+    long p2 = va_arg(ap, long);
+    long p3 = va_arg(ap, long);
+    long p4 = va_arg(ap, long);
+    long p5 = va_arg(ap, long);
+    return sscanf(str, format, p1, p2, p3, p4, p5);
+}
+#endif
diff -Naur --strip-trailing-cr g2arpi/stream/cache2.c g2/stream/cache2.c
--- g2arpi/stream/cache2.c	2003-03-31 01:40:32.000000000 +0200
+++ g2/stream/cache2.c	2003-08-04 20:16:32.000000000 +0200
@@ -17,7 +17,14 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "../osdep/timer.h"
+#ifndef WIN32
+#include <sys/wait.h>
 #include "../osdep/shmem.h"
+#else
+#include <windows.h>
+static DWORD WINAPI ThreadProc(void* s);
+#endif
 
 #include "../mp_msg.h"
 
@@ -69,7 +76,7 @@
 	// eof?
 	if(s->eof) break;
 	// waiting for buffer fill...
-	usleep(READ_USLEEP_TIME); // 10ms
+	usec_sleep(READ_USLEEP_TIME); // 10ms
 	continue; // try again...
     }
 
@@ -182,18 +189,46 @@
 
 cache_vars_t* cache_init(int size,int sector){
   int num;
+#ifndef WIN32
   cache_vars_t* s=shmem_alloc(sizeof(cache_vars_t));
+#else
+  cache_vars_t* s=malloc(sizeof(cache_vars_t));
+#endif
   memset(s,0,sizeof(cache_vars_t));
   num=size/sector;
   s->buffer_size=num*sector;
   s->sector_size=sector;
+#ifndef WIN32
   s->buffer=shmem_alloc(s->buffer_size);
+#else
+  s->buffer=malloc(s->buffer_size);
+#endif
   s->fill_limit=8*sector;
   s->back_size=size/2;
   s->prefill=size/20; // default: 5%
   return s;
 }
 
+void cache_uninit(stream_t *s) {
+  cache_vars_t* c = s->cache_data;
+  if(!s->cache_pid) return;
+#ifndef WIN32
+  kill(s->cache_pid,SIGKILL);
+  waitpid(s->cache_pid,NULL,0);
+#else
+  TerminateThread((HANDLE)s->cache_pid,0);
+  free(c->stream);
+#endif
+  if(!c) return;
+#ifndef WIN32
+  shmem_free(c->buffer,c->buffer_size);
+  shmem_free(s->cache_data,sizeof(cache_vars_t));
+#else
+  free(c->buffer);
+  free(s->cache_data);
+#endif
+}
+
 static void exit_sighandler(int x){
   // close stream
   exit(0);
@@ -215,7 +250,16 @@
   s->stream=stream; // callback
   s->prefill=size*prefill;
   
+#ifndef WIN32  
   if((stream->cache_pid=fork())){
+#else
+  {
+    DWORD threadId;
+    stream_t* stream2=malloc(sizeof(stream_t));
+    memcpy(stream2,s->stream,sizeof(stream_t));
+    s->stream=stream2;
+    stream->cache_pid = CreateThread(NULL,0,ThreadProc,s,0,&threadId);
+#endif
     // wait until cache is filled at least prefill_init %
     mp_msg(MSGT_CACHE,MSGL_V,"CACHE_PRE_INIT: %d [%d] %d  pre:%d  eof:%d  \n",
 	s->min_filepos,s->read_filepos,s->max_filepos,min,s->eof);
@@ -230,11 +274,16 @@
     return 1; // parent exits
   }
   
+#ifdef WIN32
+}
+static DWORD WINAPI ThreadProc(void*s){
+#endif
+  
 // cache thread mainloop:
   signal(SIGTERM,exit_sighandler); // kill
   while(1){
-    if(!cache_fill(s)){
-	 usleep(FILL_USLEEP_TIME); // idle
+    if(!cache_fill((cache_vars_t*)s)){
+	 usec_sleep(FILL_USLEEP_TIME); // idle
     }
 //	 cache_stats(s->cache_data);
   }
diff -Naur --strip-trailing-cr g2arpi/stream/mpdvdkit2/dvd_reader.c g2/stream/mpdvdkit2/dvd_reader.c
--- g2arpi/stream/mpdvdkit2/dvd_reader.c	2003-02-08 01:22:38.000000000 +0100
+++ g2/stream/mpdvdkit2/dvd_reader.c	2003-08-02 12:12:40.000000000 +0200
@@ -310,7 +310,9 @@
 	    if( cdir >= 0 ) {
 		chdir( path_copy );
 		new_path = getcwd( NULL, PATH_MAX );
+#ifndef __MINGW32__       
 		fchdir( cdir );
+#endif       
 		close( cdir );
 		if( new_path ) {
 		    free( path_copy );
diff -Naur --strip-trailing-cr g2arpi/stream/stream.c g2/stream/stream.c
--- g2arpi/stream/stream.c	2003-07-10 21:55:42.000000000 +0200
+++ g2/stream/stream.c	2003-08-04 14:33:46.000000000 +0200
@@ -11,9 +11,14 @@
 #ifdef USE_STREAM_CACHE
 // for kill/waitpid
 #include <signal.h>
+#ifndef __MINGW32__
 #include <sys/ioctl.h>
 #include <sys/wait.h>
 #endif
+#ifdef WIN32
+#include <windows.h>
+#endif
+#endif
 
 #include "stream.h"
 
@@ -271,10 +276,15 @@
 //  printf("\n*** free_stream() called ***\n");
 #ifdef USE_STREAM_CACHE
   if(s->cache_pid) {
+#ifndef WIN32
 //    kill(s->cache_pid,SIGTERM);
     kill(s->cache_pid,SIGKILL);
     waitpid(s->cache_pid,NULL,0);
     shmem_free(s->cache_data);
+#else
+    TerminateThread((HANDLE)s->cache_pid,0);
+    free(s->cache_data);
+#endif
   }
 #endif
   if(s->type==STREAMTYPE_DRIVER && s->driver->free) s->driver->free(s);
diff -Naur --strip-trailing-cr g2arpi/stream/stream_dvd.c g2/stream/stream_dvd.c
--- g2arpi/stream/stream_dvd.c	2003-04-16 23:00:50.000000000 +0200
+++ g2/stream/stream_dvd.c	2003-08-04 14:34:24.000000000 +0200
@@ -11,7 +11,9 @@
 
 //#include <sys/types.h>
 #include <sys/stat.h>
+#ifndef __MINGW32__
 #include <sys/ioctl.h>
+#endif
 //#include <sys/wait.h>
 //#include <signal.h>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.