Commit eb12915b authored by Adrien Maglo's avatar Adrien Maglo Committed by Jean-Baptiste Kempf

Add a desktop mode to the Direct3d video output. This allow displaying video...

Add a desktop mode to the Direct3d video output. This allow displaying video on a window located just up the desktop icon window.
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent f52524a2
...@@ -220,6 +220,7 @@ static int VideoAutoMenuBuilder( vout_thread_t *p_object, ...@@ -220,6 +220,7 @@ static int VideoAutoMenuBuilder( vout_thread_t *p_object,
PUSH_VAR( "video-on-top" ); PUSH_VAR( "video-on-top" );
#ifdef WIN32 #ifdef WIN32
PUSH_VAR( "directx-wallpaper" ); PUSH_VAR( "directx-wallpaper" );
PUSH_VAR( "direct3d-desktop" );
#endif #endif
PUSH_VAR( "video-snapshot" ); PUSH_VAR( "video-snapshot" );
PUSH_VAR( "zoom" ); PUSH_VAR( "zoom" );
...@@ -558,6 +559,7 @@ QMenu *QVLCMenu::VideoMenu( intf_thread_t *p_intf, QMenu *current ) ...@@ -558,6 +559,7 @@ QMenu *QVLCMenu::VideoMenu( intf_thread_t *p_intf, QMenu *current )
ACT_ADDCHECK( current, "video-on-top", qtr( "Always &On Top" ) ); ACT_ADDCHECK( current, "video-on-top", qtr( "Always &On Top" ) );
#ifdef WIN32 #ifdef WIN32
ACT_ADDCHECK( current, "directx-wallpaper", qtr( "DirectX Wallpaper" ) ); ACT_ADDCHECK( current, "directx-wallpaper", qtr( "DirectX Wallpaper" ) );
ACT_ADDCHECK( current, "direct3d-desktop", qtr( "Direct3D Desktop mode" ) );
#endif #endif
ACT_ADD( current, "video-snapshot", qtr( "Sna&pshot" ) ); ACT_ADD( current, "video-snapshot", qtr( "Sna&pshot" ) );
......
...@@ -80,6 +80,10 @@ static int Direct3DVoutCreateScene ( vout_thread_t * ); ...@@ -80,6 +80,10 @@ static int Direct3DVoutCreateScene ( vout_thread_t * );
static void Direct3DVoutReleaseScene ( vout_thread_t * ); static void Direct3DVoutReleaseScene ( vout_thread_t * );
static void Direct3DVoutRenderScene ( vout_thread_t *, picture_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 * Module descriptor
*****************************************************************************/ *****************************************************************************/
...@@ -111,10 +115,18 @@ static int OpenVideoVista( vlc_object_t *obj ) ...@@ -111,10 +115,18 @@ static int OpenVideoVista( vlc_object_t *obj )
return IsVistaOrAbove() ? OpenVideo( obj ) : VLC_EGENERIC; return IsVistaOrAbove() ? OpenVideo( obj ) : VLC_EGENERIC;
} }
#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 () vlc_module_begin ()
set_shortname( "Direct3D" ) set_shortname( "Direct3D" )
set_category( CAT_VIDEO ) set_category( CAT_VIDEO )
set_subcategory( SUBCAT_VIDEO_VOUT ) set_subcategory( SUBCAT_VIDEO_VOUT )
add_bool( "direct3d-desktop", 0, NULL, DESKTOP_TEXT, DESKTOP_LONGTEXT,
true )
set_description( N_("DirectX 3D video output") ) set_description( N_("DirectX 3D video output") )
set_capability( "video output", 50 ) set_capability( "video output", 50 )
add_shortcut( "direct3d" ) add_shortcut( "direct3d" )
...@@ -158,6 +170,7 @@ typedef struct ...@@ -158,6 +170,7 @@ typedef struct
*****************************************************************************/ *****************************************************************************/
static int OpenVideo( vlc_object_t *p_this ) static int OpenVideo( vlc_object_t *p_this )
{ {
vlc_value_t val;
vout_thread_t * p_vout = (vout_thread_t *)p_this; vout_thread_t * p_vout = (vout_thread_t *)p_this;
/* Allocate structure */ /* Allocate structure */
...@@ -183,6 +196,7 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -183,6 +196,7 @@ static int OpenVideo( vlc_object_t *p_this )
p_vout->p_sys->hwnd = p_vout->p_sys->hvideownd = NULL; 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->hparent = p_vout->p_sys->hfswnd = NULL;
p_vout->p_sys->i_changes = 0; p_vout->p_sys->i_changes = 0;
p_vout->p_sys->b_desktop = false;
vlc_mutex_init( &p_vout->p_sys->lock ); vlc_mutex_init( &p_vout->p_sys->lock );
SetRectEmpty( &p_vout->p_sys->rect_display ); SetRectEmpty( &p_vout->p_sys->rect_display );
SetRectEmpty( &p_vout->p_sys->rect_parent ); SetRectEmpty( &p_vout->p_sys->rect_parent );
...@@ -208,6 +222,13 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -208,6 +222,13 @@ static int OpenVideo( vlc_object_t *p_this )
/* Trigger a callback right now */ /* Trigger a callback right now */
var_TriggerCallback( p_vout, "video-on-top" ); var_TriggerCallback( p_vout, "video-on-top" );
/* Trigger a callback right now */
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" );
DisableScreensaver ( p_vout ); DisableScreensaver ( p_vout );
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -332,6 +353,7 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -332,6 +353,7 @@ static int Manage( vout_thread_t *p_vout )
rect_parent.right - rect_parent.left, rect_parent.right - rect_parent.left,
rect_parent.bottom - rect_parent.top, rect_parent.bottom - rect_parent.top,
SWP_NOZORDER ); SWP_NOZORDER );
UpdateRects( p_vout, true );
} }
} }
else else
...@@ -363,6 +385,35 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -363,6 +385,35 @@ static int Manage( vout_thread_t *p_vout )
#endif #endif
p_vout->p_sys->i_changes &= ~DX_POSITION_CHANGE; p_vout->p_sys->i_changes &= ~DX_POSITION_CHANGE;
} }
/*
* Desktop mode change
*/
if( p_vout->p_sys->i_changes & DX_DESKTOP_CHANGE )
{
/* Close the direct3d instance attached to the current output window. */
End( p_vout );
StopEventThread( p_vout );
/* Set the switching mode flag */
p_vout->p_sys->i_changes |= SWITCHING_MODE_FLAG;
/* Reset the flag */
p_vout->p_sys->i_changes &= ~DX_DESKTOP_CHANGE;
}
if( p_vout->p_sys->i_changes & EVENT_THREAD_ENDED
&& p_vout->p_sys->i_changes & SWITCHING_MODE_FLAG )
{
/* 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;
CreateEventThread( p_vout );
Init( p_vout );
/* Reset the flags */
p_vout->p_sys->i_changes &= ~EVENT_THREAD_ENDED;
p_vout->p_sys->i_changes &= ~SWITCHING_MODE_FLAG;
}
/* autoscale toggle */ /* autoscale toggle */
if( p_vout->i_changes & VOUT_SCALE_CHANGE ) if( p_vout->i_changes & VOUT_SCALE_CHANGE )
...@@ -493,6 +544,10 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -493,6 +544,10 @@ static int Manage( vout_thread_t *p_vout )
static void Display( vout_thread_t *p_vout, picture_t *p_pic ) 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;
if( p_vout->p_sys->i_changes & SWITCHING_MODE_FLAG )
return;
// Present the back buffer contents to the display // Present the back buffer contents to the display
// stretching and filtering happens here // stretching and filtering happens here
HRESULT hr = IDirect3DDevice9_Present(p_d3ddev, HRESULT hr = IDirect3DDevice9_Present(p_d3ddev,
...@@ -1266,6 +1321,9 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -1266,6 +1321,9 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
HRESULT hr; HRESULT hr;
float f_width, f_height; float f_width, f_height;
if( p_vout->p_sys->i_changes & SWITCHING_MODE_FLAG )
return;
// check if device is still available // check if device is still available
hr = IDirect3DDevice9_TestCooperativeLevel(p_d3ddev); hr = IDirect3DDevice9_TestCooperativeLevel(p_d3ddev);
if( FAILED(hr) ) if( FAILED(hr) )
...@@ -1423,3 +1481,36 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -1423,3 +1481,36 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
} }
} }
/*****************************************************************************
* 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;
}
...@@ -383,11 +383,11 @@ void* EventThread( vlc_object_t *p_this ) ...@@ -383,11 +383,11 @@ void* EventThread( vlc_object_t *p_this )
msg_Dbg( p_event, "DirectXEventThread terminating" ); msg_Dbg( p_event, "DirectXEventThread terminating" );
/* clear the changes formerly signaled */
p_event->p_vout->p_sys->i_changes = 0;
DirectXCloseWindow( p_event->p_vout ); DirectXCloseWindow( p_event->p_vout );
vlc_restorecancel (canc); vlc_restorecancel (canc);
/* clear the changes formerly signaled */
p_event->p_vout->p_sys->i_changes = EVENT_THREAD_ENDED;
return NULL; return NULL;
} }
...@@ -416,14 +416,31 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -416,14 +416,31 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
/* Get this module's instance */ /* Get this module's instance */
hInstance = GetModuleHandle(NULL); hInstance = GetModuleHandle(NULL);
/* If an external window was specified, we'll draw in it. */ #ifdef MODULE_NAME_IS_direct3d
p_vout->p_sys->parent_window = if( !p_vout->p_sys->b_desktop )
vout_RequestHWND( p_vout, &p_vout->p_sys->i_window_x, {
#endif
/* If an external window was specified, we'll draw in it. */
p_vout->p_sys->parent_window =
vout_RequestHWND( p_vout, &p_vout->p_sys->i_window_x,
&p_vout->p_sys->i_window_y, &p_vout->p_sys->i_window_y,
&p_vout->p_sys->i_window_width, &p_vout->p_sys->i_window_width,
&p_vout->p_sys->i_window_height ); &p_vout->p_sys->i_window_height );
if( p_vout->p_sys->parent_window ) if( p_vout->p_sys->parent_window )
p_vout->p_sys->hparent = p_vout->p_sys->parent_window->handle.hwnd; p_vout->p_sys->hparent = p_vout->p_sys->parent_window->handle.hwnd;
#ifdef MODULE_NAME_IS_direct3d
}
else
{
/* Find Program Manager */
HWND hwnd = FindWindow( _T("Progman"), NULL );
if( hwnd ) hwnd = FindWindowEx( hwnd, NULL, _T("SHELLDLL_DefView"), NULL );
if( hwnd ) hwnd = FindWindowEx( hwnd, NULL, _T("SysListView32"), NULL );
if( !hwnd )
msg_Err( p_vout, "Couldn't find desktop icon window. Desktop mode can't be established." );
p_vout->p_sys->hparent = hwnd;
}
#endif
/* We create the window ourself, there is no previous window proc. */ /* We create the window ourself, there is no previous window proc. */
p_vout->p_sys->pf_wndproc = NULL; p_vout->p_sys->pf_wndproc = NULL;
...@@ -601,7 +618,10 @@ static void DirectXCloseWindow( vout_thread_t *p_vout ) ...@@ -601,7 +618,10 @@ static void DirectXCloseWindow( vout_thread_t *p_vout )
DestroyWindow( p_vout->p_sys->hwnd ); DestroyWindow( p_vout->p_sys->hwnd );
if( p_vout->p_sys->hfswnd ) DestroyWindow( p_vout->p_sys->hfswnd ); if( p_vout->p_sys->hfswnd ) DestroyWindow( p_vout->p_sys->hfswnd );
vout_ReleaseWindow( p_vout->p_sys->parent_window ); #ifdef MODULE_NAME_IS_direct3d
if( !p_vout->p_sys->b_desktop )
#endif
vout_ReleaseWindow( p_vout->p_sys->parent_window );
p_vout->p_sys->hwnd = NULL; p_vout->p_sys->hwnd = NULL;
/* We don't unregister the Window Class because it could lead to race /* We don't unregister the Window Class because it could lead to race
...@@ -1322,5 +1342,6 @@ void StopEventThread( vout_thread_t *p_vout ) ...@@ -1322,5 +1342,6 @@ void StopEventThread( vout_thread_t *p_vout )
vlc_object_release( p_vout->p_sys->p_event ); vlc_object_release( p_vout->p_sys->p_event );
} }
vlc_mutex_destroy( &p_vout->p_sys->lock ); if( !p_vout->p_sys->i_changes & SWITCHING_MODE_FLAG )
vlc_mutex_destroy( &p_vout->p_sys->lock );
} }
...@@ -168,6 +168,9 @@ struct vout_sys_t ...@@ -168,6 +168,9 @@ struct vout_sys_t
#endif #endif
#ifdef MODULE_NAME_IS_direct3d #ifdef MODULE_NAME_IS_direct3d
/* show video on desktop window ? */
bool b_desktop;
// core objects // core objects
HINSTANCE hd3d9_dll; /* handle of the opened d3d9 dll */ HINSTANCE hd3d9_dll; /* handle of the opened d3d9 dll */
LPDIRECT3D9 p_d3dobj; LPDIRECT3D9 p_d3dobj;
...@@ -270,6 +273,9 @@ void StopEventThread ( vout_thread_t *p_vout ); ...@@ -270,6 +273,9 @@ void StopEventThread ( vout_thread_t *p_vout );
#define IDM_TOGGLE_ON_TOP WM_USER + 1 #define IDM_TOGGLE_ON_TOP WM_USER + 1
#define DX_POSITION_CHANGE 0x1000 #define DX_POSITION_CHANGE 0x1000
#define DX_WALLPAPER_CHANGE 0x2000 #define DX_WALLPAPER_CHANGE 0x2000
#define DX_DESKTOP_CHANGE 0x4000
#define EVENT_THREAD_ENDED 0x6000
#define SWITCHING_MODE_FLAG 0x8000
/***************************************************************************** /*****************************************************************************
* WinCE helpers * WinCE helpers
......
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