[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>