]> git.sesse.net Git - vlc/blobdiff - modules/video_output/msw/direct3d.c
better direct3d image quality
[vlc] / modules / video_output / msw / direct3d.c
index 6a9aa6a14b07e0d2906f1a9ed1e433d90c7edf5a..716b9318662ac6af6945768f28cf488495f5b98a 100644 (file)
@@ -39,7 +39,7 @@
 # include "config.h"
 #endif
 
-#include <vlc/vlc.h>
+#include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_interface.h>
 #include <vlc_playlist.h>
@@ -105,18 +105,18 @@ static int get_capability_for_osversion(void)
     return 50;
 }
 
-vlc_module_begin();
-    set_shortname( "Direct3D" );
-    set_category( CAT_VIDEO );
-    set_subcategory( SUBCAT_VIDEO_VOUT );
-    set_description( _("DirectX 3D video output") );
-    set_capability( "video output", get_capability_for_osversion() );
-    add_shortcut( "direct3d" );
-    set_callbacks( OpenVideo, CloseVideo );
+vlc_module_begin ()
+    set_shortname( "Direct3D" )
+    set_category( CAT_VIDEO )
+    set_subcategory( SUBCAT_VIDEO_VOUT )
+    set_description( N_("DirectX 3D video output") )
+    set_capability( "video output", get_capability_for_osversion() )
+    add_shortcut( "direct3d" )
+    set_callbacks( OpenVideo, CloseVideo )
 
     /* FIXME: Hack to avoid unregistering our window class */
-    linked_with_a_crap_library_which_uses_atexit( );
-vlc_module_end();
+    linked_with_a_crap_library_which_uses_atexit ()
+vlc_module_end ()
 
 #if 0 /* FIXME */
     /* check if we registered a window class because we need to
@@ -153,10 +153,8 @@ static int OpenVideo( vlc_object_t *p_this )
     /* Allocate structure */
     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
     if( p_vout->p_sys == NULL )
-    {
-        msg_Err( p_vout, "out of memory" );
         return VLC_ENOMEM;
-    }
+
     memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
 
     if( VLC_SUCCESS != Direct3DVoutCreate( p_vout ) )
@@ -205,14 +203,18 @@ static int OpenVideo( vlc_object_t *p_this )
     p_vout->p_sys->p_event =
         vlc_object_create( p_vout, sizeof(event_thread_t) );
     p_vout->p_sys->p_event->p_vout = p_vout;
+    p_vout->p_sys->p_event->window_ready = CreateEvent( NULL, TRUE, FALSE, NULL );
     if( vlc_thread_create( p_vout->p_sys->p_event, "Vout Events Thread",
-                           EventThread, 0, 1 ) )
+                           EventThread, 0 ) )
     {
         msg_Err( p_vout, "cannot create Vout EventThread" );
+        CloseHandle( p_vout->p_sys->p_event->window_ready );
         vlc_object_release( p_vout->p_sys->p_event );
         p_vout->p_sys->p_event = NULL;
         goto error;
     }
+    WaitForSingleObject( p_vout->p_sys->p_event->window_ready, INFINITE );
+    CloseHandle( p_vout->p_sys->p_event->window_ready );
 
     if( p_vout->p_sys->p_event->b_error )
     {
@@ -270,6 +272,14 @@ static void CloseVideo( vlc_object_t *p_this )
 
     Direct3DVoutRelease( p_vout );
 
+    if( p_vout->b_fullscreen )
+    {
+        msg_Dbg( p_vout, "Quitting fullscreen" );
+        Win32ToggleFullscreen( p_vout );
+        /* Force fullscreen in the core for the next video */
+        var_SetBool( p_vout, "fullscreen", true );
+    }
+
     if( p_vout->p_sys->p_event )
     {
         vlc_object_detach( p_vout->p_sys->p_event );
@@ -304,11 +314,8 @@ static void CloseVideo( vlc_object_t *p_this )
             p_vout->p_sys->i_spi_screensavetimeout, NULL, 0);
     }
 
-    if( p_vout->p_sys )
-    {
-        free( p_vout->p_sys );
-        p_vout->p_sys = NULL;
-    }
+    free( p_vout->p_sys );
+    p_vout->p_sys = NULL;
 }
 
 /*****************************************************************************
@@ -531,7 +538,7 @@ static int Manage( vout_thread_t *p_vout )
     }
 
     /* Check if the event thread is still running */
