Index: libvo/vo_direct3d.c =================================================================== --- libvo/vo_direct3d.c (revision 27958) +++ libvo/vo_direct3d.c (working copy) @@ -52,8 +52,6 @@ static int gIsPaused; /**< 1 = Movie is paused, 0 = Movie is not paused */ -static int gIsD3DConfigFinished; /**< Synchronization "semaphore". 1 when - instance of D3DConfigure is finished */ static int gIsPanscan; /**< 1= Panscan enabled, 0 = Panscan disabled */ static RECT gFullScrMovieRect; /**< Rect (upscaled) of the movie when displayed in fullscreen */ @@ -72,6 +70,10 @@ the movie's codec) */ static D3DFORMAT gDesktopFmt; /**< Desktop (screen) colorspace format. Usually XRGB */ +static int gIsLocked; /* is the region locked */ +static D3DLOCKED_RECT gLockedRect; /**< Offscreen surface we lock in order + to copy MPlayer's frame inside it.*/ + typedef struct { const unsigned int MPlayerFormat; /**< Given by MPlayer */ @@ -191,6 +193,12 @@ mp_msg(MSGT_VO,MSGL_V,"D3DDestroyContext called\r\n"); /* Let's destroy the old (if any) D3D Content */ + if (gIsLocked) + { + IDirect3DSurface9_UnlockRect(gpD3DSurface); + gIsLocked = 0; + } + if (gpD3DSurface != NULL) { IDirect3DSurface9_Release (gpD3DSurface); @@ -303,9 +311,6 @@ { mp_msg(MSGT_VO,MSGL_V,"D3DUninit called\r\n"); - /* Block further calls to D3DConfigure(). */ - gIsD3DConfigFinished = 0; - /* Destroy D3D Context inside the window. */ D3DDestroyContext(); @@ -331,21 +336,14 @@ */ if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) - return VO_TRUE; + goto skip_upload; if (mpi->flags & MP_IMGFLAG_PLANAR) { /* Copy a planar frame. */ draw_slice(mpi->planes,mpi->stride,mpi->w,mpi->h,0,0); - return VO_TRUE; + goto skip_upload; } - /* If the previous if failed, we should draw a packed frame */ - if (FAILED (IDirect3DDevice9_BeginScene(gpD3DDevice))) - { - mp_msg(MSGT_VO,MSGL_ERR,"BeginScene failed\n"); - return VO_ERROR; - } - if (FAILED (IDirect3DSurface9_LockRect(gpD3DSurface, &stLockedRect, NULL, 0))) { @@ -356,12 +354,23 @@ memcpy_pic(stLockedRect.pBits, mpi->planes[0], mpi->stride[0], mpi->height, stLockedRect.Pitch, mpi->stride[0]); +skip_upload: + + /* this unlock is used for both slice_draw path and D3DRenderFrame path */ if (FAILED (IDirect3DSurface9_UnlockRect(gpD3DSurface))) { mp_msg(MSGT_VO,MSGL_V,"Surface unlock failure\n"); return VO_ERROR; } + gIsLocked = 0; + /* If the previous if failed, we should draw a packed frame */ + if (FAILED (IDirect3DDevice9_BeginScene(gpD3DDevice))) + { + mp_msg(MSGT_VO,MSGL_ERR,"BeginScene failed\n"); + return VO_ERROR; + } + if (FAILED (IDirect3DDevice9_StretchRect (gpD3DDevice, gpD3DSurface, gIsPanscan == 1 ? @@ -443,7 +452,8 @@ D3DDISPLAYMODE DisplayMode; /* Set to zero all global variables. */ gIsPaused = 0; - gIsD3DConfigFinished = 0; + //gIsD3DConfigFinished = 0; + gIsLocked = 0; gIsPanscan = 0; gpD3DHandle = NULL; gpD3DDevice = NULL; @@ -484,9 +494,6 @@ return -1; } - /* Allow the first call to D3DConfigure. */ - gIsD3DConfigFinished = 1; - return 0; } @@ -573,16 +580,11 @@ return VO_ERROR; } - if (gIsD3DConfigFinished == 1) - { - gIsD3DConfigFinished = 0; - if (D3DConfigure () == 0) - { - gIsD3DConfigFinished = 1; - return VO_ERROR; - } - gIsD3DConfigFinished = 1; - } + if (D3DConfigure () == 0) + { + return VO_ERROR; + } + return 0; /* Success */ } @@ -656,39 +658,36 @@ */ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y ) { - D3DLOCKED_RECT stLockedRect; /**< Offscreen surface we lock in order - to copy MPlayer's frame inside it.*/ char *Src; /**< Pointer to the source image */ char *Dst; /**< Pointer to the destination image */ int UVstride; /**< Stride of the U/V planes */ - if (FAILED (IDirect3DDevice9_BeginScene(gpD3DDevice))) - { - mp_msg(MSGT_VO,MSGL_ERR,"BeginScene failed\n"); - return VO_ERROR; - } + if (gIsLocked == 0) + { + if (FAILED (IDirect3DSurface9_LockRect(gpD3DSurface, + &gLockedRect, NULL, 0))) + { + mp_msg(MSGT_VO,MSGL_V,"Surface lock failure\n"); + return VO_FALSE; + } - if (FAILED (IDirect3DSurface9_LockRect(gpD3DSurface, - &stLockedRect, NULL, 0))) - { - mp_msg(MSGT_VO,MSGL_V,"Surface lock failure\n"); - return VO_FALSE; - } + gIsLocked = 1; /* Dont lock again! */ + } - UVstride = stLockedRect.Pitch / 2; + UVstride = gLockedRect.Pitch / 2; /* Copy Y */ - Dst = stLockedRect.pBits; - Dst = Dst + stLockedRect.Pitch * y + x; + Dst = gLockedRect.pBits; + Dst = Dst + gLockedRect.Pitch * y + x; Src=src[0]; - memcpy_pic(Dst, Src, w, h, stLockedRect.Pitch, stride[0]); + memcpy_pic(Dst, Src, w, h, gLockedRect.Pitch, stride[0]); w/=2;h/=2;x/=2;y/=2; /* Copy U */ - Dst = stLockedRect.pBits; - Dst = Dst + stLockedRect.Pitch * gSrcHeight - + UVstride * y + x; + Dst = gLockedRect.pBits; + Dst = Dst + gLockedRect.Pitch * gSrcHeight + + UVstride * y + x; if (gMovieSrcFmt == MAKEFOURCC('Y','V','1','2')) Src=src[2]; else @@ -697,9 +696,9 @@ memcpy_pic(Dst, Src, w, h, UVstride, stride[1]); /* Copy V */ - Dst = stLockedRect.pBits; - Dst = Dst + stLockedRect.Pitch * gSrcHeight - + UVstride * (gSrcHeight / 2) + UVstride * y + x; + Dst = gLockedRect.pBits; + Dst = Dst + gLockedRect.Pitch * gSrcHeight + + UVstride * (gSrcHeight / 2) + UVstride * y + x; if (gMovieSrcFmt == MAKEFOURCC('Y','V','1','2')) Src=src[1]; else @@ -707,32 +706,6 @@ memcpy_pic(Dst, Src, w, h, UVstride, stride[2]); - if (FAILED (IDirect3DSurface9_UnlockRect(gpD3DSurface))) - { - mp_msg(MSGT_VO,MSGL_V,"Surface unlock failure\n"); - return VO_ERROR; - } - - if (FAILED (IDirect3DDevice9_StretchRect (gpD3DDevice, - gpD3DSurface, - gIsPanscan == 1 ? - &gPanScanSrcRect : NULL, - gpD3DBackBuf, - vo_fs == 1 ? - &gFullScrMovieRect : NULL, - D3DTEXF_LINEAR))) - { - mp_msg(MSGT_VO,MSGL_V, - "Unable to copy the frame to the back buffer\n"); - return VO_ERROR; - } - - if (FAILED (IDirect3DDevice9_EndScene(gpD3DDevice))) - { - mp_msg(MSGT_VO,MSGL_ERR,"EndScene failed\n"); - return VO_ERROR; - } - return 0; /* Success */ }