Commit 8d8844ad authored by Laurent Aimar's avatar Laurent Aimar

Fixed resize quality issue with direct3d vout (especially win7).

 It seems that depending on your driver, the resize done by
IDirect3DDevice9::Present can be of very low quality. The resize is now
done by IDirect3DDevice9::StretchRect.
parent 4bdf4fd0
...@@ -340,6 +340,12 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force ) ...@@ -340,6 +340,12 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force )
SWP_NOCOPYBITS|SWP_NOZORDER|SWP_ASYNCWINDOWPOS ); SWP_NOCOPYBITS|SWP_NOZORDER|SWP_ASYNCWINDOWPOS );
/* Destination image position and dimensions */ /* Destination image position and dimensions */
#if defined(MODULE_NAME_IS_direct3d)
rect_dest.left = 0;
rect_dest.right = i_width;
rect_dest.top = 0;
rect_dest.bottom = i_height;
#else
rect_dest.left = point.x + i_x; rect_dest.left = point.x + i_x;
rect_dest.right = rect_dest.left + i_width; rect_dest.right = rect_dest.left + i_width;
rect_dest.top = point.y + i_y; rect_dest.top = point.y + i_y;
...@@ -359,9 +365,14 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force ) ...@@ -359,9 +365,14 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force )
p_vout->p_sys->i_align_dest_size / 2 ) & p_vout->p_sys->i_align_dest_size / 2 ) &
~p_vout->p_sys->i_align_dest_size) + rect_dest.left; ~p_vout->p_sys->i_align_dest_size) + rect_dest.left;
} }
#endif
#endif
#if defined(MODULE_NAME_IS_directx) || defined(MODULE_NAME_IS_direct3d)
/* UpdateOverlay directdraw function doesn't automatically clip to the /* UpdateOverlay directdraw function doesn't automatically clip to the
* display size so we need to do it otherwise it will fail */ * display size so we need to do it otherwise it will fail
* It is also needed for d3d to avoid exceding our surface size */
/* Clip the destination window */ /* Clip the destination window */
if( !IntersectRect( &rect_dest_clipped, &rect_dest, if( !IntersectRect( &rect_dest_clipped, &rect_dest,
...@@ -378,7 +389,7 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force ) ...@@ -378,7 +389,7 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force )
rect_dest_clipped.right, rect_dest_clipped.bottom ); rect_dest_clipped.right, rect_dest_clipped.bottom );
#endif #endif
#else /* MODULE_NAME_IS_directx */ #else
/* AFAIK, there are no clipping constraints in Direct3D, OpenGL and GDI */ /* AFAIK, there are no clipping constraints in Direct3D, OpenGL and GDI */
rect_dest_clipped = rect_dest; rect_dest_clipped = rect_dest;
...@@ -430,6 +441,12 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force ) ...@@ -430,6 +441,12 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force )
p_vout->p_sys->i_align_src_size / 2 ) & p_vout->p_sys->i_align_src_size / 2 ) &
~p_vout->p_sys->i_align_src_size) + rect_src_clipped.left; ~p_vout->p_sys->i_align_src_size) + rect_src_clipped.left;
} }
#elif defined(MODULE_NAME_IS_direct3d)
/* Needed at least with YUV content */
rect_src_clipped.left &= ~1;
rect_src_clipped.right &= ~1;
rect_src_clipped.top &= ~1;
rect_src_clipped.bottom &= ~1;
#endif #endif
#ifndef NDEBUG #ifndef NDEBUG
......
...@@ -383,10 +383,11 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -383,10 +383,11 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
LPDIRECT3DDEVICE9 p_d3ddev = p_vout->p_sys->p_d3ddev; LPDIRECT3DDEVICE9 p_d3ddev = p_vout->p_sys->p_d3ddev;
// Present the back buffer contents to the display // Present the back buffer contents to the display
// stretching and filtering happens here // No stretching should happen here !
HRESULT hr = IDirect3DDevice9_Present(p_d3ddev, RECT src = p_vout->p_sys->rect_dest_clipped;
&(p_vout->p_sys->rect_src_clipped), RECT dst = p_vout->p_sys->rect_dest_clipped;
NULL, NULL, NULL); HRESULT hr = IDirect3DDevice9_Present(p_d3ddev, &src, &dst,
NULL, NULL);
if( FAILED(hr) ) if( FAILED(hr) )
msg_Dbg( p_vout, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr); msg_Dbg( p_vout, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
} }
...@@ -489,7 +490,7 @@ static void Direct3DVoutRelease( vout_thread_t *p_vout ) ...@@ -489,7 +490,7 @@ static void Direct3DVoutRelease( vout_thread_t *p_vout )
} }
} }
static int Direct3DFillPresentationParameters(vout_thread_t *p_vout, D3DPRESENT_PARAMETERS *d3dpp) static int Direct3DFillPresentationParameters(vout_thread_t *p_vout)
{ {
LPDIRECT3D9 p_d3dobj = p_vout->p_sys->p_d3dobj; LPDIRECT3D9 p_d3dobj = p_vout->p_sys->p_d3dobj;
D3DDISPLAYMODE d3ddm; D3DDISPLAYMODE d3ddm;
...@@ -506,16 +507,14 @@ static int Direct3DFillPresentationParameters(vout_thread_t *p_vout, D3DPRESENT_ ...@@ -506,16 +507,14 @@ static int Direct3DFillPresentationParameters(vout_thread_t *p_vout, D3DPRESENT_
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* keep a copy of current desktop format */
p_vout->p_sys->bbFormat = d3ddm.Format;
/* Set up the structure used to create the D3DDevice. */ /* Set up the structure used to create the D3DDevice. */
D3DPRESENT_PARAMETERS *d3dpp = &p_vout->p_sys->d3dpp;
ZeroMemory( d3dpp, sizeof(D3DPRESENT_PARAMETERS) ); ZeroMemory( d3dpp, sizeof(D3DPRESENT_PARAMETERS) );
d3dpp->Flags = D3DPRESENTFLAG_VIDEO; d3dpp->Flags = D3DPRESENTFLAG_VIDEO;
d3dpp->Windowed = TRUE; d3dpp->Windowed = TRUE;
d3dpp->hDeviceWindow = p_vout->p_sys->hvideownd; d3dpp->hDeviceWindow = p_vout->p_sys->hvideownd;
d3dpp->BackBufferWidth = p_vout->output.i_width; d3dpp->BackBufferWidth = d3ddm.Width;
d3dpp->BackBufferHeight = p_vout->output.i_height; d3dpp->BackBufferHeight = d3ddm.Height;
d3dpp->SwapEffect = D3DSWAPEFFECT_COPY; d3dpp->SwapEffect = D3DSWAPEFFECT_COPY;
d3dpp->MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp->MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; d3dpp->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
...@@ -523,6 +522,12 @@ static int Direct3DFillPresentationParameters(vout_thread_t *p_vout, D3DPRESENT_ ...@@ -523,6 +522,12 @@ static int Direct3DFillPresentationParameters(vout_thread_t *p_vout, D3DPRESENT_
d3dpp->BackBufferCount = 1; d3dpp->BackBufferCount = 1;
d3dpp->EnableAutoDepthStencil = FALSE; d3dpp->EnableAutoDepthStencil = FALSE;
RECT *display = &p_vout->p_sys->rect_display;
display->left = 0;
display->top = 0;
display->right = d3dpp->BackBufferWidth;
display->bottom = d3dpp->BackBufferHeight;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -537,10 +542,9 @@ static int Direct3DVoutOpen( vout_thread_t *p_vout ) ...@@ -537,10 +542,9 @@ static int Direct3DVoutOpen( vout_thread_t *p_vout )
{ {
LPDIRECT3D9 p_d3dobj = p_vout->p_sys->p_d3dobj; LPDIRECT3D9 p_d3dobj = p_vout->p_sys->p_d3dobj;
LPDIRECT3DDEVICE9 p_d3ddev; LPDIRECT3DDEVICE9 p_d3ddev;
D3DPRESENT_PARAMETERS d3dpp;
HRESULT hr; HRESULT hr;
if( VLC_SUCCESS != Direct3DFillPresentationParameters(p_vout, &d3dpp) ) if( VLC_SUCCESS != Direct3DFillPresentationParameters(p_vout) )
return VLC_EGENERIC; return VLC_EGENERIC;
// Create the D3DDevice // Create the D3DDevice
...@@ -548,7 +552,7 @@ static int Direct3DVoutOpen( vout_thread_t *p_vout ) ...@@ -548,7 +552,7 @@ static int Direct3DVoutOpen( vout_thread_t *p_vout )
D3DDEVTYPE_HAL, p_vout->p_sys->hvideownd, D3DDEVTYPE_HAL, p_vout->p_sys->hvideownd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING| D3DCREATE_SOFTWARE_VERTEXPROCESSING|
D3DCREATE_MULTITHREADED, D3DCREATE_MULTITHREADED,
&d3dpp, &p_d3ddev ); &p_vout->p_sys->d3dpp, &p_d3ddev );
if( FAILED(hr) ) if( FAILED(hr) )
{ {
msg_Err(p_vout, "Could not create the D3D device! (hr=0x%lX)", hr); msg_Err(p_vout, "Could not create the D3D device! (hr=0x%lX)", hr);
...@@ -583,17 +587,16 @@ static void Direct3DVoutClose( vout_thread_t *p_vout ) ...@@ -583,17 +587,16 @@ static void Direct3DVoutClose( vout_thread_t *p_vout )
static int Direct3DVoutResetDevice( vout_thread_t *p_vout ) static int Direct3DVoutResetDevice( vout_thread_t *p_vout )
{ {
LPDIRECT3DDEVICE9 p_d3ddev = p_vout->p_sys->p_d3ddev; LPDIRECT3DDEVICE9 p_d3ddev = p_vout->p_sys->p_d3ddev;
D3DPRESENT_PARAMETERS d3dpp;
HRESULT hr; HRESULT hr;
if( VLC_SUCCESS != Direct3DFillPresentationParameters(p_vout, &d3dpp) ) if( VLC_SUCCESS != Direct3DFillPresentationParameters(p_vout) )
return VLC_EGENERIC; return VLC_EGENERIC;
// release all D3D objects // release all D3D objects
Direct3DVoutReleaseScene( p_vout ); Direct3DVoutReleaseScene( p_vout );
Direct3DVoutReleasePictures( p_vout ); Direct3DVoutReleasePictures( p_vout );
hr = IDirect3DDevice9_Reset(p_d3ddev, &d3dpp); hr = IDirect3DDevice9_Reset(p_d3ddev, &p_vout->p_sys->d3dpp);
if( SUCCEEDED(hr) ) if( SUCCEEDED(hr) )
{ {
// re-create them // re-create them
...@@ -725,7 +728,7 @@ static int Direct3DVoutCreatePictures( vout_thread_t *p_vout, size_t i_num_pics ...@@ -725,7 +728,7 @@ static int Direct3DVoutCreatePictures( vout_thread_t *p_vout, size_t i_num_pics
** the requested chroma which is usable by the hardware in an offscreen surface, as they ** the requested chroma which is usable by the hardware in an offscreen surface, as they
** typically support more formats than textures ** typically support more formats than textures
*/ */
const d3d_format_t *p_format = Direct3DVoutFindFormat(p_vout, i_chroma, p_vout->p_sys->bbFormat); const d3d_format_t *p_format = Direct3DVoutFindFormat(p_vout, i_chroma, p_vout->p_sys->d3dpp.BackBufferFormat);
if( !p_format ) if( !p_format )
{ {
msg_Err(p_vout, "surface pixel format is not supported."); msg_Err(p_vout, "surface pixel format is not supported.");
...@@ -968,11 +971,11 @@ static int Direct3DVoutCreateScene( vout_thread_t *p_vout ) ...@@ -968,11 +971,11 @@ static int Direct3DVoutCreateScene( vout_thread_t *p_vout )
** which would usually be a RGB format ** which would usually be a RGB format
*/ */
hr = IDirect3DDevice9_CreateTexture(p_d3ddev, hr = IDirect3DDevice9_CreateTexture(p_d3ddev,
p_vout->render.i_width, p_vout->p_sys->d3dpp.BackBufferWidth,
p_vout->render.i_height, p_vout->p_sys->d3dpp.BackBufferHeight,
1, 1,
D3DUSAGE_RENDERTARGET, D3DUSAGE_RENDERTARGET,
p_vout->p_sys->bbFormat, p_vout->p_sys->d3dpp.BackBufferFormat,
D3DPOOL_DEFAULT, D3DPOOL_DEFAULT,
&p_d3dtex, &p_d3dtex,
NULL); NULL);
...@@ -1126,8 +1129,12 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -1126,8 +1129,12 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
return; return;
} }
/* Copy picture surface into texture surface, color space conversion happens here */ /* Copy picture surface into texture surface
hr = IDirect3DDevice9_StretchRect(p_d3ddev, p_d3dsrc, NULL, p_d3ddest, NULL, D3DTEXF_NONE); * color space conversion and scaling happen here */
RECT src = p_vout->p_sys->rect_src_clipped;
RECT dst = p_vout->p_sys->rect_dest_clipped;
hr = IDirect3DDevice9_StretchRect(p_d3ddev, p_d3dsrc, &src, p_d3ddest, &dst, D3DTEXF_LINEAR);
IDirect3DSurface9_Release(p_d3ddest); IDirect3DSurface9_Release(p_d3ddest);
if( FAILED(hr) ) if( FAILED(hr) )
{ {
...@@ -1144,8 +1151,8 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -1144,8 +1151,8 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
} }
/* Setup vertices */ /* Setup vertices */
f_width = (float)(p_vout->output.i_width); f_width = (float)p_vout->p_sys->d3dpp.BackBufferWidth;
f_height = (float)(p_vout->output.i_height); f_height = (float)p_vout->p_sys->d3dpp.BackBufferHeight;
/* -0.5f is a "feature" of DirectX and it seems to apply to Direct3d also */ /* -0.5f is a "feature" of DirectX and it seems to apply to Direct3d also */
/* http://www.sjbrown.co.uk/2003/05/01/fix-directx-rasterisation/ */ /* http://www.sjbrown.co.uk/2003/05/01/fix-directx-rasterisation/ */
......
...@@ -156,7 +156,7 @@ struct vout_sys_t ...@@ -156,7 +156,7 @@ struct vout_sys_t
HINSTANCE hd3d9_dll; /* handle of the opened d3d9 dll */ HINSTANCE hd3d9_dll; /* handle of the opened d3d9 dll */
LPDIRECT3D9 p_d3dobj; LPDIRECT3D9 p_d3dobj;
LPDIRECT3DDEVICE9 p_d3ddev; LPDIRECT3DDEVICE9 p_d3ddev;
D3DFORMAT bbFormat; D3DPRESENT_PARAMETERS d3dpp;
// scene objects // scene objects
LPDIRECT3DTEXTURE9 p_d3dtex; LPDIRECT3DTEXTURE9 p_d3dtex;
LPDIRECT3DVERTEXBUFFER9 p_d3dvtc; LPDIRECT3DVERTEXBUFFER9 p_d3dvtc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment