Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-gpu
Commits
4a1df8f1
Commit
4a1df8f1
authored
Oct 20, 2009
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cosmetics.
parent
caa6b574
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
430 additions
and
504 deletions
+430
-504
modules/video_output/msw/direct3d.c
modules/video_output/msw/direct3d.c
+430
-504
No files found.
modules/video_output/msw/direct3d.c
View file @
4a1df8f1
...
...
@@ -45,111 +45,80 @@
#include <windows.h>
#include <d3d9.h>
#include "vout.h"
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static
int
OpenVideo
(
vlc_object_t
*
);
static
void
CloseVideo
(
vlc_object_t
*
);
static
int
Init
(
vout_thread_t
*
);
static
void
End
(
vout_thread_t
*
);
static
int
Manage
(
vout_thread_t
*
);
static
void
Display
(
vout_thread_t
*
,
picture_t
*
);
static
void
FirstDisplay
(
vout_thread_t
*
,
picture_t
*
);
static
int
Direct3DVoutCreate
(
vout_thread_t
*
);
static
void
Direct3DVoutRelease
(
vout_thread_t
*
);
static
int
Direct3DVoutOpen
(
vout_thread_t
*
);
static
void
Direct3DVoutClose
(
vout_thread_t
*
);
static
int
Direct3DVoutResetDevice
(
vout_thread_t
*
);
static
int
Direct3DVoutCreatePictures
(
vout_thread_t
*
,
size_t
);
static
void
Direct3DVoutReleasePictures
(
vout_thread_t
*
);
static
int
Direct3DVoutLockSurface
(
vout_thread_t
*
,
picture_t
*
);
static
int
Direct3DVoutUnlockSurface
(
vout_thread_t
*
,
picture_t
*
);
static
int
Direct3DVoutCreateScene
(
vout_thread_t
*
);
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
);
#include "common.h"
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static
bool
IsVistaOrAbove
(
void
)
{
OSVERSIONINFO
winVer
;
winVer
.
dwOSVersionInfoSize
=
sizeof
(
OSVERSIONINFO
);
if
(
GetVersionEx
(
&
winVer
)
)
{
if
(
winVer
.
dwMajorVersion
>
5
)
{
/* Windows Vista or above, make this module the default */
return
true
;
}
}
/* Windows XP or lower, make sure this module isn't the default */
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
;
}
static
int
OpenVideoXP
(
vlc_object_t
*
);
static
int
OpenVideoVista
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
#define DESKTOP_TEXT N_("Enable desktop mode ")
#define DESKTOP_LONGTEXT N_(
\
"The desktop mode allows you to display the video on the desktop."
)
#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
)
set_shortname
(
"Direct3D"
)
set_category
(
CAT_VIDEO
)
set_subcategory
(
SUBCAT_VIDEO_VOUT
)
add_bool
(
"direct3d-desktop"
,
false
,
NULL
,
DESKTOP_TEXT
,
DESKTOP_LONGTEXT
,
true
)
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
)
set_description
(
N_
(
"DirectX 3D video output"
)
)
set_capability
(
"video output"
,
50
)
add_shortcut
(
"direct3d"
)
set_callbacks
(
OpenVideoXP
,
Close
)
/* FIXME: Hack to avoid unregistering our window class */
linked_with_a_crap_library_which_uses_atexit
()
add_submodule
()
set_capability
(
"video output"
,
150
)
add_shortcut
(
"direct3d"
)
set_callbacks
(
OpenVideoVista
,
CloseVideo
)
set_capability
(
"video output"
,
150
)
add_shortcut
(
"direct3d"
)
set_callbacks
(
OpenVideoVista
,
Close
)
vlc_module_end
()
#if 0 /* FIXME */
/* check if we registered a window class because we need to
* unregister it */
WNDCLASS wndclass;
if
( GetClassInfo( GetModuleHandle(NULL), "VLC DirectX", &wndclass )
)
UnregisterClass(
"VLC DirectX", GetModuleHandle(NULL)
);
if
(GetClassInfo(GetModuleHandle(NULL), "VLC DirectX", &wndclass)
)
UnregisterClass(
"VLC DirectX", GetModuleHandle(NULL)
);
#endif
/*****************************************************************************
* CUSTOMVERTEX:
*****************************************************************************
* Local prototypes.
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
int
Init
(
vout_thread_t
*
);
static
void
End
(
vout_thread_t
*
);
static
int
Manage
(
vout_thread_t
*
);
static
void
Display
(
vout_thread_t
*
,
picture_t
*
);
static
void
FirstDisplay
(
vout_thread_t
*
,
picture_t
*
);
static
int
Direct3DCreate
(
vout_thread_t
*
);
static
void
Direct3DRelease
(
vout_thread_t
*
);
static
int
Direct3DOpen
(
vout_thread_t
*
);
static
void
Direct3DClose
(
vout_thread_t
*
);
static
int
Direct3DResetDevice
(
vout_thread_t
*
);
static
int
Direct3DCreatePictures
(
vout_thread_t
*
,
size_t
);
static
void
Direct3DReleasePictures
(
vout_thread_t
*
);
static
int
Direct3DLockSurface
(
vout_thread_t
*
,
picture_t
*
);
static
int
Direct3DUnlockSurface
(
vout_thread_t
*
,
picture_t
*
);
static
int
Direct3DCreateScene
(
vout_thread_t
*
);
static
void
Direct3DReleaseScene
(
vout_thread_t
*
);
static
void
Direct3DRenderScene
(
vout_thread_t
*
,
picture_t
*
);
static
int
DesktopCallback
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
typedef
struct
{
FLOAT
x
,
y
,
z
;
// vertex untransformed position
...
...
@@ -160,88 +129,103 @@ typedef struct
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
/*****************************************************************************
* OpenVideo: allocate Vout video thread output method
*****************************************************************************
* This function allocates and initialize the Direct3D vout method.
*****************************************************************************/
static
int
OpenVideo
(
vlc_object_t
*
p_this
)
/**
* It creates a Direct3D vout display.
*/
static
int
Open
(
vlc_object_t
*
object
)
{
v
lc_value_t
val
;
vout_
thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_thi
s
;
v
out_thread_t
*
p_vout
=
(
vout_thread_t
*
)
object
;
vout_
sys_t
*
p_sy
s
;
/* Allocate structure */
p_vout
->
p_sys
=
calloc
(
1
,
sizeof
(
vout_sys_t
)
);
if
(
p_vout
->
p_sys
==
NULL
)
p_vout
->
p_sys
=
p_sys
=
calloc
(
1
,
sizeof
(
vout_sys_t
)
);
if
(
!
p_sys
)
return
VLC_ENOMEM
;
if
(
VLC_SUCCESS
!=
Direct3DVoutCreate
(
p_vout
)
)
{
msg_Err
(
p_vout
,
"Direct3D could not be initialized !"
);
Direct3DVoutRelease
(
p_vout
);
free
(
p_vout
->
p_sys
);
if
(
VLC_SUCCESS
!=
Direct3DCreate
(
p_vout
))
{
msg_Err
(
p_vout
,
"Direct3D could not be initialized !"
);
Direct3DRelease
(
p_vout
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
p_
vout
->
p_
sys
->
b_desktop
=
false
;
p_sys
->
b_desktop
=
false
;
/* Initialisations */
p_vout
->
pf_init
=
Init
;
p_vout
->
pf_end
=
End
;
p_vout
->
pf_manage
=
Manage
;
p_vout
->
pf_render
=
Direct3D
Vout
RenderScene
;
p_vout
->
pf_render
=
Direct3DRenderScene
;
p_vout
->
pf_display
=
FirstDisplay
;
p_vout
->
pf_control
=
Control
;
if
(
CommonInit
(
p_vout
)
)
if
(
CommonInit
(
p_vout
)
)
goto
error
;
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
);
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
);
/* Trigger a callback right now */
var_Create
(
p_vout
,
"direct3d-desktop"
,
VLC_VAR_BOOL
|
VLC_VAR_DOINHERIT
);
var_Create
(
p_vout
,
"direct3d-desktop"
,
VLC_VAR_BOOL
|
VLC_VAR_DOINHERIT
);
vlc_value_t
val
;
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"
);
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:
Close
Video
(
VLC_OBJECT
(
p_vout
)
);
Close
(
VLC_OBJECT
(
p_vout
)
);
return
VLC_EGENERIC
;
}
/*****************************************************************************
* CloseVideo: destroy Sys video thread output method
*****************************************************************************
* Terminate an output method created by Create
*****************************************************************************/
static
void
CloseVideo
(
vlc_object_t
*
p_this
)
static
bool
IsVistaOrAbove
(
void
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
OSVERSIONINFO
winVer
;
winVer
.
dwOSVersionInfoSize
=
sizeof
(
OSVERSIONINFO
);
return
GetVersionEx
(
&
winVer
)
&&
winVer
.
dwMajorVersion
>
5
;
}
CommonClean
(
p_vout
);
static
int
OpenVideoXP
(
vlc_object_t
*
obj
)
{
/* Windows XP or lower, make sure this module isn't the default */
return
IsVistaOrAbove
()
?
VLC_EGENERIC
:
Open
(
obj
);
}
Direct3DVoutRelease
(
p_vout
);
static
int
OpenVideoVista
(
vlc_object_t
*
obj
)
{
/* Windows Vista or above, make this module the default */
return
IsVistaOrAbove
()
?
Open
(
obj
)
:
VLC_EGENERIC
;
}
/**
* It destroyes a Direct3D vout display.
*/
static
void
Close
(
vlc_object_t
*
object
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
object
;
CommonClean
(
p_vout
);
Direct3DRelease
(
p_vout
);
free
(
p_vout
->
p_sys
);
free
(
p_vout
->
p_sys
);
}
/*****************************************************************************
* Init: initialize Direct3D video thread output method
*****************************************************************************/
static
int
Init
(
vout_thread_t
*
p_vout
)
static
int
Init
(
vout_thread_t
*
p_vout
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
int
i_ret
;
p_
vout
->
p_sys
->
b_hw_yuv
=
var_GetBool
(
p_vout
,
"directx-hw-yuv"
);
p_
sys
->
b_hw_yuv
=
var_GetBool
(
p_vout
,
"directx-hw-yuv"
);
/* Initialise Direct3D */
if
(
VLC_SUCCESS
!=
Direct3DVoutOpen
(
p_vout
)
)
{
msg_Err
(
p_vout
,
"cannot initialize Direct3D"
);
if
(
Direct3DOpen
(
p_vout
))
{
msg_Err
(
p_vout
,
"cannot initialize Direct3D"
);
return
VLC_EGENERIC
;
}
...
...
@@ -252,28 +236,26 @@ static int Init( vout_thread_t *p_vout )
p_vout
->
output
.
i_height
=
p_vout
->
render
.
i_height
;
p_vout
->
output
.
i_aspect
=
p_vout
->
render
.
i_aspect
;
p_vout
->
fmt_out
=
p_vout
->
fmt_in
;
UpdateRects
(
p_vout
,
true
);
UpdateRects
(
p_vout
,
true
);
/* create picture pool */
p_vout
->
output
.
i_chroma
=
0
;
i_ret
=
Direct3DVoutCreatePictures
(
p_vout
,
1
);
if
(
VLC_SUCCESS
!=
i_ret
)
{
i_ret
=
Direct3DCreatePictures
(
p_vout
,
1
);
if
(
i_ret
)
{
msg_Err
(
p_vout
,
"Direct3D picture pool initialization failed !"
);
return
i_ret
;
}
/* create scene */
i_ret
=
Direct3DVoutCreateScene
(
p_vout
);
if
(
VLC_SUCCESS
!=
i_ret
)
{
i_ret
=
Direct3DCreateScene
(
p_vout
);
if
(
i_ret
)
{
msg_Err
(
p_vout
,
"Direct3D scene initialization failed !"
);
Direct3D
Vout
ReleasePictures
(
p_vout
);
Direct3DReleasePictures
(
p_vout
);
return
i_ret
;
}
/* Change the window title bar text */
EventThreadUpdateTitle
(
p_vout
->
p_sys
->
p_event
,
VOUT_TITLE
" (Direct3D output)"
);
EventThreadUpdateTitle
(
p_sys
->
p_event
,
VOUT_TITLE
" (Direct3D output)"
);
p_vout
->
fmt_out
.
i_chroma
=
p_vout
->
output
.
i_chroma
;
return
VLC_SUCCESS
;
...
...
@@ -285,11 +267,11 @@ static int Init( vout_thread_t *p_vout )
* Terminate an output method created by Create.
* It is called at the end of the thread.
*****************************************************************************/
static
void
End
(
vout_thread_t
*
p_vout
)
static
void
End
(
vout_thread_t
*
p_vout
)
{
Direct3D
Vout
ReleaseScene
(
p_vout
);
Direct3D
Vout
ReleasePictures
(
p_vout
);
Direct3D
VoutClose
(
p_vout
);
Direct3DReleaseScene
(
p_vout
);
Direct3DReleasePictures
(
p_vout
);
Direct3D
Close
(
p_vout
);
}
/*****************************************************************************
...
...
@@ -298,59 +280,56 @@ static void End( vout_thread_t *p_vout )
* This function should be called regularly by the video output thread.
* It returns a non null value if an error occurred.
*****************************************************************************/
static
int
Manage
(
vout_thread_t
*
p_vout
)
static
int
Manage
(
vout_thread_t
*
p_vout
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
CommonManage
(
p_vout
);
CommonManage
(
p_vout
);
/*
* Position Change
*/
if
(
p_vout
->
p_sys
->
i_changes
&
DX_POSITION_CHANGE
)
{
if
(
p_sys
->
i_changes
&
DX_POSITION_CHANGE
)
{
#if 0 /* need that when bicubic filter is available */
RECT rect;
UINT width, height;
GetClientRect(p_
vout->p_
sys->hvideownd, &rect);
GetClientRect(p_sys->hvideownd, &rect);
width = rect.right-rect.left;
height = rect.bottom-rect.top;
if( (width != p_vout->p_sys->d3dpp.BackBufferWidth)
|| (height != p_vout->p_sys->d3dpp.BackBufferHeight) )
if (width != p_sys->d3dpp.BackBufferWidth || height != p_sys->d3dpp.BackBufferHeight)
{
msg_Dbg(p_vout, "resizing device back buffers to (%lux%lu)", width, height);
// need to reset D3D device to resize back buffer
if
( VLC_SUCCESS != Direct3DVoutResetDevice(p_vout, width, height)
)
if
(VLC_SUCCESS != Direct3DResetDevice(p_vout, width, height)
)
return VLC_EGENERIC;
}
#endif
p_
vout
->
p_
sys
->
i_changes
&=
~
DX_POSITION_CHANGE
;
p_sys
->
i_changes
&=
~
DX_POSITION_CHANGE
;
}
/*
* Desktop mode change
*/
if
(
p_vout
->
p_sys
->
i_changes
&
DX_DESKTOP_CHANGE
)
{
if
(
p_sys
->
i_changes
&
DX_DESKTOP_CHANGE
)
{
/* Close the direct3d instance attached to the current output window. */
End
(
p_vout
);
End
(
p_vout
);
ExitFullscreen
(
p_vout
);
ExitFullscreen
(
p_vout
);
EventThreadStop
(
p_vout
->
p_sys
->
p_event
);
EventThreadStop
(
p_sys
->
p_event
);
/* Open the direct3d output and attaches it to the new window */
p_
vout
->
p_sys
->
b_desktop
=
!
p_vout
->
p_sys
->
b_desktop
;
p_
sys
->
b_desktop
=
!
p_sys
->
b_desktop
;
p_vout
->
pf_display
=
FirstDisplay
;
event_cfg_t
cfg
;
memset
(
&
cfg
,
0
,
sizeof
(
cfg
));
cfg
.
use_desktop
=
p_
vout
->
p_
sys
->
b_desktop
;
cfg
.
use_desktop
=
p_sys
->
b_desktop
;
event_hwnd_t
hwnd
;
EventThreadStart
(
p_vout
->
p_sys
->
p_event
,
&
hwnd
,
&
cfg
);
EventThreadStart
(
p_sys
->
p_event
,
&
hwnd
,
&
cfg
);
p_sys
->
parent_window
=
hwnd
.
parent_window
;
p_sys
->
hparent
=
hwnd
.
hparent
;
...
...
@@ -358,10 +337,10 @@ static int Manage( vout_thread_t *p_vout )
p_sys
->
hvideownd
=
hwnd
.
hvideownd
;
p_sys
->
hfswnd
=
hwnd
.
hfswnd
;
Init
(
p_vout
);
Init
(
p_vout
);
/* Reset the flag */
p_
vout
->
p_
sys
->
i_changes
&=
~
DX_DESKTOP_CHANGE
;
p_sys
->
i_changes
&=
~
DX_DESKTOP_CHANGE
;
}
return
VLC_SUCCESS
;
...
...
@@ -373,28 +352,27 @@ static int Manage( vout_thread_t *p_vout )
* This function sends the currently rendered image to the display, wait until
* it is displayed and switch the two rendering buffers, preparing next frame.
*****************************************************************************/
static
void
Display
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
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
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
LPDIRECT3DDEVICE9
p_d3ddev
=
p_sys
->
p_d3ddev
;
VLC_UNUSED
(
p_pic
)
;
// Present the back buffer contents to the display
// No stretching should happen here !
RECT
src
=
p_
vout
->
p_
sys
->
rect_dest_clipped
;
RECT
dst
=
p_
vout
->
p_
sys
->
rect_dest_clipped
;
RECT
src
=
p_sys
->
rect_dest_clipped
;
RECT
dst
=
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
);
if
(
FAILED
(
hr
)
)
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
}
/*
** this function is only used once when the first picture is received
** this function will show the video window once a picture is ready
*/
static
void
FirstDisplay
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
static
void
FirstDisplay
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
/* get initial picture presented through D3D */
Display
(
p_vout
,
p_pic
);
...
...
@@ -403,13 +381,13 @@ static void FirstDisplay( vout_thread_t *p_vout, picture_t *p_pic )
** Video window is initially hidden, show it now since we got a
** picture to show.
*/
SetWindowPos
(
p_vout
->
p_sys
->
hvideownd
,
0
,
0
,
0
,
0
,
0
,
SWP_ASYNCWINDOWPOS
|
SWP_FRAMECHANGED
|
SWP_SHOWWINDOW
|
SWP_NOMOVE
|
SWP_NOSIZE
|
SWP_NOZORDER
);
SetWindowPos
(
p_vout
->
p_sys
->
hvideownd
,
0
,
0
,
0
,
0
,
0
,
SWP_ASYNCWINDOWPOS
|
SWP_FRAMECHANGED
|
SWP_SHOWWINDOW
|
SWP_NOMOVE
|
SWP_NOSIZE
|
SWP_NOZORDER
);
/* use and restores proper display function for further pictures */
p_vout
->
pf_display
=
Display
;
...
...
@@ -421,47 +399,40 @@ static void FirstDisplay( vout_thread_t *p_vout, picture_t *p_pic )
* This function initialize Direct3D and analyze available resources from
* default adapter.
*****************************************************************************/
static
int
Direct3D
VoutCreate
(
vout_thread_t
*
p_vout
)
static
int
Direct3D
Create
(
vout_thread_t
*
p_vout
)
{
HRESULT
hr
;
LPDIRECT3D9
p_d3dobj
;
D3DCAPS9
d3dCaps
;
LPDIRECT3D9
(
WINAPI
*
OurDirect3DCreate9
)(
UINT
SDKVersion
);
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
p_vout
->
p_sys
->
hd3d9_dll
=
LoadLibrary
(
TEXT
(
"D3D9.DLL"
));
if
(
NULL
==
p_vout
->
p_sys
->
hd3d9_dll
)
{
msg_Warn
(
p_vout
,
"cannot load d3d9.dll, aborting"
);
p_sys
->
hd3d9_dll
=
LoadLibrary
(
TEXT
(
"D3D9.DLL"
));
if
(
!
p_sys
->
hd3d9_dll
)
{
msg_Warn
(
p_vout
,
"cannot load d3d9.dll, aborting"
);
return
VLC_EGENERIC
;
}
LPDIRECT3D9
(
WINAPI
*
OurDirect3DCreate9
)(
UINT
SDKVersion
);
OurDirect3DCreate9
=
(
void
*
)
GetProcAddress
(
p_vout
->
p_sys
->
hd3d9_dll
,
TEXT
(
"Direct3DCreate9"
)
);
if
(
OurDirect3DCreate9
==
NULL
)
{
msg_Err
(
p_vout
,
"Cannot locate reference to Direct3DCreate9 ABI in DLL"
);
(
void
*
)
GetProcAddress
(
p_sys
->
hd3d9_dll
,
TEXT
(
"Direct3DCreate9"
));
if
(
!
OurDirect3DCreate9
)
{
msg_Err
(
p_vout
,
"Cannot locate reference to Direct3DCreate9 ABI in DLL"
);
return
VLC_EGENERIC
;
}
/* Create the D3D object. */
p_d3dobj
=
OurDirect3DCreate9
(
D3D_SDK_VERSION
);
if
(
NULL
==
p_d3dobj
)
{
msg_Err
(
p_vout
,
"Could not create Direct3D9 instance."
);
LPDIRECT3D9
p_d3dobj
=
OurDirect3DCreate9
(
D3D_SDK_VERSION
);
if
(
!
p_d3dobj
)
{
msg_Err
(
p_vout
,
"Could not create Direct3D9 instance."
);
return
VLC_EGENERIC
;
}
p_
vout
->
p_
sys
->
p_d3dobj
=
p_d3dobj
;
p_sys
->
p_d3dobj
=
p_d3dobj
;
/*
** Get device capabilities
*/
D3DCAPS9
d3dCaps
;
ZeroMemory
(
&
d3dCaps
,
sizeof
(
d3dCaps
));
hr
=
IDirect3D9_GetDeviceCaps
(
p_d3dobj
,
D3DADAPTER_DEFAULT
,
D3DDEVTYPE_HAL
,
&
d3dCaps
);
if
(
FAILED
(
hr
)
)
{
msg_Err
(
p_vout
,
"Could not read adapter capabilities. (hr=0x%lX)"
,
hr
);
HRESULT
hr
=
IDirect3D9_GetDeviceCaps
(
p_d3dobj
,
D3DADAPTER_DEFAULT
,
D3DDEVTYPE_HAL
,
&
d3dCaps
);
if
(
FAILED
(
hr
))
{
msg_Err
(
p_vout
,
"Could not read adapter capabilities. (hr=0x%lX)"
,
hr
);
return
VLC_EGENERIC
;
}
/* TODO: need to test device capabilities and select the right render function */
...
...
@@ -472,24 +443,23 @@ static int Direct3DVoutCreate( vout_thread_t *p_vout )
/*****************************************************************************
* DirectD3DVoutRelease: release an instance of Direct3D9
*****************************************************************************/
static
void
Direct3DVoutRelease
(
vout_thread_t
*
p_vout
)
static
void
Direct3DRelease
(
vout_thread_t
*
p_vout
)
{
if
(
p_vout
->
p_sys
->
p_d3dobj
)
{
IDirect3D9_Release
(
p_vout
->
p_sys
->
p_d3dobj
);
p_vout
->
p_sys
->
p_d3dobj
=
NULL
;
}
if
(
NULL
!=
p_vout
->
p_sys
->
hd3d9_dll
)
{
FreeLibrary
(
p_vout
->
p_sys
->
hd3d9_dll
);
p_vout
->
p_sys
->
hd3d9_dll
=
NULL
;
}
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
if
(
p_sys
->
p_d3dobj
)
IDirect3D9_Release
(
p_sys
->
p_d3dobj
);
if
(
p_sys
->
hd3d9_dll
)
FreeLibrary
(
p_sys
->
hd3d9_dll
);
p_sys
->
p_d3dobj
=
NULL
;
p_sys
->
hd3d9_dll
=
NULL
;
}
static
int
Direct3DFillPresentationParameters
(
vout_thread_t
*
p_vout
)
{
LPDIRECT3D9
p_d3dobj
=
p_vout
->
p_sys
->
p_d3dobj
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
LPDIRECT3D9
p_d3dobj
=
p_sys
->
p_d3dobj
;
D3DDISPLAYMODE
d3ddm
;
HRESULT
hr
;
...
...
@@ -497,16 +467,15 @@ static int Direct3DFillPresentationParameters(vout_thread_t *p_vout)
** Get the current desktop display mode, so we can set up a back
** buffer of the same format
*/
hr
=
IDirect3D9_GetAdapterDisplayMode
(
p_d3dobj
,
D3DADAPTER_DEFAULT
,
&
d3ddm
);
if
(
FAILED
(
hr
))
{
msg_Err
(
p_vout
,
"Could not read adapter display mode. (hr=0x%lX)"
,
hr
);
hr
=
IDirect3D9_GetAdapterDisplayMode
(
p_d3dobj
,
D3DADAPTER_DEFAULT
,
&
d3ddm
);
if
(
FAILED
(
hr
))
{
msg_Err
(
p_vout
,
"Could not read adapter display mode. (hr=0x%lX)"
,
hr
);
return
VLC_EGENERIC
;
}
/* 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
->
Windowed
=
TRUE
;
d3dpp
->
hDeviceWindow
=
p_vout
->
p_sys
->
hvideownd
;
...
...
@@ -545,44 +514,44 @@ static int Direct3DFillPresentationParameters(vout_thread_t *p_vout)
* this must be called from the vout thread for performance reason, as
* all Direct3D Device APIs are used in a non multithread safe environment
*****************************************************************************/
static
int
Direct3D
VoutOpen
(
vout_thread_t
*
p_vout
)
static
int
Direct3D
Open
(
vout_thread_t
*
p_vout
)
{
LPDIRECT3D9
p_d3dobj
=
p_vout
->
p_sys
->
p_d3dobj
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
LPDIRECT3D9
p_d3dobj
=
p_sys
->
p_d3dobj
;
LPDIRECT3DDEVICE9
p_d3ddev
;
HRESULT
hr
;
if
(
VLC_SUCCESS
!=
Direct3DFillPresentationParameters
(
p_vout
)
)
if
(
Direct3DFillPresentationParameters
(
p_vout
)
)
return
VLC_EGENERIC
;
// Create the D3DDevice
hr
=
IDirect3D9_CreateDevice
(
p_d3dobj
,
D3DADAPTER_DEFAULT
,
D3DDEVTYPE_HAL
,
p_
vout
->
p_
sys
->
hvideownd
,
D3DDEVTYPE_HAL
,
p_sys
->
hvideownd
,
D3DCREATE_SOFTWARE_VERTEXPROCESSING
|
D3DCREATE_MULTITHREADED
,
&
p_vout
->
p_sys
->
d3dpp
,
&
p_d3ddev
);
if
(
FAILED
(
hr
)
)
{
&
p_sys
->
d3dpp
,
&
p_d3ddev
);
if
(
FAILED
(
hr
))
{
msg_Err
(
p_vout
,
"Could not create the D3D device! (hr=0x%lX)"
,
hr
);
return
VLC_EGENERIC
;
}
p_
vout
->
p_
sys
->
p_d3ddev
=
p_d3ddev
;
p_sys
->
p_d3ddev
=
p_d3ddev
;
msg_Dbg
(
p_vout
,
"Direct3D device adapter successfully initialized"
);
msg_Dbg
(
p_vout
,
"Direct3D device adapter successfully initialized"
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* DirectD3DClose: release the Direct3D9 device
*****************************************************************************/
static
void
Direct3D
VoutClose
(
vout_thread_t
*
p_vout
)
static
void
Direct3D
Close
(
vout_thread_t
*
p_vout
)
{
if
(
p_vout
->
p_sys
->
p_d3ddev
)
{
IDirect3DDevice9_Release
(
p_vout
->
p_sys
->
p_d3ddev
);
p_vout
->
p_sys
->
p_d3ddev
=
NULL
;
}
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
p_vout
->
p_sys
->
hmonitor
=
NULL
;
if
(
p_sys
->
p_d3ddev
)
IDirect3DDevice9_Release
(
p_sys
->
p_d3ddev
);
p_sys
->
p_d3ddev
=
NULL
;
p_sys
->
hmonitor
=
NULL
;
}
/*****************************************************************************
...
...
@@ -591,47 +560,44 @@ static void Direct3DVoutClose( vout_thread_t *p_vout )
* All resources must be deallocated before the reset occur, they will be
* realllocated once the reset has been performed successfully
*****************************************************************************/
static
int
Direct3D
VoutResetDevice
(
vout_thread_t
*
p_vout
)
static
int
Direct3D
ResetDevice
(
vout_thread_t
*
p_vout
)
{
LPDIRECT3DDEVICE9
p_d3ddev
=
p_vout
->
p_sys
->
p_d3ddev
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
LPDIRECT3DDEVICE9
p_d3ddev
=
p_sys
->
p_d3ddev
;
HRESULT
hr
;
if
(
VLC_SUCCESS
!=
Direct3DFillPresentationParameters
(
p_vout
)
)
if
(
Direct3DFillPresentationParameters
(
p_vout
)
)
return
VLC_EGENERIC
;
// release all D3D objects
Direct3D
VoutReleaseScene
(
p_vout
);
Direct3D
VoutReleasePictures
(
p_vout
);
Direct3D
ReleaseScene
(
p_vout
);
Direct3D
ReleasePictures
(
p_vout
);
hr
=
IDirect3DDevice9_Reset
(
p_d3ddev
,
&
p_vout
->
p_sys
->
d3dpp
);
if
(
SUCCEEDED
(
hr
)
)
{
// re-create them
if
(
(
VLC_SUCCESS
!=
Direct3DVoutCreatePictures
(
p_vout
,
1
))
||
(
VLC_SUCCESS
!=
Direct3DVoutCreateScene
(
p_vout
))
)
{
msg_Dbg
(
p_vout
,
"%s failed !"
,
__FUNCTION__
);
return
VLC_EGENERIC
;
}
}
else
{
hr
=
IDirect3DDevice9_Reset
(
p_d3ddev
,
&
p_sys
->
d3dpp
);
if
(
FAILED
(
hr
))
{
msg_Err
(
p_vout
,
"%s failed ! (hr=%08lX)"
,
__FUNCTION__
,
hr
);
return
VLC_EGENERIC
;
}
// re-create them
if
(
Direct3DCreatePictures
(
p_vout
,
1
)
||
Direct3DCreateScene
(
p_vout
))
{
msg_Dbg
(
p_vout
,
"%s failed !"
,
__FUNCTION__
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
static
int
Direct3D
VoutCheckFormat
(
vout_thread_t
*
p_vout
,
D3DFORMAT
target
,
D3DFORMAT
format
)
static
int
Direct3D
CheckFormat
(
vout_thread_t
*
p_vout
,
D3DFORMAT
target
,
D3DFORMAT
format
)
{
LPDIRECT3D9
p_d3dobj
=
p_vout
->
p_sys
->
p_d3dobj
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
LPDIRECT3D9
p_d3dobj
=
p_sys
->
p_d3dobj
;
HRESULT
hr
;
/* test whether device can create a surface of that format */
hr
=
IDirect3D9_CheckDeviceFormat
(
p_d3dobj
,
D3DADAPTER_DEFAULT
,
D3DDEVTYPE_HAL
,
target
,
0
,
D3DRTYPE_SURFACE
,
format
);
if
(
SUCCEEDED
(
hr
)
)
{
D3DDEVTYPE_HAL
,
target
,
0
,
D3DRTYPE_SURFACE
,
format
);
if
(
SUCCEEDED
(
hr
))
{
/* test whether device can perform color-conversion
** from that format to target format
*/
...
...
@@ -640,10 +606,9 @@ static int Direct3DVoutCheckFormat( vout_thread_t *p_vout,
D3DDEVTYPE_HAL
,
format
,
target
);
}
if
(
!
SUCCEEDED
(
hr
)
)
{
if
(
D3DERR_NOTAVAILABLE
!=
hr
)
msg_Err
(
p_vout
,
"Could not query adapter supported formats. (hr=0x%lX)"
,
hr
);
if
(
!
SUCCEEDED
(
hr
))
{
if
(
D3DERR_NOTAVAILABLE
!=
hr
)
msg_Err
(
p_vout
,
"Could not query adapter supported formats. (hr=0x%lX)"
,
hr
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
...
...
@@ -675,34 +640,32 @@ static const d3d_format_t p_d3d_formats[] = {
{
NULL
,
0
,
0
,
0
,
0
,
0
}
};
static
const
d3d_format_t
*
Direct3D
VoutFindFormat
(
vout_thread_t
*
p_vout
,
in
t
i_chroma
,
D3DFORMAT
target
)
static
const
d3d_format_t
*
Direct3D
FindFormat
(
vout_thread_t
*
p_vout
,
vlc_fourcc_
t
i_chroma
,
D3DFORMAT
target
)
{
for
(
unsigned
pass
=
0
;
pass
<
2
;
pass
++
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
for
(
unsigned
pass
=
0
;
pass
<
2
;
pass
++
)
{
const
vlc_fourcc_t
*
p_chromas
;
if
(
pass
==
0
&&
p_vout
->
p_sys
->
b_hw_yuv
&&
vlc_fourcc_IsYUV
(
i_chroma
)
)
p_chromas
=
vlc_fourcc_GetYUVFallback
(
i_chroma
);
else
if
(
pass
==
1
)
p_chromas
=
vlc_fourcc_GetRGBFallback
(
i_chroma
);
if
(
pass
==
0
&&
p_sys
->
b_hw_yuv
&&
vlc_fourcc_IsYUV
(
i_chroma
)
)
p_chromas
=
vlc_fourcc_GetYUVFallback
(
i_chroma
);
else
if
(
pass
==
1
)
p_chromas
=
vlc_fourcc_GetRGBFallback
(
i_chroma
);
else
continue
;
for
(
unsigned
i
=
0
;
p_chromas
[
i
]
!=
0
;
i
++
)
{
for
(
unsigned
j
=
0
;
p_d3d_formats
[
j
].
name
;
j
++
)
{
for
(
unsigned
i
=
0
;
p_chromas
[
i
]
!=
0
;
i
++
)
{
for
(
unsigned
j
=
0
;
p_d3d_formats
[
j
].
name
;
j
++
)
{
const
d3d_format_t
*
p_format
=
&
p_d3d_formats
[
j
];
if
(
p_format
->
fourcc
!=
p_chromas
[
i
]
)
if
(
p_format
->
fourcc
!=
p_chromas
[
i
]
)
continue
;
msg_Warn
(
p_vout
,
"trying surface pixel format: %s"
,
p_format
->
name
);
if
(
!
Direct3DVoutCheckFormat
(
p_vout
,
target
,
p_format
->
format
)
)
{
msg_Dbg
(
p_vout
,
"selected surface pixel format is %s"
,
p_format
->
name
);
msg_Warn
(
p_vout
,
"trying surface pixel format: %s"
,
p_format
->
name
);
if
(
!
Direct3DCheckFormat
(
p_vout
,
target
,
p_format
->
format
))
{
msg_Dbg
(
p_vout
,
"selected surface pixel format is %s"
,
p_format
->
name
);
return
p_format
;
}
}
...
...
@@ -712,21 +675,22 @@ static const d3d_format_t *Direct3DVoutFindFormat(vout_thread_t *p_vout, int i_c
}
/*****************************************************************************
* Direct3D
Vout
CreatePictures: allocate a vector of identical pictures
* Direct3DCreatePictures: allocate a vector of identical pictures
*****************************************************************************
* Each picture has an associated offscreen surface in video memory
* depending on hardware capabilities the picture chroma will be as close
* as possible to the orginal render chroma to reduce CPU conversion overhead
* and delegate this work to video card GPU
*****************************************************************************/
static
int
Direct3D
VoutCreatePictures
(
vout_thread_t
*
p_vout
,
size_t
i_num_pics
)
static
int
Direct3D
CreatePictures
(
vout_thread_t
*
p_vout
,
size_t
i_num_pics
)
{
LPDIRECT3DDEVICE9
p_d3ddev
=
p_vout
->
p_sys
->
p_d3ddev
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
LPDIRECT3DDEVICE9
p_d3ddev
=
p_sys
->
p_d3ddev
;
HRESULT
hr
;
size_t
c
;
// if vout is already running, use current chroma, otherwise choose from upstream
in
t
i_chroma
=
p_vout
->
output
.
i_chroma
?
p_vout
->
output
.
i_chroma
:
p_vout
->
render
.
i_chroma
;
vlc_fourcc_
t
i_chroma
=
p_vout
->
output
.
i_chroma
?
p_vout
->
output
.
i_chroma
:
p_vout
->
render
.
i_chroma
;
I_OUTPUTPICTURES
=
0
;
...
...
@@ -735,9 +699,8 @@ 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
*/
const
d3d_format_t
*
p_format
=
Direct3DVoutFindFormat
(
p_vout
,
i_chroma
,
p_vout
->
p_sys
->
d3dpp
.
BackBufferFormat
);
if
(
!
p_format
)
{
const
d3d_format_t
*
p_format
=
Direct3DFindFormat
(
p_vout
,
i_chroma
,
p_sys
->
d3dpp
.
BackBufferFormat
);
if
(
!
p_format
)
{
msg_Err
(
p_vout
,
"surface pixel format is not supported."
);
return
VLC_EGENERIC
;
}
...
...
@@ -747,164 +710,155 @@ static int Direct3DVoutCreatePictures( vout_thread_t *p_vout, size_t i_num_pics
p_vout
->
output
.
i_bmask
=
p_format
->
bmask
;
/* */
for
(
c
=
0
;
c
<
i_num_pics
;
)
{
for
(
c
=
0
;
c
<
i_num_pics
;)
{
LPDIRECT3DSURFACE9
p_d3dsurf
;
picture_t
*
p_pic
=
p_vout
->
p_picture
+
c
;
hr
=
IDirect3DDevice9_CreateOffscreenPlainSurface
(
p_d3ddev
,
p_vout
->
render
.
i_width
,
p_vout
->
render
.
i_height
,
p_format
->
format
,
D3DPOOL_DEFAULT
,
&
p_d3dsurf
,
NULL
);
if
(
FAILED
(
hr
)
)
{
p_vout
->
render
.
i_width
,
p_vout
->
render
.
i_height
,
p_format
->
format
,
D3DPOOL_DEFAULT
,
&
p_d3dsurf
,
NULL
);
if
(
FAILED
(
hr
))
{
msg_Err
(
p_vout
,
"Failed to create picture surface. (hr=0x%lx)"
,
hr
);
Direct3D
Vout
ReleasePictures
(
p_vout
);
Direct3DReleasePictures
(
p_vout
);
return
VLC_EGENERIC
;
}
/* fill surface with black color */
IDirect3DDevice9_ColorFill
(
p_d3ddev
,
p_d3dsurf
,
NULL
,
D3DCOLOR_ARGB
(
0xFF
,
0
,
0
,
0
)
);
IDirect3DDevice9_ColorFill
(
p_d3ddev
,
p_d3dsurf
,
NULL
,
D3DCOLOR_ARGB
(
0xFF
,
0
,
0
,
0
));
/* */
video_format_Setup
(
&
p_pic
->
format
,
p_vout
->
output
.
i_chroma
,
p_vout
->
output
.
i_width
,
p_vout
->
output
.
i_height
,
p_vout
->
output
.
i_aspect
);
video_format_Setup
(
&
p_pic
->
format
,
p_vout
->
output
.
i_chroma
,
p_vout
->
output
.
i_width
,
p_vout
->
output
.
i_height
,
p_vout
->
output
.
i_aspect
);
/* assign surface to internal structure */
p_pic
->
p_sys
=
(
void
*
)
p_d3dsurf
;
/* Now that we've got our direct-buffer, we can finish filling in the
* picture_t structures */
switch
(
p_vout
->
output
.
i_chroma
)
{
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_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
switch
(
p_vout
->
output
.
i_chroma
)
{
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_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
break
;
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_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
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_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
break
;
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_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
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_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
break
;
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_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
break
;
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
;
p_pic
->
p
->
i_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
break
;
case
VLC_CODEC_I420
:
case
VLC_CODEC_J420
:
case
VLC_CODEC_YV12
:
p_pic
->
i_planes
=
3
;
for
(
int
n
=
0
;
n
<
p_pic
->
i_planes
;
n
++
)
{
const
unsigned
d
=
1
+
(
n
>
0
);
plane_t
*
p
=
&
p_pic
->
p
[
n
];
p
->
i_pixel_pitch
=
1
;
p
->
i_lines
=
p
->
i_visible_lines
=
p_vout
->
output
.
i_height
/
d
;
p
->
i_visible_pitch
=
p_vout
->
output
.
i_width
/
d
;
}
break
;
default:
Direct3DVout
ReleasePictures
(
p_vout
);
return
VLC_EGENERIC
;
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_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
break
;
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
;
p_pic
->
p
->
i_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
break
;
case
VLC_CODEC_I420
:
case
VLC_CODEC_J420
:
case
VLC_CODEC_YV12
:
p_pic
->
i_planes
=
3
;
for
(
int
n
=
0
;
n
<
p_pic
->
i_planes
;
n
++
)
{
const
unsigned
d
=
1
+
(
n
>
0
);
plane_t
*
p
=
&
p_pic
->
p
[
n
];
p
->
i_pixel_pitch
=
1
;
p
->
i_lines
=
p
->
i_visible_lines
=
p_vout
->
output
.
i_height
/
d
;
p
->
i_visible_pitch
=
p_vout
->
output
.
i_width
/
d
;
}
break
;
default:
Direct3D
ReleasePictures
(
p_vout
);
return
VLC_EGENERIC
;
}
p_pic
->
i_status
=
DESTROYED_PICTURE
;
p_pic
->
i_type
=
DIRECT_PICTURE
;
p_pic
->
b_slow
=
true
;
p_pic
->
pf_lock
=
Direct3D
Vout
LockSurface
;
p_pic
->
pf_unlock
=
Direct3D
Vout
UnlockSurface
;
p_pic
->
pf_lock
=
Direct3DLockSurface
;
p_pic
->
pf_unlock
=
Direct3DUnlockSurface
;
PP_OUTPUTPICTURE
[
c
]
=
p_pic
;
I_OUTPUTPICTURES
=
++
c
;
}
msg_Dbg
(
p_vout
,
"%u Direct3D pictures created successfully"
,
c
);
msg_Dbg
(
p_vout
,
"%u Direct3D pictures created successfully"
,
c
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Direct3D
Vout
ReleasePictures: destroy a picture vector
* Direct3DReleasePictures: destroy a picture vector
*****************************************************************************
* release all video resources used for pictures
*****************************************************************************/
static
void
Direct3D
VoutReleasePictures
(
vout_thread_t
*
p_vout
)
static
void
Direct3D
ReleasePictures
(
vout_thread_t
*
p_vout
)
{
size_t
i_num_pics
=
I_OUTPUTPICTURES
;
size_t
c
;
for
(
c
=
0
;
c
<
i_num_pics
;
++
c
)
{
picture_t
*
p_pic
=
p_vout
->
p_picture
+
c
;
if
(
p_pic
->
p_sys
)
{
LPDIRECT3DSURFACE9
p_d3dsurf
=
(
LPDIRECT3DSURFACE9
)
p_pic
->
p_sys
;
for
(
c
=
0
;
c
<
i_num_pics
;
c
++
)
{
picture_t
*
p_pic
=
&
p_vout
->
p_picture
[
c
];
if
(
!
p_pic
->
p_sys
)
continue
;
p_pic
->
p_sys
=
NULL
;
LPDIRECT3DSURFACE9
p_d3dsurf
=
(
LPDIRECT3DSURFACE9
)
p_pic
->
p_sys
;
if
(
p_d3dsurf
)
IDirect3DSurface9_Release
(
p_d3dsurf
);
if
(
p_d3dsurf
)
{
IDirect3DSurface9_Release
(
p_d3dsurf
);
}
}
p_pic
->
p_sys
=
NULL
;
}
msg_Dbg
(
p_vout
,
"%u Direct3D pictures released."
,
c
);
msg_Dbg
(
p_vout
,
"%u Direct3D pictures released."
,
c
);
I_OUTPUTPICTURES
=
0
;
}
/*****************************************************************************
* Direct3D
Vout
LockSurface: Lock surface and get picture data pointer
* Direct3DLockSurface: Lock surface and get picture data pointer
*****************************************************************************
* This function locks a surface and get the surface descriptor which amongst
* other things has the pointer to the picture data.
*****************************************************************************/
static
int
Direct3D
VoutLockSurface
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
static
int
Direct3D
LockSurface
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
HRESULT
hr
;
D3DLOCKED_RECT
d3drect
;
LPDIRECT3DSURFACE9
p_d3dsurf
=
(
LPDIRECT3DSURFACE9
)
p_pic
->
p_sys
;
if
(
NULL
==
p_d3dsurf
)
if
(
!
p_d3dsurf
)
return
VLC_EGENERIC
;
/* Lock the surface to get a valid pointer to the picture buffer */
hr
=
IDirect3DSurface9_LockRect
(
p_d3dsurf
,
&
d3drect
,
NULL
,
0
)
;
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
D3DLOCKED_RECT
d3drect
;
HRESULT
hr
=
IDirect3DSurface9_LockRect
(
p_d3dsurf
,
&
d3drect
,
NULL
,
0
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
return
VLC_EGENERIC
;
}
...
...
@@ -913,12 +867,11 @@ static int Direct3DVoutLockSurface( vout_thread_t *p_vout, picture_t *p_pic )
p_pic
->
p
->
i_pitch
=
d3drect
.
Pitch
;
/* Fill chroma planes for planar YUV */
if
(
p_pic
->
format
.
i_chroma
==
VLC_CODEC_I420
||
if
(
p_pic
->
format
.
i_chroma
==
VLC_CODEC_I420
||
p_pic
->
format
.
i_chroma
==
VLC_CODEC_J420
||
p_pic
->
format
.
i_chroma
==
VLC_CODEC_YV12
)
{
for
(
int
n
=
1
;
n
<
p_pic
->
i_planes
;
n
++
)
{
p_pic
->
format
.
i_chroma
==
VLC_CODEC_YV12
)
{
for
(
int
n
=
1
;
n
<
p_pic
->
i_planes
;
n
++
)
{
const
plane_t
*
o
=
&
p_pic
->
p
[
n
-
1
];
plane_t
*
p
=
&
p_pic
->
p
[
n
];
...
...
@@ -926,8 +879,7 @@ static int Direct3DVoutLockSurface( vout_thread_t *p_vout, picture_t *p_pic )
p
->
i_pitch
=
d3drect
.
Pitch
/
2
;
}
/* The d3d buffer is always allocated as YV12 */
if
(
vlc_fourcc_AreUVPlanesSwapped
(
p_pic
->
format
.
i_chroma
,
VLC_CODEC_YV12
)
)
{
if
(
vlc_fourcc_AreUVPlanesSwapped
(
p_pic
->
format
.
i_chroma
,
VLC_CODEC_YV12
))
{
uint8_t
*
p_tmp
=
p_pic
->
p
[
1
].
p_pixels
;
p_pic
->
p
[
1
].
p_pixels
=
p_pic
->
p
[
2
].
p_pixels
;
p_pic
->
p
[
2
].
p_pixels
=
p_tmp
;
...
...
@@ -938,35 +890,33 @@ static int Direct3DVoutLockSurface( vout_thread_t *p_vout, picture_t *p_pic )
}
/*****************************************************************************
* Direct3D
Vout
UnlockSurface: Unlock a surface locked by Direct3DLockSurface().
* Direct3DUnlockSurface: Unlock a surface locked by Direct3DLockSurface().
*****************************************************************************/
static
int
Direct3D
VoutUnlockSurface
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
static
int
Direct3D
UnlockSurface
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
HRESULT
hr
;
LPDIRECT3DSURFACE9
p_d3dsurf
=
(
LPDIRECT3DSURFACE9
)
p_pic
->
p_sys
;
if
(
NULL
==
p_d3dsurf
)
if
(
!
p_d3dsurf
)
return
VLC_EGENERIC
;
/* Unlock the Surface */
hr
=
IDirect3DSurface9_UnlockRect
(
p_d3dsurf
);
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
HRESULT
hr
=
IDirect3DSurface9_UnlockRect
(
p_d3dsurf
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Direct3D
Vout
CreateScene: allocate and initialize a 3D scene
* Direct3DCreateScene: allocate and initialize a 3D scene
*****************************************************************************
* for advanced blending/filtering a texture needs be used in a 3D scene.
*****************************************************************************/
static
int
Direct3DVoutCreateScene
(
vout_thread_t
*
p_vout
)
static
int
Direct3DCreateScene
(
vout_thread_t
*
p_vout
)
{
LPDIRECT3DDEVICE9
p_d3ddev
=
p_vout
->
p_sys
->
p_d3ddev
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
LPDIRECT3DDEVICE9
p_d3ddev
=
p_sys
->
p_d3ddev
;
LPDIRECT3DTEXTURE9
p_d3dtex
;
LPDIRECT3DVERTEXBUFFER9
p_d3dvtc
;
...
...
@@ -978,16 +928,15 @@ static int Direct3DVoutCreateScene( vout_thread_t *p_vout )
** which would usually be a RGB format
*/
hr
=
IDirect3DDevice9_CreateTexture
(
p_d3ddev
,
p_vout
->
p_sys
->
d3dpp
.
BackBufferWidth
,
p_vout
->
p_sys
->
d3dpp
.
BackBufferHeight
,
1
,
D3DUSAGE_RENDERTARGET
,
p_vout
->
p_sys
->
d3dpp
.
BackBufferFormat
,
D3DPOOL_DEFAULT
,
&
p_d3dtex
,
NULL
);
if
(
FAILED
(
hr
))
{
p_sys
->
d3dpp
.
BackBufferWidth
,
p_sys
->
d3dpp
.
BackBufferHeight
,
1
,
D3DUSAGE_RENDERTARGET
,
p_sys
->
d3dpp
.
BackBufferFormat
,
D3DPOOL_DEFAULT
,
&
p_d3dtex
,
NULL
);
if
(
FAILED
(
hr
))
{
msg_Err
(
p_vout
,
"Failed to create texture. (hr=0x%lx)"
,
hr
);
return
VLC_EGENERIC
;
}
...
...
@@ -996,21 +945,20 @@ static int Direct3DVoutCreateScene( vout_thread_t *p_vout )
** Create a vertex buffer for use when rendering scene
*/
hr
=
IDirect3DDevice9_CreateVertexBuffer
(
p_d3ddev
,
sizeof
(
CUSTOMVERTEX
)
*
4
,
D3DUSAGE_DYNAMIC
|
D3DUSAGE_WRITEONLY
,
D3DFVF_CUSTOMVERTEX
,
D3DPOOL_DEFAULT
,
&
p_d3dvtc
,
NULL
);
if
(
FAILED
(
hr
)
)
{
sizeof
(
CUSTOMVERTEX
)
*
4
,
D3DUSAGE_DYNAMIC
|
D3DUSAGE_WRITEONLY
,
D3DFVF_CUSTOMVERTEX
,
D3DPOOL_DEFAULT
,
&
p_d3dvtc
,
NULL
);
if
(
FAILED
(
hr
))
{
msg_Err
(
p_vout
,
"Failed to create vertex buffer. (hr=0x%lx)"
,
hr
);
IDirect3DTexture9_Release
(
p_d3dtex
);
return
VLC_EGENERIC
;
}
p_
vout
->
p_
sys
->
p_d3dtex
=
p_d3dtex
;
p_
vout
->
p_
sys
->
p_d3dvtc
=
p_d3dvtc
;
p_sys
->
p_d3dtex
=
p_d3dtex
;
p_sys
->
p_d3dvtc
=
p_d3dvtc
;
// Texture coordinates outside the range [0.0, 1.0] are set
// to the texture color at 0.0 or 1.0, respectively.
...
...
@@ -1055,31 +1003,29 @@ static int Direct3DVoutCreateScene( vout_thread_t *p_vout )
// turn off alpha operation
IDirect3DDevice9_SetTextureStageState
(
p_d3ddev
,
0
,
D3DTSS_ALPHAOP
,
D3DTOP_DISABLE
);
msg_Dbg
(
p_vout
,
"Direct3D scene created successfully"
);
msg_Dbg
(
p_vout
,
"Direct3D scene created successfully"
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Direct3D
Vout
ReleaseScene
* Direct3DReleaseScene
*****************************************************************************/
static
void
Direct3D
VoutReleaseScene
(
vout_thread_t
*
p_vout
)
static
void
Direct3D
ReleaseScene
(
vout_thread_t
*
p_vout
)
{
LPDIRECT3DTEXTURE9
p_d3dtex
=
p_vout
->
p_sys
->
p_d3dtex
;
LPDIRECT3DVERTEXBUFFER9
p_d3dvtc
=
p_vout
->
p_sys
->
p_d3dvtc
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
if
(
p_d3dvtc
)
{
LPDIRECT3DVERTEXBUFFER9
p_d3dvtc
=
p_sys
->
p_d3dvtc
;
if
(
p_d3dvtc
)
IDirect3DVertexBuffer9_Release
(
p_d3dvtc
);
p_vout
->
p_sys
->
p_d3dvtc
=
NULL
;
}
if
(
p_d3dtex
)
{
LPDIRECT3DTEXTURE9
p_d3dtex
=
p_sys
->
p_d3dtex
;
if
(
p_d3dtex
)
IDirect3DTexture9_Release
(
p_d3dtex
);
p_vout
->
p_sys
->
p_d3dtex
=
NULL
;
}
msg_Dbg
(
p_vout
,
"Direct3D scene released successfully"
);
p_sys
->
p_d3dvtc
=
NULL
;
p_sys
->
p_d3dtex
=
NULL
;
msg_Dbg
(
p_vout
,
"Direct3D scene released successfully"
);
}
/*****************************************************************************
...
...
@@ -1088,51 +1034,43 @@ static void Direct3DVoutReleaseScene( vout_thread_t *p_vout )
* This function is intented for higher end 3D cards, with pixel shader support
* and at least 64 MB of video RAM.
*****************************************************************************/
static
void
Direct3D
VoutRenderScene
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
static
void
Direct3D
RenderScene
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
LPDIRECT3DDEVICE9
p_d3ddev
=
p_vout
->
p_sys
->
p_d3ddev
;
LPDIRECT3DTEXTURE9
p_d3dtex
;
LPDIRECT3DVERTEXBUFFER9
p_d3dvtc
;
LPDIRECT3DSURFACE9
p_d3dsrc
,
p_d3ddest
;
CUSTOMVERTEX
*
p_vertices
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
LPDIRECT3DDEVICE9
p_d3ddev
=
p_sys
->
p_d3ddev
;
HRESULT
hr
;
float
f_width
,
f_height
;
// check if device is still available
hr
=
IDirect3DDevice9_TestCooperativeLevel
(
p_d3ddev
);
if
(
FAILED
(
hr
)
)
{
if
(
(
D3DERR_DEVICENOTRESET
!=
hr
)
||
(
VLC_SUCCESS
!=
Direct3DVoutResetDevice
(
p_vout
))
)
{
if
(
FAILED
(
hr
))
{
if
(
hr
!=
D3DERR_DEVICENOTRESET
||
Direct3DResetDevice
(
p_vout
))
{
// device is not usable at present (lost device, out of video mem ?)
return
;
}
}
p_d3dtex
=
p_vout
->
p_sys
->
p_d3dtex
;
p_d3dvtc
=
p_vout
->
p_sys
->
p_d3dvtc
;
/* */
LPDIRECT3DTEXTURE9
p_d3dtex
=
p_sys
->
p_d3dtex
;
LPDIRECT3DVERTEXBUFFER9
p_d3dvtc
=
p_sys
->
p_d3dvtc
;
/* Clear the backbuffer and the zbuffer */
hr
=
IDirect3DDevice9_Clear
(
p_d3ddev
,
0
,
NULL
,
D3DCLEAR_TARGET
,
D3DCOLOR_XRGB
(
0
,
0
,
0
),
1
.
0
f
,
0
);
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
hr
=
IDirect3DDevice9_Clear
(
p_d3ddev
,
0
,
NULL
,
D3DCLEAR_TARGET
,
D3DCOLOR_XRGB
(
0
,
0
,
0
),
1
.
0
f
,
0
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
return
;
}
/* retrieve picture surface */
p_d3dsrc
=
(
LPDIRECT3DSURFACE9
)
p_pic
->
p_sys
;
if
(
NULL
==
p_d3dsrc
)
{
msg_Dbg
(
p_vout
,
"no surface to render ?"
);
LPDIRECT3DSURFACE9
p_d3dsrc
=
(
LPDIRECT3DSURFACE9
)
p_pic
->
p_sys
;
if
(
!
p_d3dsrc
)
{
msg_Dbg
(
p_vout
,
"no surface to render ?"
);
return
;
}
/* retrieve texture top-level surface */
LPDIRECT3DSURFACE9
p_d3ddest
;
hr
=
IDirect3DTexture9_GetSurfaceLevel
(
p_d3dtex
,
0
,
&
p_d3ddest
);
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
return
;
}
...
...
@@ -1143,23 +1081,22 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
hr
=
IDirect3DDevice9_StretchRect
(
p_d3ddev
,
p_d3dsrc
,
&
src
,
p_d3ddest
,
&
dst
,
D3DTEXF_LINEAR
);
IDirect3DSurface9_Release
(
p_d3ddest
);
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
return
;
}
/* Update the vertex buffer */
CUSTOMVERTEX
*
p_vertices
;
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
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
return
;
}
/* Setup vertices */
f_width
=
(
float
)
p_vout
->
p_sys
->
d3dpp
.
BackBufferWidth
;
f_height
=
(
float
)
p_vout
->
p_sys
->
d3dpp
.
BackBufferHeight
;
f
loat
f
_width
=
(
float
)
p_vout
->
p_sys
->
d3dpp
.
BackBufferWidth
;
f
loat
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/ */
...
...
@@ -1196,17 +1133,15 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
p_vertices
[
3
].
tv
=
1
.
0
f
;
hr
=
IDirect3DVertexBuffer9_Unlock
(
p_d3dvtc
);
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
return
;
}
// Begin the scene
hr
=
IDirect3DDevice9_BeginScene
(
p_d3ddev
);
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
return
;
}
...
...
@@ -1215,45 +1150,40 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
// textures) and lighting information. In this case, we are modulating
// (blending) our texture with the diffuse color of the vertices.
hr
=
IDirect3DDevice9_SetTexture
(
p_d3ddev
,
0
,
(
LPDIRECT3DBASETEXTURE9
)
p_d3dtex
);
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
IDirect3DDevice9_EndScene
(
p_d3ddev
);
return
;
}
// Render the vertex buffer contents
hr
=
IDirect3DDevice9_SetStreamSource
(
p_d3ddev
,
0
,
p_d3dvtc
,
0
,
sizeof
(
CUSTOMVERTEX
));
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
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
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
IDirect3DDevice9_EndScene
(
p_d3ddev
);
return
;
}
// draw rectangle
hr
=
IDirect3DDevice9_DrawPrimitive
(
p_d3ddev
,
D3DPT_TRIANGLEFAN
,
0
,
2
);
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
IDirect3DDevice9_EndScene
(
p_d3ddev
);
return
;
}
// End the scene
hr
=
IDirect3DDevice9_EndScene
(
p_d3ddev
);
if
(
FAILED
(
hr
)
)
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
if
(
FAILED
(
hr
))
{
msg_Dbg
(
p_vout
,
"%s:%d (hr=0x%0lX)"
,
__FUNCTION__
,
__LINE__
,
hr
);
return
;
}
}
...
...
@@ -1261,32 +1191,28 @@ 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
,
static
int
DesktopCallback
(
vlc_object_t
*
object
,
char
const
*
psz_cmd
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
void
*
p_data
)
{
VLC_UNUSED
(
psz_cmd
);
VLC_UNUSED
(
oldval
);
VLC_UNUSED
(
p_data
);
VLC_UNUSED
(
psz_cmd
);
VLC_UNUSED
(
oldval
);
VLC_UNUSED
(
p_data
);
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
object
;
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
((
newval
.
b_bool
&&
!
p_vout
->
p_sys
->
b_desktop
)
||
(
!
newval
.
b_bool
&&
p_vout
->
p_sys
->
b_desktop
))
{
if
(
p_playlist
)
{
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
);
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
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment