Index: libvo/vo_direct3d.c =================================================================== --- libvo/vo_direct3d.c (revision 27979) +++ libvo/vo_direct3d.c (working copy) @@ -52,9 +52,10 @@ static struct global_priv { int is_paused; /**< 1 = Movie is paused, 0 = Movie is not paused */ - int is_cfg_finished; /**< Synchronization "semaphore". 1 when - instance of reconfigure_d3d is finished */ - + int is_panscan; /**< 1= Panscan enabled, 0 = Panscan disabled */ + int is_surface_locked; /**< 1 = The offscreen surface is locked, + 0 = it's not */ + D3DLOCKED_RECT locked_rect; /**< The locked Offscreen surface */ RECT fs_movie_rect; /**< Rect (upscaled) of the movie when displayed in fullscreen */ RECT fs_panscan_rect; /**< PanScan source surface cropping in @@ -139,7 +140,7 @@ priv->fs_panscan_rect.right = priv->src_width - border; } else { priv->fs_movie_rect.left = (vo_dwidth - scaled_width) / 2; - priv->fs_movie_rect.right = priv->fs_movie_rect.left + scaled_width; + priv->fs_movie_rect.right = priv->fs_movie_rect.left + scaled_width; } if (scaled_height > vo_dheight) { int border = priv->src_height * (scaled_height - vo_dheight) / scaled_height; @@ -148,7 +149,7 @@ priv->fs_panscan_rect.bottom = priv->src_height - border; } else { priv->fs_movie_rect.top = (vo_dheight - scaled_height) / 2; - priv->fs_movie_rect.bottom = priv->fs_movie_rect.top + scaled_height; + priv->fs_movie_rect.bottom = priv->fs_movie_rect.top + scaled_height; } mp_msg(MSGT_VO,MSGL_V, @@ -164,6 +165,11 @@ mp_msg(MSGT_VO,MSGL_V,"destroy_d3d_context called\r\n"); /* Let's destroy the old (if any) D3D Content */ + if (priv->is_surface_locked) { + IDirect3DSurface9_UnlockRect(priv->d3d_surface); + priv->is_surface_locked = 0; + } + if (priv->d3d_surface != NULL) { IDirect3DSurface9_Release (priv->d3d_surface); priv->d3d_surface = NULL; @@ -269,9 +275,6 @@ { mp_msg(MSGT_VO,MSGL_V,"uninit_d3d called\r\n"); - /* Block further calls to reconfigure_d3d(). */ - priv->is_cfg_finished = 0; - /* Destroy D3D Context inside the window. */ destroy_d3d_context(); @@ -288,41 +291,45 @@ */ static uint32_t render_d3d_frame(mp_image_t *mpi) { - D3DLOCKED_RECT locked_rect; /**< Offscreen surface we lock in order - to copy MPlayer's frame inside it.*/ - /* Uncomment when direct rendering is implemented. * if (mpi->flags & MP_IMGFLAG_DIRECT) ... */ + /* If the whole image is ready */ 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(priv->d3d_device))) { - mp_msg(MSGT_VO,MSGL_ERR,"BeginScene failed\n"); - return VO_ERROR; + /* If we're here, then we should lock the rect and copy a packed frame */ + if (!priv->is_surface_locked) { + if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, + &priv->locked_rect, NULL, 0))) { + mp_msg(MSGT_VO,MSGL_V,"Surface lock failure\n"); + return VO_FALSE; + } + priv->is_surface_locked = 1; /* Don't lock again */ } + memcpy_pic(priv->locked_rect.pBits, mpi->planes[0], mpi->stride[0], + mpi->height, priv->locked_rect.Pitch, mpi->stride[0]); - if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, - &locked_rect, NULL, 0))) { - mp_msg(MSGT_VO,MSGL_ERR,"Surface lock failure\n"); - return VO_ERROR; - } - - memcpy_pic(locked_rect.pBits, mpi->planes[0], mpi->stride[0], - mpi->height, locked_rect.Pitch, mpi->stride[0]); - +skip_upload: + /* This unlock is used for both slice_draw path and render_d3d_frame path. */ if (FAILED(IDirect3DSurface9_UnlockRect(priv->d3d_surface))) { mp_msg(MSGT_VO,MSGL_V,"Surface unlock failure\n"); return VO_ERROR; } + priv->is_surface_locked = 0; + + if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) { + mp_msg(MSGT_VO,MSGL_ERR,"BeginScene failed\n"); + return VO_ERROR; + } + if (FAILED(IDirect3DDevice9_StretchRect(priv->d3d_device, priv->d3d_surface, &priv->fs_panscan_rect, @@ -441,9 +448,6 @@ return -1; } - /* Allow the first call to reconfigure_d3d. */ - priv->is_cfg_finished = 1; - return 0; } @@ -527,14 +531,9 @@ return VO_ERROR; } - if (priv->is_cfg_finished) { - priv->is_cfg_finished = 0; - if (!reconfigure_d3d()) { - priv->is_cfg_finished = 1; - return VO_ERROR; - } - priv->is_cfg_finished = 1; - } + if (!reconfigure_d3d()) + return VO_ERROR; + return 0; /* Success */ } @@ -607,76 +606,52 @@ */ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y ) { - D3DLOCKED_RECT locked_rect; /**< 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 */ + char *my_src; /**< Pointer to the source image */ + char *dst; /**< Pointer to the destination image */ + int uv_stride; /**< Stride of the U/V planes */ - if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) { - mp_msg(MSGT_VO,MSGL_ERR,"BeginScene failed\n"); - return VO_ERROR; + /* Lock the offscreen surface if it's not already locked. */ + if (!priv->is_surface_locked) { + if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, + &priv->locked_rect, NULL, 0))) { + mp_msg(MSGT_VO,MSGL_V,"Surface lock failure\n"); + return VO_FALSE; + } + priv->is_surface_locked = 1; /* Don't lock again */ } - if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, - &locked_rect, NULL, 0))) { - mp_msg(MSGT_VO,MSGL_V,"Surface lock failure\n"); - return VO_FALSE; - } + uv_stride = priv->locked_rect.Pitch / 2; - UVstride = locked_rect.Pitch / 2; - /* Copy Y */ - Dst = locked_rect.pBits; - Dst = Dst + locked_rect.Pitch * y + x; - Src=src[0]; - memcpy_pic(Dst, Src, w, h, locked_rect.Pitch, stride[0]); + dst = priv->locked_rect.pBits; + dst = dst + priv->locked_rect.Pitch * y + x; + my_src=src[0]; + memcpy_pic(dst, my_src, w, h, priv->locked_rect.Pitch, stride[0]); w/=2;h/=2;x/=2;y/=2; /* Copy U */ - Dst = locked_rect.pBits; - Dst = Dst + locked_rect.Pitch * priv->src_height - + UVstride * y + x; + dst = priv->locked_rect.pBits; + dst = dst + priv->locked_rect.Pitch * priv->src_height + + uv_stride * y + x; if (priv->movie_src_fmt == MAKEFOURCC('Y','V','1','2')) - Src=src[2]; + my_src=src[2]; else - Src=src[1]; + my_src=src[1]; - memcpy_pic(Dst, Src, w, h, UVstride, stride[1]); + memcpy_pic(dst, my_src, w, h, uv_stride, stride[1]); /* Copy V */ - Dst = locked_rect.pBits; - Dst = Dst + locked_rect.Pitch * priv->src_height - + UVstride * (priv->src_height / 2) + UVstride * y + x; + dst = priv->locked_rect.pBits; + dst = dst + priv->locked_rect.Pitch * priv->src_height + + uv_stride * (priv->src_height / 2) + uv_stride * y + x; if (priv->movie_src_fmt == MAKEFOURCC('Y','V','1','2')) - Src=src[1]; + my_src=src[1]; else - Src=src[2]; + my_src=src[2]; - memcpy_pic(Dst, Src, w, h, UVstride, stride[2]); + memcpy_pic(dst, my_src, w, h, uv_stride, stride[2]); - if (FAILED(IDirect3DSurface9_UnlockRect(priv->d3d_surface))) { - mp_msg(MSGT_VO,MSGL_V,"Surface unlock failure\n"); - return VO_ERROR; - } - - if (FAILED(IDirect3DDevice9_StretchRect(priv->d3d_device, - priv->d3d_surface, - &priv->fs_panscan_rect, - priv->d3d_backbuf, - &priv->fs_movie_rect, - 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(priv->d3d_device))) { - mp_msg(MSGT_VO,MSGL_ERR,"EndScene failed\n"); - return VO_ERROR; - } - return 0; /* Success */ }