-    if( p_vout->p_sys->p_event->b_die )
+    if( !vlc_object_alive (p_vout->p_sys->p_event) )
     {
         return VLC_EGENERIC; /* exit */
     }
@@ -736,7 +743,7 @@ static void Direct3DVoutClose( vout_thread_t *p_vout )
        IDirect3DDevice9_Release(p_vout->p_sys->p_d3ddev);
        p_vout->p_sys->p_d3ddev = NULL;
     }
+
     p_vout->p_sys->hmonitor = NULL;
 }
 
@@ -1034,7 +1041,7 @@ static int Direct3DVoutCreatePictures( vout_thread_t *p_vout, size_t i_num_pics
 
         /* fill surface with black color */
         IDirect3DDevice9_ColorFill(p_d3ddev, p_d3dsurf, NULL, D3DCOLOR_ARGB(0xFF, 0, 0, 0) );
+
         /* assign surface to internal structure */
         p_pic->p_sys = (void *)p_d3dsurf;
 
@@ -1380,41 +1387,43 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
     }
 
     /* Setup vertices */
-    f_width  = (float)(p_vout->output.i_width) + 1;
-    f_height = (float)(p_vout->output.i_height) + 1;
+    f_width  = (float)(p_vout->output.i_width);
+    f_height = (float)(p_vout->output.i_height);
 
-    p_vertices[0].x       = 0.0f;       // left
-    p_vertices[0].y       = 0.0f;       // top
+    /* -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/ */
+    p_vertices[0].x       = -0.5f;       // left
+    p_vertices[0].y       = -0.5f;       // top
     p_vertices[0].z       = 0.0f;
     p_vertices[0].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
     p_vertices[0].rhw     = 1.0f;
     p_vertices[0].tu      = 0.0f;
     p_vertices[0].tv      = 0.0f;
-    p_vertices[1].x       = f_width;    // right
-    p_vertices[1].y       = 0.0f;       // top
+
+    p_vertices[1].x       = f_width - 0.5f;    // right
+    p_vertices[1].y       = -0.5f;       // top
     p_vertices[1].z       = 0.0f;
     p_vertices[1].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
     p_vertices[1].rhw     = 1.0f;
     p_vertices[1].tu      = 1.0f;
     p_vertices[1].tv      = 0.0f;
-    p_vertices[2].x       = f_width;    // right
-    p_vertices[2].y       = f_height;   // bottom
+
+    p_vertices[2].x       = f_width - 0.5f;    // right
+    p_vertices[2].y       = f_height - 0.5f;   // bottom
     p_vertices[2].z       = 0.0f;
     p_vertices[2].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
     p_vertices[2].rhw     = 1.0f;
     p_vertices[2].tu      = 1.0f;
     p_vertices[2].tv      = 1.0f;
-    p_vertices[3].x       = 0.0f;       // left
-    p_vertices[3].y       = f_height;   // bottom
+
+    p_vertices[3].x       = -0.5f;       // left
+    p_vertices[3].y       = f_height - 0.5f;   // bottom
     p_vertices[3].z       = 0.0f;
     p_vertices[3].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
     p_vertices[3].rhw     = 1.0f;
     p_vertices[3].tu      = 0.0f;
     p_vertices[3].tv      = 1.0f;
+
     hr= IDirect3DVertexBuffer9_Unlock(p_d3dvtc);
     if( FAILED(hr) )
     {
@@ -1450,16 +1459,8 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
         IDirect3DDevice9_EndScene(p_d3ddev);
         return;
     }
-    // we use FVF instead of vertex shader
-    hr = IDirect3DDevice9_SetVertexShader(p_d3ddev, NULL);
-    if( FAILED(hr) )
-    {
-        msg_Dbg( p_vout, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
-        IDirect3DDevice9_EndScene(p_d3ddev);
-        return;
-    }
 
+    // we use FVF instead of vertex shader
     hr = IDirect3DDevice9_SetFVF(p_d3ddev, D3DFVF_CUSTOMVERTEX);
     if( FAILED(hr) )
     {