/*****************************************************************************
* direct3d.c: Windows Direct3D video output module
*****************************************************************************
- * Copyright (C) 2006 the VideoLAN team
+ * Copyright (C) 2006-2009 the VideoLAN team
*$Id$
*
* Authors: Damien Fouilleul <damienf@videolan.org>
# include "config.h"
#endif
-#include <vlc/vlc.h>
+#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_interface.h>
#include <vlc_playlist.h>
static void Direct3DVoutReleaseScene ( vout_thread_t * );
static void Direct3DVoutRenderScene ( vout_thread_t *, picture_t * );
+static int DesktopCallback( vlc_object_t *p_this, char const *psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval,
+ void *p_data );
+
/*****************************************************************************
* Module descriptor
*****************************************************************************/
-static bool _got_vista_or_above;
-
-static int get_capability_for_osversion(void)
+static bool IsVistaOrAbove(void)
{
OSVERSIONINFO winVer;
winVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if( winVer.dwMajorVersion > 5 )
{
/* Windows Vista or above, make this module the default */
- _got_vista_or_above = true;
- return 150;
+ return true;
}
}
/* Windows XP or lower, make sure this module isn't the default */
- _got_vista_or_above = false;
- return 50;
+ return false;
+}
+
+static int OpenVideoXP( vlc_object_t *obj )
+{
+ return IsVistaOrAbove() ? VLC_EGENERIC : OpenVideo( obj );
+}
+
+static int OpenVideoVista( vlc_object_t *obj )
+{
+ return IsVistaOrAbove() ? OpenVideo( obj ) : VLC_EGENERIC;
}
-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 );
+#define DESKTOP_TEXT N_("Enable desktop mode ")
+#define DESKTOP_LONGTEXT N_( \
+ "The desktop mode allows you to display the video on the desktop." )
+
+vlc_module_begin ()
+ set_shortname( "Direct3D" )
+ set_category( CAT_VIDEO )
+ set_subcategory( SUBCAT_VIDEO_VOUT )
+
+ add_bool( "direct3d-desktop", false, NULL, DESKTOP_TEXT, DESKTOP_LONGTEXT,
+ true )
+
+ set_description( N_("DirectX 3D video output") )
+ set_capability( "video output", 50 )
+ add_shortcut( "direct3d" )
+ set_callbacks( OpenVideoXP, 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 ()
+
+ add_submodule()
+ set_capability( "video output", 150 )
+ add_shortcut( "direct3d" )
+ set_callbacks( OpenVideoVista, CloseVideo )
+vlc_module_end ()
#if 0 /* FIXME */
/* check if we registered a window class because we need to
*****************************************************************************/
static int OpenVideo( vlc_object_t *p_this )
{
- vout_thread_t * p_vout = (vout_thread_t *)p_this;
vlc_value_t val;
+ vout_thread_t * p_vout = (vout_thread_t *)p_this;
/* Allocate structure */
- p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+ p_vout->p_sys = calloc( 1, sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
return VLC_ENOMEM;
- memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
if( VLC_SUCCESS != Direct3DVoutCreate( p_vout ) )
{
msg_Err( p_vout, "Direct3D could not be initialized !");
- goto error;
+ Direct3DVoutRelease( p_vout );
+ free( p_vout->p_sys );
+ return VLC_EGENERIC;
}
/* Initialisations */
p_vout->pf_manage = Manage;
p_vout->pf_render = Direct3DVoutRenderScene;
p_vout->pf_display = FirstDisplay;
+ p_vout->pf_control = Control;
- p_vout->p_sys->hwnd = p_vout->p_sys->hvideownd = NULL;
- p_vout->p_sys->hparent = p_vout->p_sys->hfswnd = NULL;
- p_vout->p_sys->i_changes = 0;
- vlc_mutex_init( &p_vout->p_sys->lock );
- SetRectEmpty( &p_vout->p_sys->rect_display );
- SetRectEmpty( &p_vout->p_sys->rect_parent );
+ if( CommonInit( p_vout ) )
+ goto error;
+ p_vout->p_sys->b_desktop = false;
var_Create( p_vout, "directx-hw-yuv", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_vout, "directx-device", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
- p_vout->p_sys->b_cursor_hidden = 0;
- p_vout->p_sys->i_lastmoved = mdate();
- p_vout->p_sys->i_mouse_hide_timeout =
- var_GetInteger(p_vout, "mouse-hide-timeout") * 1000;
-
- var_Create( p_vout, "video-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
- var_Create( p_vout, "disable-screensaver", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-
- /* Set main window's size */
- p_vout->p_sys->i_window_width = p_vout->i_window_width;
- p_vout->p_sys->i_window_height = p_vout->i_window_height;
-
- /* Create the Vout EventThread, this thread is created by us to isolate
- * the Win32 PeekMessage function calls. We want to do this because
- * Windows can stay blocked inside this call for a long time, and when
- * this happens it thus blocks vlc's video_output thread.
- * Vout EventThread will take care of the creation of the video
- * window (because PeekMessage has to be called from the same thread which
- * created the window). */
- msg_Dbg( p_vout, "creating Vout EventThread" );
- 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;
- if( vlc_thread_create( p_vout->p_sys->p_event, "Vout Events Thread",
- EventThread, 0, 1 ) )
- {
- msg_Err( p_vout, "cannot create Vout EventThread" );
- vlc_object_release( p_vout->p_sys->p_event );
- p_vout->p_sys->p_event = NULL;
- goto error;
- }
-
- if( p_vout->p_sys->p_event->b_error )
- {
- msg_Err( p_vout, "Vout EventThread failed" );
- goto error;
- }
-
- vlc_object_attach( p_vout->p_sys->p_event, p_vout );
-
- msg_Dbg( p_vout, "Vout EventThread running" );
-
- /* Variable to indicate if the window should be on top of others */
/* Trigger a callback right now */
- var_Get( p_vout, "video-on-top", &val );
- var_Set( p_vout, "video-on-top", val );
-
- /* disable screensaver by temporarily changing system settings */
- p_vout->p_sys->i_spi_lowpowertimeout = 0;
- p_vout->p_sys->i_spi_powerofftimeout = 0;
- p_vout->p_sys->i_spi_screensavetimeout = 0;
- var_Get( p_vout, "disable-screensaver", &val);
- if( val.b_bool ) {
- msg_Dbg(p_vout, "disabling screen saver");
- SystemParametersInfo(SPI_GETLOWPOWERTIMEOUT,
- 0, &(p_vout->p_sys->i_spi_lowpowertimeout), 0);
- if( 0 != p_vout->p_sys->i_spi_lowpowertimeout ) {
- SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT, 0, NULL, 0);
- }
- SystemParametersInfo(SPI_GETPOWEROFFTIMEOUT, 0,
- &(p_vout->p_sys->i_spi_powerofftimeout), 0);
- if( 0 != p_vout->p_sys->i_spi_powerofftimeout ) {
- SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, 0, NULL, 0);
- }
- SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0,
- &(p_vout->p_sys->i_spi_screensavetimeout), 0);
- if( 0 != p_vout->p_sys->i_spi_screensavetimeout ) {
- SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, 0, NULL, 0);
- }
- }
+ var_Create( p_vout, "direct3d-desktop", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );
+ val.psz_string = _("Desktop");
+ var_Change( p_vout, "direct3d-desktop", VLC_VAR_SETTEXT, &val, NULL );
+ var_AddCallback( p_vout, "direct3d-desktop", DesktopCallback, NULL );
+ var_TriggerCallback( p_vout, "direct3d-desktop" );
+
return VLC_SUCCESS;
- error:
+error:
CloseVideo( VLC_OBJECT(p_vout) );
return VLC_EGENERIC;
}
Direct3DVoutRelease( p_vout );
- if( p_vout->p_sys->p_event )
- {
- vlc_object_detach( p_vout->p_sys->p_event );
-
- /* Kill Vout EventThread */
- vlc_object_kill( p_vout->p_sys->p_event );
-
- /* we need to be sure Vout EventThread won't stay stuck in
- * GetMessage, so we send a fake message */
- if( p_vout->p_sys->hwnd )
- {
- PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0);
- }
-
- vlc_thread_join( p_vout->p_sys->p_event );
- vlc_object_release( p_vout->p_sys->p_event );
- }
-
- vlc_mutex_destroy( &p_vout->p_sys->lock );
-
- /* restore screensaver system settings */
- if( 0 != p_vout->p_sys->i_spi_lowpowertimeout ) {
- SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT,
- p_vout->p_sys->i_spi_lowpowertimeout, NULL, 0);
- }
- if( 0 != p_vout->p_sys->i_spi_powerofftimeout ) {
- SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT,
- p_vout->p_sys->i_spi_powerofftimeout, NULL, 0);
- }
- if( 0 != p_vout->p_sys->i_spi_screensavetimeout ) {
- SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT,
- p_vout->p_sys->i_spi_screensavetimeout, NULL, 0);
- }
+ CommonClean( p_vout );
- if( p_vout->p_sys )
- {
- free( p_vout->p_sys );
- p_vout->p_sys = NULL;
- }
+ free( p_vout->p_sys );
}
/*****************************************************************************
static int Init( vout_thread_t *p_vout )
{
int i_ret;
- vlc_value_t val;
- var_Get( p_vout, "directx-hw-yuv", &val );
- p_vout->p_sys->b_hw_yuv = val.b_bool;
+ p_vout->p_sys->b_hw_yuv = var_GetBool( p_vout, "directx-hw-yuv" );
/* Initialise Direct3D */
if( VLC_SUCCESS != Direct3DVoutOpen( p_vout ) )
*****************************************************************************/
static int Manage( vout_thread_t *p_vout )
{
- /* If we do not control our window, we check for geometry changes
- * ourselves because the parent might not send us its events. */
- vlc_mutex_lock( &p_vout->p_sys->lock );
- if( p_vout->p_sys->hparent && !p_vout->b_fullscreen )
- {
- RECT rect_parent;
- POINT point;
-
- vlc_mutex_unlock( &p_vout->p_sys->lock );
-
- GetClientRect( p_vout->p_sys->hparent, &rect_parent );
- point.x = point.y = 0;
- ClientToScreen( p_vout->p_sys->hparent, &point );
- OffsetRect( &rect_parent, point.x, point.y );
-
- if( !EqualRect( &rect_parent, &p_vout->p_sys->rect_parent ) )
- {
- p_vout->p_sys->rect_parent = rect_parent;
-
- SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
- rect_parent.right - rect_parent.left,
- rect_parent.bottom - rect_parent.top,
- SWP_NOZORDER );
- }
- }
- else
- {
- vlc_mutex_unlock( &p_vout->p_sys->lock );
- }
+ CommonManage( p_vout );
/*
* Position Change
p_vout->p_sys->i_changes &= ~DX_POSITION_CHANGE;
}
- /* Check for cropping / aspect changes */
- if( p_vout->i_changes & VOUT_CROP_CHANGE ||
- p_vout->i_changes & VOUT_ASPECT_CHANGE )
- {
- p_vout->i_changes &= ~VOUT_CROP_CHANGE;
- p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;
-
- p_vout->fmt_out.i_x_offset = p_vout->fmt_in.i_x_offset;
- p_vout->fmt_out.i_y_offset = p_vout->fmt_in.i_y_offset;
- p_vout->fmt_out.i_visible_width = p_vout->fmt_in.i_visible_width;
- p_vout->fmt_out.i_visible_height = p_vout->fmt_in.i_visible_height;
- p_vout->fmt_out.i_aspect = p_vout->fmt_in.i_aspect;
- p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;
- p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;
- p_vout->output.i_aspect = p_vout->fmt_in.i_aspect;
- UpdateRects( p_vout, true );
- }
-
- /* We used to call the Win32 PeekMessage function here to read the window
- * messages. But since window can stay blocked into this function for a
- * long time (for example when you move your window on the screen), I
- * decided to isolate PeekMessage in another thread. */
-
/*
- * Fullscreen change
+ * Desktop mode change
*/
- if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE
- || p_vout->p_sys->i_changes & VOUT_FULLSCREEN_CHANGE )
+ if( p_vout->p_sys->i_changes & DX_DESKTOP_CHANGE )
{
- Win32ToggleFullscreen( p_vout );
+ /* Close the direct3d instance attached to the current output window. */
+ End( p_vout );
- p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
- p_vout->p_sys->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
- }
+ ExitFullscreen( p_vout );
- /*
- * Pointer change
- */
- if( p_vout->b_fullscreen && !p_vout->p_sys->b_cursor_hidden &&
- (mdate() - p_vout->p_sys->i_lastmoved) >
- p_vout->p_sys->i_mouse_hide_timeout )
- {
- POINT point;
- HWND hwnd;
+ EventThreadStop( p_vout->p_sys->p_event );
- /* Hide the cursor only if it is inside our window */
- GetCursorPos( &point );
- hwnd = WindowFromPoint(point);
- if( hwnd == p_vout->p_sys->hwnd || hwnd == p_vout->p_sys->hvideownd )
- {
- PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
- }
- else
- {
- p_vout->p_sys->i_lastmoved = mdate();
- }
- }
+ /* Open the direct3d output and attaches it to the new window */
+ p_vout->p_sys->b_desktop = !p_vout->p_sys->b_desktop;
+ p_vout->pf_display = FirstDisplay;
- /*
- * "Always on top" status change
- */
- if( p_vout->p_sys->b_on_top_change )
- {
- vlc_value_t val;
- HMENU hMenu = GetSystemMenu( p_vout->p_sys->hwnd, FALSE );
-
- var_Get( p_vout, "video-on-top", &val );
-
- /* Set the window on top if necessary */
- if( val.b_bool && !( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )
- & WS_EX_TOPMOST ) )
- {
- CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,
- MF_BYCOMMAND | MFS_CHECKED );
- SetWindowPos( p_vout->p_sys->hwnd, HWND_TOPMOST, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE );
- }
- else
- /* The window shouldn't be on top */
- if( !val.b_bool && ( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )
- & WS_EX_TOPMOST ) )
- {
- CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,
- MF_BYCOMMAND | MFS_UNCHECKED );
- SetWindowPos( p_vout->p_sys->hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE );
- }
+ EventThreadStart( p_vout->p_sys->p_event );
- p_vout->p_sys->b_on_top_change = false;
- }
+ Init( p_vout );
- /* Check if the event thread is still running */
- if( p_vout->p_sys->p_event->b_die )
- {
- return VLC_EGENERIC; /* exit */
+ /* Reset the flag */
+ p_vout->p_sys->i_changes &= ~DX_DESKTOP_CHANGE;
}
return VLC_SUCCESS;
*****************************************************************************/
static void Display( vout_thread_t *p_vout, picture_t *p_pic )
{
+ VLC_UNUSED( 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,
IDirect3DDevice9_Release(p_vout->p_sys->p_d3ddev);
p_vout->p_sys->p_d3ddev = NULL;
}
-
+
p_vout->p_sys->hmonitor = NULL;
}
/* it sounds like vista does not support YUV surfaces at all */
switch( i_chroma )
{
- case VLC_FOURCC('U','Y','V','Y'):
- case VLC_FOURCC('U','Y','N','V'):
- case VLC_FOURCC('Y','4','2','2'):
+ case VLC_CODEC_UYVY:
{
static const D3DFORMAT formats[] =
{ D3DFMT_UYVY, D3DFMT_YUY2, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };
return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));
}
- case VLC_FOURCC('I','4','2','0'):
- case VLC_FOURCC('I','4','2','2'):
- case VLC_FOURCC('Y','V','1','2'):
+ case VLC_CODEC_I420:
+ case VLC_CODEC_I422:
+ case VLC_CODEC_YV12:
{
/* typically 3D textures don't support planar format
** fallback to packed version and use CPU for the conversion
{ D3DFMT_YUY2, D3DFMT_UYVY, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };
return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));
}
- case VLC_FOURCC('Y','U','Y','2'):
- case VLC_FOURCC('Y','U','N','V'):
+ case VLC_CODEC_YUYV:
{
static const D3DFORMAT formats[] =
{ D3DFMT_YUY2, D3DFMT_UYVY, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };
switch( i_chroma )
{
- case VLC_FOURCC('R', 'V', '1', '5'):
+ case VLC_CODEC_RGB15:
{
static const D3DFORMAT formats[] =
{ D3DFMT_X1R5G5B5 };
return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));
}
- case VLC_FOURCC('R', 'V', '1', '6'):
+ case VLC_CODEC_RGB16:
{
static const D3DFORMAT formats[] =
{ D3DFMT_R5G6B5 };
return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));
}
- case VLC_FOURCC('R', 'V', '2', '4'):
+ case VLC_CODEC_RGB24:
{
static const D3DFORMAT formats[] =
{ D3DFMT_R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8 };
return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));
}
- case VLC_FOURCC('R', 'V', '3', '2'):
+ case VLC_CODEC_RGB32:
{
static const D3DFORMAT formats[] =
{ D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8 };
switch( format )
{
case D3DFMT_YUY2:
- p_vout->output.i_chroma = VLC_FOURCC('Y', 'U', 'Y', '2');
+ p_vout->output.i_chroma = VLC_CODEC_YUYV;
break;
case D3DFMT_UYVY:
- p_vout->output.i_chroma = VLC_FOURCC('U', 'Y', 'V', 'Y');
+ p_vout->output.i_chroma = VLC_CODEC_UYVY;
break;
case D3DFMT_R8G8B8:
- p_vout->output.i_chroma = VLC_FOURCC('R', 'V', '2', '4');
+ p_vout->output.i_chroma = VLC_CODEC_RGB24;
p_vout->output.i_rmask = 0xff0000;
p_vout->output.i_gmask = 0x00ff00;
p_vout->output.i_bmask = 0x0000ff;
break;
case D3DFMT_X8R8G8B8:
case D3DFMT_A8R8G8B8:
- p_vout->output.i_chroma = VLC_FOURCC('R', 'V', '3', '2');
+ p_vout->output.i_chroma = VLC_CODEC_RGB32;
p_vout->output.i_rmask = 0x00ff0000;
p_vout->output.i_gmask = 0x0000ff00;
p_vout->output.i_bmask = 0x000000ff;
break;
case D3DFMT_R5G6B5:
- p_vout->output.i_chroma = VLC_FOURCC('R', 'V', '1', '6');
+ p_vout->output.i_chroma = VLC_CODEC_RGB16;
p_vout->output.i_rmask = (0x1fL)<<11;
p_vout->output.i_gmask = (0x3fL)<<5;
p_vout->output.i_bmask = (0x1fL)<<0;
break;
case D3DFMT_X1R5G5B5:
- p_vout->output.i_chroma = VLC_FOURCC('R', 'V', '1', '5');
+ p_vout->output.i_chroma = VLC_CODEC_RGB15;
p_vout->output.i_rmask = (0x1fL)<<10;
p_vout->output.i_gmask = (0x1fL)<<5;
p_vout->output.i_bmask = (0x1fL)<<0;
HRESULT hr;
size_t c;
// if vout is already running, use current chroma, otherwise choose from upstream
- int i_chroma = p_vout->output.i_chroma ? : p_vout->render.i_chroma;
+ int i_chroma = p_vout->output.i_chroma ? p_vout->output.i_chroma
+ : p_vout->render.i_chroma;
I_OUTPUTPICTURES = 0;
/* 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;
* picture_t structures */
switch( p_vout->output.i_chroma )
{
- case VLC_FOURCC('R','G','B','2'):
+ case VLC_CODEC_RGB8:
p_pic->p->i_lines = p_vout->output.i_height;
p_pic->p->i_visible_lines = p_vout->output.i_height;
p_pic->p->i_pixel_pitch = 1;
p_pic->p->i_pixel_pitch;
p_pic->i_planes = 1;
break;
- case VLC_FOURCC('R','V','1','5'):
- case VLC_FOURCC('R','V','1','6'):
+ case VLC_CODEC_RGB15:
+ case VLC_CODEC_RGB16:
p_pic->p->i_lines = p_vout->output.i_height;
p_pic->p->i_visible_lines = p_vout->output.i_height;
p_pic->p->i_pixel_pitch = 2;
p_pic->p->i_pixel_pitch;
p_pic->i_planes = 1;
break;
- case VLC_FOURCC('R','V','2','4'):
+ case VLC_CODEC_RGB24:
p_pic->p->i_lines = p_vout->output.i_height;
p_pic->p->i_visible_lines = p_vout->output.i_height;
p_pic->p->i_pixel_pitch = 3;
p_pic->p->i_pixel_pitch;
p_pic->i_planes = 1;
break;
- case VLC_FOURCC('R','V','3','2'):
+ case VLC_CODEC_RGB32:
p_pic->p->i_lines = p_vout->output.i_height;
p_pic->p->i_visible_lines = p_vout->output.i_height;
p_pic->p->i_pixel_pitch = 4;
p_pic->p->i_pixel_pitch;
p_pic->i_planes = 1;
break;
- case VLC_FOURCC('U','Y','V','Y'):
- case VLC_FOURCC('Y','U','Y','2'):
+ case VLC_CODEC_UYVY:
+ case VLC_CODEC_YUYV:
p_pic->p->i_lines = p_vout->output.i_height;
p_pic->p->i_visible_lines = p_vout->output.i_height;
p_pic->p->i_pixel_pitch = 2;
}
/* Update the vertex buffer */
- hr = IDirect3DVertexBuffer9_Lock(p_d3dvtc, 0, 0, (VOID **)(&p_vertices), D3DLOCK_DISCARD);
+ hr = IDirect3DVertexBuffer9_Lock(p_d3dvtc, 0, 0, (&p_vertices), D3DLOCK_DISCARD);
if( FAILED(hr) )
{
msg_Dbg( p_vout, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
}
/* 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) )
{
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) )
{
}
}
+
+/*****************************************************************************
+ * DesktopCallback: desktop mode variable callback
+ *****************************************************************************/
+static int DesktopCallback( vlc_object_t *p_this, char const *psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval,
+ void *p_data )
+{
+ VLC_UNUSED( psz_cmd );
+ VLC_UNUSED( oldval );
+ VLC_UNUSED( p_data );
+
+ vout_thread_t *p_vout = (vout_thread_t *)p_this;
+
+ if( (newval.b_bool && !p_vout->p_sys->b_desktop) ||
+ (!newval.b_bool && p_vout->p_sys->b_desktop) )
+ {
+ playlist_t *p_playlist = pl_Hold( p_vout );
+
+ if( p_playlist )
+ {
+ /* Modify playlist as well because the vout might have to be
+ * restarted */
+ var_Create( p_playlist, "direct3d-desktop", VLC_VAR_BOOL );
+ var_Set( p_playlist, "direct3d-desktop", newval );
+ pl_Release( p_vout );
+ }
+
+ p_vout->p_sys->i_changes |= DX_DESKTOP_CHANGE;
+ }
+
+ return VLC_SUCCESS;
+}