[vlc-devel] commit: Fixed resize quality issue with direct3d vout (especially win7). ( Laurent Aimar )

git version control git at videolan.org
Wed Oct 21 20:07:44 CEST 2009


vlc | branch: 1.0-bugfix | Laurent Aimar <fenrir at videolan.org> | Mon Oct 19 20:11:25 2009 +0200| [321d5e3e56e11ef0013cdac800de658fbe78094f] | committer: 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.

(cherry picked from commit 8d8844adcd8e44d58291a2e8d025ca3ca3c89067)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=321d5e3e56e11ef0013cdac800de658fbe78094f
---

 modules/video_output/msw/direct3d.c |   55 +++++++++++++++++++---------------
 modules/video_output/msw/events.c   |   21 ++++++++++++-
 modules/video_output/msw/vout.h     |    2 +-
 3 files changed, 51 insertions(+), 27 deletions(-)

diff --git a/modules/video_output/msw/direct3d.c b/modules/video_output/msw/direct3d.c
index 6435154..e2040af 100644
--- a/modules/video_output/msw/direct3d.c
+++ b/modules/video_output/msw/direct3d.c
@@ -584,10 +584,11 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
 {
     LPDIRECT3DDEVICE9       p_d3ddev = p_vout->p_sys->p_d3ddev;
     // Present the back buffer contents to the display
-    // stretching and filtering happens here
-    HRESULT hr = IDirect3DDevice9_Present(p_d3ddev,
-                    &(p_vout->p_sys->rect_src_clipped),
-                    NULL, NULL, NULL);
+    // No stretching should happen here !
+    RECT src = p_vout->p_sys->rect_dest_clipped;
+    RECT dst = p_vout->p_sys->rect_dest_clipped;
+    HRESULT hr = IDirect3DDevice9_Present(p_d3ddev, &src, &dst,
+                                          NULL, NULL);
     if( FAILED(hr) )
         msg_Dbg( p_vout, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
 }
@@ -690,7 +691,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;
     D3DDISPLAYMODE d3ddm;
@@ -707,16 +708,14 @@ static int Direct3DFillPresentationParameters(vout_thread_t *p_vout, D3DPRESENT_
        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. */
+    D3DPRESENT_PARAMETERS *d3dpp = &p_vout->p_sys->d3dpp;
     ZeroMemory( d3dpp, sizeof(D3DPRESENT_PARAMETERS) );
     d3dpp->Flags                  = D3DPRESENTFLAG_VIDEO;
     d3dpp->Windowed               = TRUE;
     d3dpp->hDeviceWindow          = p_vout->p_sys->hvideownd;
-    d3dpp->BackBufferWidth        = p_vout->output.i_width;
-    d3dpp->BackBufferHeight       = p_vout->output.i_height;
+    d3dpp->BackBufferWidth        = d3ddm.Width;
+    d3dpp->BackBufferHeight       = d3ddm.Height;
     d3dpp->SwapEffect             = D3DSWAPEFFECT_COPY;
     d3dpp->MultiSampleType        = D3DMULTISAMPLE_NONE;
     d3dpp->PresentationInterval   = D3DPRESENT_INTERVAL_DEFAULT;
@@ -724,6 +723,12 @@ static int Direct3DFillPresentationParameters(vout_thread_t *p_vout, D3DPRESENT_
     d3dpp->BackBufferCount        = 1;
     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;
 }
 
@@ -738,10 +743,9 @@ static int Direct3DVoutOpen( vout_thread_t *p_vout )
 {
     LPDIRECT3D9 p_d3dobj = p_vout->p_sys->p_d3dobj;
     LPDIRECT3DDEVICE9 p_d3ddev;
-    D3DPRESENT_PARAMETERS d3dpp;
     HRESULT hr;
 
-    if( VLC_SUCCESS != Direct3DFillPresentationParameters(p_vout, &d3dpp) )
+    if( VLC_SUCCESS != Direct3DFillPresentationParameters(p_vout) )
         return VLC_EGENERIC;
 
     // Create the D3DDevice
@@ -749,7 +753,7 @@ static int Direct3DVoutOpen( vout_thread_t *p_vout )
                                  D3DDEVTYPE_HAL, p_vout->p_sys->hvideownd,
                                  D3DCREATE_SOFTWARE_VERTEXPROCESSING|
                                  D3DCREATE_MULTITHREADED,
-                                 &d3dpp, &p_d3ddev );
+                                 &p_vout->p_sys->d3dpp, &p_d3ddev );
     if( FAILED(hr) )
     {
        msg_Err(p_vout, "Could not create the D3D device! (hr=0x%lX)", hr);
@@ -784,17 +788,16 @@ static void Direct3DVoutClose( vout_thread_t *p_vout )
 static int Direct3DVoutResetDevice( vout_thread_t *p_vout )
 {
     LPDIRECT3DDEVICE9       p_d3ddev = p_vout->p_sys->p_d3ddev;
-    D3DPRESENT_PARAMETERS   d3dpp;
     HRESULT hr;
 
-    if( VLC_SUCCESS != Direct3DFillPresentationParameters(p_vout, &d3dpp) )
+    if( VLC_SUCCESS != Direct3DFillPresentationParameters(p_vout) )
         return VLC_EGENERIC;
 
     // release all D3D objects
     Direct3DVoutReleaseScene( p_vout );
     Direct3DVoutReleasePictures( p_vout );
 
-    hr = IDirect3DDevice9_Reset(p_d3ddev, &d3dpp);
+    hr = IDirect3DDevice9_Reset(p_d3ddev, &p_vout->p_sys->d3dpp);
     if( SUCCEEDED(hr) )
     {
         // re-create them
@@ -1041,7 +1044,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
     ** typically support more formats than textures
     */
-    format = Direct3DVoutFindFormat(p_vout, i_chroma, p_vout->p_sys->bbFormat);
+    format = Direct3DVoutFindFormat(p_vout, i_chroma, p_vout->p_sys->d3dpp.BackBufferFormat);
     if( VLC_SUCCESS != Direct3DVoutSetOutputFormat(p_vout, format) )
     {
         msg_Err(p_vout, "surface pixel format is not supported.");
@@ -1239,11 +1242,11 @@ static int Direct3DVoutCreateScene( vout_thread_t *p_vout )
     ** which would usually be a RGB format
     */
     hr = IDirect3DDevice9_CreateTexture(p_d3ddev,
-            p_vout->render.i_width,
-            p_vout->render.i_height,
+            p_vout->p_sys->d3dpp.BackBufferWidth,
+            p_vout->p_sys->d3dpp.BackBufferHeight,
             1,
             D3DUSAGE_RENDERTARGET,
-            p_vout->p_sys->bbFormat,
+            p_vout->p_sys->d3dpp.BackBufferFormat,
             D3DPOOL_DEFAULT,
             &p_d3dtex,
             NULL);
@@ -1398,8 +1401,12 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
         return;
     }
 
-    /* Copy picture surface into texture surface, color space conversion happens here */
-    hr = IDirect3DDevice9_StretchRect(p_d3ddev, p_d3dsrc, NULL, p_d3ddest, NULL, D3DTEXF_NONE);
+    /* Copy picture surface into texture surface
+     * 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);
     if( FAILED(hr) )
     {
@@ -1416,8 +1423,8 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
     }
 
     /* Setup vertices */
-    f_width  = (float)(p_vout->output.i_width);
-    f_height = (float)(p_vout->output.i_height);
+    f_width  = (float)p_vout->p_sys->d3dpp.BackBufferWidth;
+    f_height = (float)p_vout->p_sys->d3dpp.BackBufferHeight;
 
     /* -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/ */
diff --git a/modules/video_output/msw/events.c b/modules/video_output/msw/events.c
index a35bdee..53760a3 100644
--- a/modules/video_output/msw/events.c
+++ b/modules/video_output/msw/events.c
@@ -660,6 +660,12 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force )
                       SWP_NOCOPYBITS|SWP_NOZORDER|SWP_ASYNCWINDOWPOS );
 
     /* 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.right = rect_dest.left + i_width;
     rect_dest.top = point.y + i_y;
@@ -679,9 +685,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) + 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
-     * 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 */
     if( !IntersectRect( &rect_dest_clipped, &rect_dest,
@@ -698,7 +709,7 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force )
                      rect_dest_clipped.right, rect_dest_clipped.bottom );
 #endif
 
-#else /* MODULE_NAME_IS_vout_directx */
+#else
 
     /* AFAIK, there are no clipping constraints in Direct3D, OpenGL and GDI */
     rect_dest_clipped = rect_dest;
@@ -750,6 +761,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) + 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
 
 #if 0
diff --git a/modules/video_output/msw/vout.h b/modules/video_output/msw/vout.h
index b2b1f82..0bf8b6e 100644
--- a/modules/video_output/msw/vout.h
+++ b/modules/video_output/msw/vout.h
@@ -172,7 +172,7 @@ struct vout_sys_t
     HINSTANCE               hd3d9_dll;       /* handle of the opened d3d9 dll */
     LPDIRECT3D9             p_d3dobj;
     LPDIRECT3DDEVICE9       p_d3ddev;
-    D3DFORMAT               bbFormat;
+    D3DPRESENT_PARAMETERS   d3dpp;
     // scene objects
     LPDIRECT3DTEXTURE9      p_d3dtex;
     LPDIRECT3DVERTEXBUFFER9 p_d3dvtc;




More information about the vlc-devel mailing list