Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
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-1.1
Commits
284900dc
Commit
284900dc
authored
Dec 26, 2009
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Converted wingdi/wingapi to vout display.
parent
72974fc1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
324 additions
and
506 deletions
+324
-506
modules/video_output/msw/Modules.am
modules/video_output/msw/Modules.am
+7
-7
modules/video_output/msw/common.c
modules/video_output/msw/common.c
+8
-11
modules/video_output/msw/common.h
modules/video_output/msw/common.h
+11
-25
modules/video_output/msw/wingdi.c
modules/video_output/msw/wingdi.c
+298
-463
No files found.
modules/video_output/msw/Modules.am
View file @
284900dc
...
...
@@ -24,16 +24,16 @@ SOURCES_glwin32 = \
SOURCES_wingdi = \
wingdi.c \
vout
.h \
events
_vo
.h \
events
_vo
.c \
common
_vo
.c \
common
.h \
events.h \
events.c \
common.c \
$(NULL)
SOURCES_wingapi = \
wingdi.c \
vout.h \
events
_vo
.h \
events
_vo
.c \
common
_vo
.c \
events.h \
events.c \
common.c \
$(NULL)
modules/video_output/msw/common.c
View file @
284900dc
...
...
@@ -169,7 +169,7 @@ void CommonManage(vout_display_t *vd)
/* FIXME I find such #ifdef quite weirds. Are they really needed ? */
#if defined(MODULE_NAME_IS_direct3d)
#if defined(MODULE_NAME_IS_direct3d)
|| defined(MODULE_NAME_IS_wingdi) || defined(MODULE_NAME_IS_wingapi)
SetWindowPos
(
sys
->
hwnd
,
0
,
0
,
0
,
rect_parent
.
right
-
rect_parent
.
left
,
rect_parent
.
bottom
-
rect_parent
.
top
,
...
...
@@ -186,15 +186,6 @@ void CommonManage(vout_display_t *vd)
rect_parent
.
right
-
rect_parent
.
left
,
rect_parent
.
bottom
-
rect_parent
.
top
,
0
);
#if defined(MODULE_NAME_IS_wingdi) || defined(MODULE_NAME_IS_wingapi)
unsigned
int
i_x
,
i_y
,
i_width
,
i_height
;
vout_PlacePicture
(
vd
,
rect_parent
.
right
-
rect_parent
.
left
,
rect_parent
.
bottom
-
rect_parent
.
top
,
&
i_x
,
&
i_y
,
&
i_width
,
&
i_height
);
SetWindowPos
(
sys
->
hvideownd
,
HWND_TOP
,
i_x
,
i_y
,
i_width
,
i_height
,
0
);
#endif
#endif
}
}
...
...
@@ -271,7 +262,9 @@ void UpdateRects(vout_display_t *vd,
EventThreadUpdateWindowPosition
(
sys
->
event
,
&
has_moved
,
&
is_resized
,
point
.
x
,
point
.
y
,
rect
.
right
,
rect
.
bottom
);
if
(
!
is_forced
&&
!
has_moved
&&
!
is_resized
)
if
(
is_resized
)
vout_display_SendEventDisplaySize
(
vd
,
rect
.
right
,
rect
.
bottom
,
cfg
->
is_fullscreen
);
if
(
!
is_forced
&&
!
has_moved
&&
!
is_resized
)
return
;
/* Update the window position and size */
...
...
@@ -283,6 +276,10 @@ void UpdateRects(vout_display_t *vd,
vout_display_PlacePicture
(
&
place
,
source
,
&
place_cfg
,
true
);
EventThreadUpdateSourceAndPlace
(
sys
->
event
,
source
,
&
place
);
#if defined(MODULE_NAME_IS_wingapi)
if
(
place
.
width
!=
fmt
->
i_width
||
place
.
height
!=
fmt
->
i_height
)
vout_display_SendEventPicturesInvalid
(
vd
);
#endif
if
(
sys
->
hvideownd
)
SetWindowPos
(
sys
->
hvideownd
,
0
,
...
...
modules/video_output/msw/common.h
View file @
284900dc
...
...
@@ -187,39 +187,24 @@ struct vout_display_sys_t
bool
desktop_requested
;
#endif
#ifdef MODULE_NAME_IS_wingdi
#if defined(MODULE_NAME_IS_wingdi) || defined(MODULE_NAME_IS_wingapi)
int
i_depth
;
/* Our offscreen bitmap and its framebuffer */
HDC
off_dc
;
HBITMAP
off_bitmap
;
uint8_t
*
p_pic_buffer
;
int
i_pic_pitch
;
int
i_pic_pixel_pitch
;
BITMAPINFO
bitmapinfo
;
RGBQUAD
red
;
RGBQUAD
green
;
RGBQUAD
blue
;
#endif
#ifdef MODULE_NAME_IS_wingapi
int
i_depth
;
int
render_width
;
int
render_height
;
/* Our offscreen bitmap and its framebuffer */
HDC
off_dc
;
HBITMAP
off_bitmap
;
uint8_t
*
p_pic_buffer
;
int
i_pic_pitch
;
int
i_pic_pixel_pitch
;
picture_pool_t
*
pool
;
BITMAPINFO
bitmapinfo
;
RGBQUAD
red
;
RGBQUAD
green
;
RGBQUAD
blue
;
struct
{
BITMAPINFO
bitmapinfo
;
RGBQUAD
red
;
RGBQUAD
green
;
RGBQUAD
blue
;
};
# ifdef MODULE_NAME_IS_wingapi
HINSTANCE
gapi_dll
;
/* handle of the opened gapi dll */
/* GAPI functions */
...
...
@@ -230,6 +215,7 @@ struct vout_display_sys_t
GXDisplayProperties
(
*
GXGetDisplayProperties
)();
int
(
*
GXSuspend
)();
int
(
*
GXResume
)();
# endif
#endif
};
...
...
modules/video_output/msw/wingdi.c
View file @
284900dc
...
...
@@ -29,580 +29,415 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_playlist.h>
#include <vlc_vout.h>
#include <vlc_vout
_display
.h>
#include <windows.h>
#include <commctrl.h>
#include "vout.h"
#define MAX_DIRECTBUFFERS 10
#include "common.h"
#ifndef WS_NONAVDONEBUTTON
#define WS_NONAVDONEBUTTON 0
#endif
/*****************************************************************************
* 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
Render
(
vout_thread_t
*
,
picture_t
*
);
#ifdef MODULE_NAME_IS_wingapi
static
void
FirstDisplayGAPI
(
vout_thread_t
*
,
picture_t
*
);
static
void
DisplayGAPI
(
vout_thread_t
*
,
picture_t
*
);
static
int
GAPILockSurface
(
vout_thread_t
*
,
picture_t
*
);
static
int
GAPIUnlockSurface
(
vout_thread_t
*
,
picture_t
*
);
#else
static
void
FirstDisplayGDI
(
vout_thread_t
*
,
picture_t
*
);
static
void
DisplayGDI
(
vout_thread_t
*
,
picture_t
*
);
# define WS_NONAVDONEBUTTON 0
#endif
static
void
SetPalette
(
vout_thread_t
*
,
uint16_t
*
,
uint16_t
*
,
uint16_t
*
);
static
void
InitBuffers
(
vout_thread_t
*
);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
vlc_module_begin
()
set_category
(
CAT_VIDEO
)
set_subcategory
(
SUBCAT_VIDEO_VOUT
)
set_category
(
CAT_VIDEO
)
set_subcategory
(
SUBCAT_VIDEO_VOUT
)
#ifdef MODULE_NAME_IS_wingapi
set_shortname
(
"Windows GAPI"
)
set_description
(
N_
(
"Windows GAPI video output"
)
)
set_capability
(
"video output"
,
20
)
set_shortname
(
"Windows GAPI"
)
set_description
(
N_
(
"Windows GAPI video output"
)
)
set_capability
(
"vout display"
,
20
)
#else
set_shortname
(
"Windows GDI"
)
set_description
(
N_
(
"Windows GDI video output"
)
)
set_capability
(
"video output"
,
10
)
set_shortname
(
"Windows GDI"
)
set_description
(
N_
(
"Windows GDI video output"
)
)
set_capability
(
"vout display"
,
10
)
#endif
set_callbacks
(
OpenVideo
,
CloseVideo
)
set_callbacks
(
Open
,
Close
)
vlc_module_end
()
/*****************************************************************************
*
OpenVideo: activate GDI video thread output method
*
Local prototypes
*****************************************************************************/
static
int
OpenVideo
(
vlc_object_t
*
p_this
)
static
picture_pool_t
*
Pool
(
vout_display_t
*
,
unsigned
);
static
void
Display
(
vout_display_t
*
,
picture_t
*
);
static
int
Control
(
vout_display_t
*
,
int
,
va_list
);
static
void
Manage
(
vout_display_t
*
);
static
int
Init
(
vout_display_t
*
,
video_format_t
*
,
int
,
int
);
static
void
Clean
(
vout_display_t
*
);
/* */
static
int
Open
(
vlc_object_t
*
object
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
vout_display_t
*
vd
=
(
vout_display_t
*
)
object
;
vout_display_sys_t
*
sys
;
p_vout
->
p_sys
=
(
vout_sys_t
*
)
calloc
(
1
,
sizeof
(
vout_sys_t
)
);
if
(
!
p_vout
->
p_sys
)
return
VLC_ENOMEM
;
vd
->
sys
=
sys
=
calloc
(
1
,
sizeof
(
*
sys
));
if
(
!
sys
)
return
VLC_ENOMEM
;
#ifdef MODULE_NAME_IS_wingapi
/* Load GAPI */
p_vout
->
p_sys
->
gapi_dll
=
LoadLibrary
(
_T
(
"GX.DLL"
)
);
if
(
p_vout
->
p_sys
->
gapi_dll
==
NULL
)
{
msg_Warn
(
p_vout
,
"failed loading gx.dll"
);
free
(
p_vout
->
p_sys
);
sys
->
gapi_dll
=
LoadLibrary
(
_T
(
"GX.DLL"
));
if
(
!
sys
->
gapi_dll
)
{
msg_Warn
(
vd
,
"failed loading gx.dll"
);
free
(
sys
);
return
VLC_EGENERIC
;
}
GXOpenDisplay
=
(
void
*
)
GetProcAddress
(
p_vout
->
p_
sys
->
gapi_dll
,
_T
(
"?GXOpenDisplay@@YAHPAUHWND__@@K@Z"
)
);
GXCloseDisplay
=
(
void
*
)
GetProcAddress
(
p_vout
->
p_
sys
->
gapi_dll
,
_T
(
"?GXCloseDisplay@@YAHXZ"
)
);
GXBeginDraw
=
(
void
*
)
GetProcAddress
(
p_vout
->
p_
sys
->
gapi_dll
,
_T
(
"?GXBeginDraw@@YAPAXXZ"
)
);
GXEndDraw
=
(
void
*
)
GetProcAddress
(
p_vout
->
p_
sys
->
gapi_dll
,
_T
(
"?GXEndDraw@@YAHXZ"
)
);
GXGetDisplayProperties
=
(
void
*
)
GetProcAddress
(
p_vout
->
p_
sys
->
gapi_dll
,
_T
(
"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ"
)
);
GXSuspend
=
(
void
*
)
GetProcAddress
(
p_vout
->
p_
sys
->
gapi_dll
,
_T
(
"?GXSuspend@@YAHXZ"
)
);
GXResume
=
GetProcAddress
(
p_vout
->
p_
sys
->
gapi_dll
,
_T
(
"?GXResume@@YAHXZ"
)
);
if
(
!
GXOpenDisplay
||
!
GXCloseDisplay
||
!
GXBeginDraw
||
!
GXEndDraw
||
!
GX
GetDisplayProperties
||
!
GXSuspend
||
!
GXResume
)
{
msg_Err
(
p_vout
,
"failed GetProcAddress on gapi.dll"
);
free
(
p_vout
->
p_sys
);
GXOpenDisplay
=
(
void
*
)
GetProcAddress
(
sys
->
gapi_dll
,
_T
(
"?GXOpenDisplay@@YAHPAUHWND__@@K@Z"
));
GXCloseDisplay
=
(
void
*
)
GetProcAddress
(
sys
->
gapi_dll
,
_T
(
"?GXCloseDisplay@@YAHXZ"
));
GXBeginDraw
=
(
void
*
)
GetProcAddress
(
sys
->
gapi_dll
,
_T
(
"?GXBeginDraw@@YAPAXXZ"
));
GXEndDraw
=
(
void
*
)
GetProcAddress
(
sys
->
gapi_dll
,
_T
(
"?GXEndDraw@@YAHXZ"
));
GXGetDisplayProperties
=
(
void
*
)
GetProcAddress
(
sys
->
gapi_dll
,
_T
(
"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ"
));
GXSuspend
=
(
void
*
)
GetProcAddress
(
sys
->
gapi_dll
,
_T
(
"?GXSuspend@@YAHXZ"
));
GXResume
=
GetProcAddress
(
sys
->
gapi_dll
,
_T
(
"?GXResume@@YAHXZ"
));
if
(
!
GXOpenDisplay
||
!
GXCloseDisplay
||
!
GX
BeginDraw
||
!
GXEndDraw
||
!
GXGetDisplayProperties
||
!
GXSuspend
||
!
GXResume
)
{
msg_Err
(
vd
,
"failed GetProcAddress on gapi.dll"
);
free
(
sys
);
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_vout
,
"GAPI DLL loaded"
);
p_vout
->
p_sys
->
render_width
=
p_vout
->
render
.
i_width
;
p_vout
->
p_sys
->
render_height
=
p_vout
->
render
.
i_height
;
msg_Dbg
(
vd
,
"GAPI DLL loaded"
);
#endif
p_vout
->
pf_init
=
Init
;
p_vout
->
pf_end
=
End
;
p_vout
->
pf_manage
=
Manage
;
p_vout
->
pf_render
=
Render
;
p_vout
->
pf_control
=
Control
;
#ifdef MODULE_NAME_IS_wingapi
p_vout
->
pf_display
=
FirstDisplayGAPI
;
#else
p_vout
->
pf_display
=
FirstDisplayGDI
;
#endif
if
(
CommonInit
(
vd
))
goto
error
;
if
(
CommonInit
(
p_vout
)
)
/* */
video_format_t
fmt
=
vd
->
fmt
;
if
(
Init
(
vd
,
&
fmt
,
fmt
.
i_width
,
fmt
.
i_height
))
goto
error
;
vout_display_info_t
info
=
vd
->
info
;
info
.
is_slow
=
false
;
info
.
has_double_click
=
true
;
info
.
has_hide_mouse
=
true
;
info
.
has_pictures_invalid
=
true
;
/* */
vd
->
fmt
=
fmt
;
vd
->
info
=
info
;
vd
->
pool
=
Pool
;
vd
->
prepare
=
NULL
;
vd
->
display
=
Display
;
vd
->
manage
=
Manage
;
vd
->
control
=
Control
;
return
VLC_SUCCESS
;
error:
Close
Video
(
VLC_OBJECT
(
p_vout
)
);
Close
(
VLC_OBJECT
(
vd
)
);
return
VLC_EGENERIC
;
}
/*****************************************************************************
* CloseVideo: deactivate the GDI video output
*****************************************************************************/
static
void
CloseVideo
(
vlc_object_t
*
p_this
)
/* */
static
void
Close
(
vlc_object_t
*
object
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
vout_display_t
*
vd
=
(
vout_display_t
*
)
object
;
Clean
(
vd
);
CommonClean
(
p_vout
);
CommonClean
(
vd
);
#ifdef MODULE_NAME_IS_wingapi
FreeLibrary
(
p_vout
->
p_sys
->
gapi_dll
);
FreeLibrary
(
vd
->
sys
->
gapi_dll
);
#endif
free
(
p_vout
->
p_sys
);
free
(
vd
->
sys
);
}
/*****************************************************************************
* Init: initialize video thread output method
*****************************************************************************/
static
int
Init
(
vout_thread_t
*
p_vout
)
/* */
static
picture_pool_t
*
Pool
(
vout_display_t
*
vd
,
unsigned
count
)
{
picture_t
*
p_pic
;
/* Initialize offscreen buffer */
InitBuffers
(
p_vout
);
p_vout
->
p_sys
->
rect_display
.
left
=
0
;
p_vout
->
p_sys
->
rect_display
.
top
=
0
;
p_vout
->
p_sys
->
rect_display
.
right
=
GetSystemMetrics
(
SM_CXSCREEN
);
p_vout
->
p_sys
->
rect_display
.
bottom
=
GetSystemMetrics
(
SM_CYSCREEN
);
I_OUTPUTPICTURES
=
0
;
/* Initialize the output structure */
switch
(
p_vout
->
p_sys
->
i_depth
)
{
case
8
:
p_vout
->
output
.
i_chroma
=
VLC_CODEC_RGB8
;
p_vout
->
output
.
pf_setpalette
=
SetPalette
;
break
;
case
15
:
p_vout
->
output
.
i_chroma
=
VLC_CODEC_RGB15
;
p_vout
->
output
.
i_rmask
=
0x7c00
;
p_vout
->
output
.
i_gmask
=
0x03e0
;
p_vout
->
output
.
i_bmask
=
0x001f
;
break
;
case
16
:
p_vout
->
output
.
i_chroma
=
VLC_CODEC_RGB16
;
p_vout
->
output
.
i_rmask
=
0xf800
;
p_vout
->
output
.
i_gmask
=
0x07e0
;
p_vout
->
output
.
i_bmask
=
0x001f
;
break
;
case
24
:
p_vout
->
output
.
i_chroma
=
VLC_CODEC_RGB24
;
p_vout
->
output
.
i_rmask
=
0x00ff0000
;
p_vout
->
output
.
i_gmask
=
0x0000ff00
;
p_vout
->
output
.
i_bmask
=
0x000000ff
;
break
;
case
32
:
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
;
default:
msg_Err
(
p_vout
,
"screen depth %i not supported"
,
p_vout
->
p_sys
->
i_depth
);
return
VLC_EGENERIC
;
break
;
}
p_pic
=
&
p_vout
->
p_picture
[
0
];
VLC_UNUSED
(
count
);
return
vd
->
sys
->
pool
;
}
static
void
Display
(
vout_display_t
*
vd
,
picture_t
*
picture
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
#ifdef MODULE_NAME_IS_wingapi
p_vout
->
output
.
i_width
=
0
;
p_vout
->
output
.
i_height
=
0
;
p_pic
->
pf_lock
=
GAPILockSurface
;
p_pic
->
pf_unlock
=
GAPIUnlockSurface
;
Manage
(
p_vout
);
GAPILockSurface
(
p_vout
,
p_pic
);
p_vout
->
i_changes
=
0
;
p_vout
->
output
.
i_width
=
p_vout
->
p_sys
->
render_width
;
p_vout
->
output
.
i_height
=
p_vout
->
p_sys
->
render_height
;
/* */
#else
p_vout
->
output
.
i_width
=
p_vout
->
render
.
i_width
;
p_vout
->
output
.
i_height
=
p_vout
->
render
.
i_height
;
p_vout
->
fmt_out
=
p_vout
->
fmt_in
;
p_vout
->
fmt_out
.
i_chroma
=
p_vout
->
output
.
i_chroma
;
#endif
p_vout
->
output
.
i_aspect
=
p_vout
->
render
.
i_aspect
;
#define rect_src vd->sys->rect_src
#define rect_src_clipped vd->sys->rect_src_clipped
#define rect_dest vd->sys->rect_dest
#define rect_dest_clipped vd->sys->rect_dest_clipped
RECT
rect_dst
=
rect_dest_clipped
;
HDC
hdc
=
GetDC
(
sys
->
hvideownd
);
p_pic
->
p
->
p_pixels
=
p_vout
->
p_sys
->
p_pic_buffer
;
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_pitch
=
p_vout
->
p_sys
->
i_pic_pitch
;
p_pic
->
p
->
i_pixel_pitch
=
p_vout
->
p_sys
->
i_pic_pixel_pitch
;
p_pic
->
p
->
i_visible_pitch
=
p_vout
->
output
.
i_width
*
p_pic
->
p
->
i_pixel_pitch
;
p_pic
->
i_planes
=
1
;
p_pic
->
i_status
=
DESTROYED_PICTURE
;
p_pic
->
i_type
=
DIRECT_PICTURE
;
OffsetRect
(
&
rect_dst
,
-
rect_dest
.
left
,
-
rect_dest
.
top
);
SelectObject
(
sys
->
off_dc
,
sys
->
off_bitmap
);
PP_OUTPUTPICTURE
[
I_OUTPUTPICTURES
++
]
=
p_pic
;
if
(
rect_dest_clipped
.
right
-
rect_dest_clipped
.
left
!=
rect_src_clipped
.
right
-
rect_src_clipped
.
left
||
rect_dest_clipped
.
bottom
-
rect_dest_clipped
.
top
!=
rect_src_clipped
.
bottom
-
rect_src_clipped
.
top
)
{
StretchBlt
(
hdc
,
rect_dst
.
left
,
rect_dst
.
top
,
rect_dst
.
right
,
rect_dst
.
bottom
,
sys
->
off_dc
,
rect_src_clipped
.
left
,
rect_src_clipped
.
top
,
rect_src_clipped
.
right
,
rect_src_clipped
.
bottom
,
SRCCOPY
);
}
else
{
BitBlt
(
hdc
,
rect_dst
.
left
,
rect_dst
.
top
,
rect_dst
.
right
,
rect_dst
.
bottom
,
sys
->
off_dc
,
rect_src_clipped
.
left
,
rect_src_clipped
.
top
,
SRCCOPY
);
}
/* Change the window title bar text */
#
ifdef MODULE_NAME_IS_wingapi
EventThreadUpdateTitle
(
p_vout
->
p_sys
->
p_event
,
VOUT_TITLE
" (WinGAPI output)"
);
#
else
EventThreadUpdateTitle
(
p_vout
->
p_sys
->
p_event
,
VOUT_TITLE
" (WinGDI output)"
);
ReleaseDC
(
sys
->
hvideownd
,
hdc
);
#
undef rect_src
#undef rect_src_clipped
#
undef rect_dest
#undef rect_dest_clipped
#endif
UpdateRects
(
p_vout
,
true
);
/* TODO */
picture_Release
(
picture
);
return
VLC_SUCCESS
;
CommonDisplay
(
vd
)
;
}
/*****************************************************************************
* End: terminate video thread output method
*****************************************************************************/
static
void
End
(
vout_thread_t
*
p_vout
)
static
int
Control
(
vout_display_t
*
vd
,
int
query
,
va_list
args
)
{
#ifdef MODULE_NAME_IS_wingapi
GXCloseDisplay
();
#else
DeleteDC
(
p_vout
->
p_sys
->
off_dc
);
DeleteObject
(
p_vout
->
p_sys
->
off_bitmap
);
#endif
}
/*****************************************************************************
* Manage: handle events
*****************************************************************************
* This function should be called regularly by video output thread. It manages
* console events. It returns a non null value on error.
*****************************************************************************/
static
int
Manage
(
vout_thread_t
*
p_vout
)
{
/*
* Position Change
*/
if
(
p_vout
->
p_sys
->
i_changes
&
DX_POSITION_CHANGE
)
{
p_vout
->
p_sys
->
i_changes
&=
~
DX_POSITION_CHANGE
;
switch
(
query
)
{
case
VOUT_DISPLAY_RESET_PICTURES
:
assert
(
0
);
return
VLC_EGENERIC
;
default:
return
CommonControl
(
vd
,
query
,
args
);
}
CommonManage
(
p_vout
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Render: render previously calculated output
*****************************************************************************/
static
void
Render
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
static
void
Manage
(
vout_display_t
*
vd
)
{
/* No need to do anything, the fake direct buffers stay as they are */
(
void
)
p_vout
;
(
void
)
p_pic
;
CommonManage
(
vd
);
}
/*****************************************************************************
* Display: displays previously rendered output
*****************************************************************************/
#define rect_src p_vout->p_sys->rect_src
#define rect_src_clipped p_vout->p_sys->rect_src_clipped
#define rect_dest p_vout->p_sys->rect_dest
#define rect_dest_clipped p_vout->p_sys->rect_dest_clipped
#ifndef MODULE_NAME_IS_wingapi
static
void
DisplayGDI
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
VLC_UNUSED
(
p_pic
);
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
RECT
rect_dst
=
rect_dest_clipped
;
HDC
hdc
=
GetDC
(
p_sys
->
hvideownd
);
OffsetRect
(
&
rect_dst
,
-
rect_dest
.
left
,
-
rect_dest
.
top
);
SelectObject
(
p_sys
->
off_dc
,
p_sys
->
off_bitmap
);
if
(
rect_dest_clipped
.
right
-
rect_dest_clipped
.
left
!=
rect_src_clipped
.
right
-
rect_src_clipped
.
left
||
rect_dest_clipped
.
bottom
-
rect_dest_clipped
.
top
!=
rect_src_clipped
.
bottom
-
rect_src_clipped
.
top
)
{
StretchBlt
(
hdc
,
rect_dst
.
left
,
rect_dst
.
top
,
rect_dst
.
right
,
rect_dst
.
bottom
,
p_sys
->
off_dc
,
rect_src_clipped
.
left
,
rect_src_clipped
.
top
,
rect_src_clipped
.
right
,
rect_src_clipped
.
bottom
,
SRCCOPY
);
}
else
{
BitBlt
(
hdc
,
rect_dst
.
left
,
rect_dst
.
top
,
rect_dst
.
right
,
rect_dst
.
bottom
,
p_sys
->
off_dc
,
rect_src_clipped
.
left
,
rect_src_clipped
.
top
,
SRCCOPY
);
}
ReleaseDC
(
p_sys
->
hvideownd
,
hdc
);
}
#ifdef MODULE_NAME_IS_wingapi
struct
picture_sys_t
{
vout_display_t
*
vd
;
};
static
void
FirstDisplayGDI
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
static
int
Lock
(
picture_t
*
picture
)
{
/*
** 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
);
/* get initial picture presented */
DisplayGDI
(
p_vout
,
p_pic
);
/* use and restores proper display function for further pictures */
p_vout
->
pf_display
=
DisplayGDI
;
}
vout_display_t
*
vd
=
picture
->
p_sys
->
vd
;
#else
/* */
if
(
sys
->
rect_dest_clipped
.
right
-
sys
->
rect_dest_clipped
.
left
!=
vd
->
fmt
.
i_width
||
sys
->
rect_dest_clipped
.
bottom
-
sys
->
rect_dest_clipped
.
top
!=
vd
->
fmt
.
i_height
)
return
VLC_EGENERIC
;
static
int
GAPILockSurface
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
int
i_x
,
i_y
,
i_width
,
i_height
;
RECT
video_rect
;
POINT
point
;
GetClientRect
(
p_sys
->
hwnd
,
&
video_rect
);
vout_PlacePicture
(
p_vout
,
video_rect
.
right
-
video_rect
.
left
,
video_rect
.
bottom
-
video_rect
.
top
,
&
i_x
,
&
i_y
,
&
i_width
,
&
i_height
);
point
.
x
=
point
.
y
=
0
;
ClientToScreen
(
p_sys
->
hwnd
,
&
point
);
i_x
+=
point
.
x
+
video_rect
.
left
;
i_y
+=
point
.
y
+
video_rect
.
top
;
if
(
i_width
!=
p_vout
->
output
.
i_width
||
i_height
!=
p_vout
->
output
.
i_height
)
{
GXDisplayProperties
gxdisplayprop
=
GXGetDisplayProperties
();
p_sys
->
render_width
=
i_width
;
p_sys
->
render_height
=
i_height
;
p_vout
->
i_changes
|=
VOUT_SIZE_CHANGE
;
msg_Dbg
(
p_vout
,
"vout size change (%ix%i -> %ix%i)"
,
i_width
,
i_height
,
p_vout
->
output
.
i_width
,
p_vout
->
output
.
i_height
);
p_vout
->
p_sys
->
i_pic_pixel_pitch
=
gxdisplayprop
.
cbxPitch
;
p_vout
->
p_sys
->
i_pic_pitch
=
gxdisplayprop
.
cbyPitch
;
/* */
GXDisplayProperties
gxdisplayprop
=
GXGetDisplayProperties
();
uint8_t
*
p_pic_buffer
=
GXBeginDraw
();
if
(
!
sys
->
p_pic_buffer
)
{
msg_Err
(
vd
,
"GXBeginDraw error %d "
,
GetLastError
());
return
VLC_EGENERIC
;
}
else
{
GXDisplayProperties
gxdisplayprop
;
RECT
display_rect
,
dest_rect
;
uint8_t
*
p_dest
,
*
p_src
=
p_pic
->
p
->
p_pixels
;
video_rect
.
left
=
i_x
;
video_rect
.
top
=
i_y
;
video_rect
.
right
=
i_x
+
i_width
;
video_rect
.
bottom
=
i_y
+
i_height
;
gxdisplayprop
=
GXGetDisplayProperties
();
display_rect
.
left
=
0
;
display_rect
.
top
=
0
;
display_rect
.
right
=
gxdisplayprop
.
cxWidth
;
display_rect
.
bottom
=
gxdisplayprop
.
cyHeight
;
if
(
!
IntersectRect
(
&
dest_rect
,
&
video_rect
,
&
display_rect
)
)
{
return
VLC_EGENERIC
;
}
#ifndef NDEBUG
msg_Dbg
(
p_vout
,
"video (%d,%d,%d,%d) display (%d,%d,%d,%d) "
"dest (%d,%d,%d,%d)"
,
video_rect
.
left
,
video_rect
.
right
,
video_rect
.
top
,
video_rect
.
bottom
,
display_rect
.
left
,
display_rect
.
right
,
display_rect
.
top
,
display_rect
.
bottom
,
dest_rect
.
left
,
dest_rect
.
right
,
dest_rect
.
top
,
dest_rect
.
bottom
);
#endif
if
(
!
(
p_dest
=
GXBeginDraw
())
)
{
#ifndef NDEBUG
msg_Err
(
p_vout
,
"GXBeginDraw error %d "
,
GetLastError
()
);
#endif
return
VLC_EGENERIC
;
}
p_src
+=
(
dest_rect
.
left
-
video_rect
.
left
)
*
gxdisplayprop
.
cbxPitch
+
(
dest_rect
.
top
-
video_rect
.
top
)
*
p_pic
->
p
->
i_pitch
;
p_dest
+=
dest_rect
.
left
*
gxdisplayprop
.
cbxPitch
+
dest_rect
.
top
*
gxdisplayprop
.
cbyPitch
;
i_width
=
dest_rect
.
right
-
dest_rect
.
left
;
i_height
=
dest_rect
.
bottom
-
dest_rect
.
top
;
p_pic_buffer
+=
sys
->
rect_dest
.
top
*
gxdisplayprop
.
cbyPitch
+
sys
->
rect_dest
.
left
*
gxdisplayprop
.
cbxPitch
;
p_pic
->
p
->
p_pixels
=
p_dest
;
}
/* */
picture
->
p
[
0
].
i_pitch
=
gxdisplayprop
.
cbyPitch
;
picture
->
p
[
0
].
p_pixels
=
p_pic_buffer
;
return
VLC_SUCCESS
;
}
static
int
GAPIUnlockSurface
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
static
void
Unlock
(
picture_t
*
picture
)
{
GXEndDraw
();
return
VLC_SUCCESS
;
}
static
void
DisplayGAPI
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
}
static
void
FirstDisplayGAPI
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
/* get initial picture presented through D3D */
DisplayGAPI
(
p_vout
,
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
);
/* use and restores proper display function for further pictures */
p_vout
->
pf_display
=
DisplayGAPI
;
}
#endif
#undef rect_src
#undef rect_src_clipped
#undef rect_dest
#undef rect_dest_clipped
/*****************************************************************************
* SetPalette: sets an 8 bpp palette
*****************************************************************************/
static
void
SetPalette
(
vout_thread_t
*
p_vout
,
uint16_t
*
red
,
uint16_t
*
green
,
uint16_t
*
blue
)
{
VLC_UNUSED
(
red
);
VLC_UNUSED
(
green
);
VLC_UNUSED
(
blue
);
msg_Err
(
p_vout
,
"FIXME: SetPalette unimplemented"
);
}
/*****************************************************************************
* InitBuffers: initialize an offscreen bitmap for direct buffer operations.
*****************************************************************************/
static
void
InitBuffers
(
vout_thread_t
*
p_vout
)
static
int
Init
(
vout_display_t
*
vd
,
video_format_t
*
fmt
,
int
width
,
int
height
)
{
BITMAPINFOHEADER
*
p_header
=
&
p_vout
->
p_sys
->
bitmapinfo
.
bmiHeader
;
BITMAPINFO
*
p_info
=
&
p_vout
->
p_sys
->
bitmapinfo
;
HDC
window_dc
=
GetDC
(
p_vout
->
p_sys
->
hvideownd
);
vout_display_sys_t
*
sys
=
vd
->
sys
;
/* Get screen properties */
/* */
RECT
*
display
=
&
sys
->
rect_display
;
display
->
left
=
0
;
display
->
top
=
0
;
#ifdef MODULE_NAME_IS_wingapi
GXDisplayProperties
gx_displayprop
=
GXGetDisplayProperties
()
;
p_vout
->
p_sys
->
i_depth
=
gx_displayprop
.
cBPP
;
display
->
right
=
GXGetDisplayProperties
().
cxWidth
;
display
->
bottom
=
GXGetDisplayProperties
().
cyHeight
;
#else
p_vout
->
p_sys
->
i_depth
=
GetDeviceCaps
(
window_dc
,
PLANES
)
*
GetDeviceCaps
(
window_dc
,
BITSPIXEL
)
;
display
->
right
=
GetSystemMetrics
(
SM_CXSCREEN
);;
display
->
bottom
=
GetSystemMetrics
(
SM_CYSCREEN
);
;
#endif
msg_Dbg
(
p_vout
,
"GDI depth is %i"
,
p_vout
->
p_sys
->
i_depth
);
#ifdef MODULE_NAME_IS_wingapi
GXOpenDisplay
(
p_vout
->
p_sys
->
hvideownd
,
GX_FULLSCREEN
);
/* Initialize an offscreen bitmap for direct buffer operations. */
/* */
HDC
window_dc
=
GetDC
(
sys
->
hvideownd
);
/* */
#ifdef MODULE_NAME_IS_wingapi
GXDisplayProperties
gx_displayprop
=
GXGetDisplayProperties
();
sys
->
i_depth
=
gx_displayprop
.
cBPP
;
#else
/* Initialize offscreen bitmap */
memset
(
p_info
,
0
,
sizeof
(
BITMAPINFO
)
+
3
*
sizeof
(
RGBQUAD
)
);
sys
->
i_depth
=
GetDeviceCaps
(
window_dc
,
PLANES
)
*
GetDeviceCaps
(
window_dc
,
BITSPIXEL
);
#endif
p_header
->
biSize
=
sizeof
(
BITMAPINFOHEADER
);
p_header
->
biSizeImage
=
0
;
p_header
->
biPlanes
=
1
;
switch
(
p_vout
->
p_sys
->
i_depth
)
{
/* */
msg_Dbg
(
vd
,
"GDI depth is %i"
,
sys
->
i_depth
);
switch
(
sys
->
i_depth
)
{
case
8
:
p_header
->
biBitCount
=
8
;
p_header
->
biCompression
=
BI_RGB
;
/* FIXME: we need a palette here */
fmt
->
i_chroma
=
VLC_CODEC_RGB8
;
break
;
case
15
:
p_header
->
biBitCount
=
15
;
p_header
->
biCompression
=
BI_BITFIELDS
;
//BI_RGB;
((
DWORD
*
)
p_info
->
bmiColors
)[
0
]
=
0x00007c00
;
((
DWORD
*
)
p_info
->
bmiColors
)[
1
]
=
0x000003e0
;
((
DWORD
*
)
p_info
->
bmiColors
)[
2
]
=
0x0000001f
;
fmt
->
i_chroma
=
VLC_CODEC_RGB15
;
fmt
->
i_rmask
=
0x7c00
;
fmt
->
i_gmask
=
0x03e0
;
fmt
->
i_bmask
=
0x001f
;
break
;
case
16
:
p_header
->
biBitCount
=
16
;
p_header
->
biCompression
=
BI_BITFIELDS
;
//BI_RGB;
((
DWORD
*
)
p_info
->
bmiColors
)[
0
]
=
0x0000f800
;
((
DWORD
*
)
p_info
->
bmiColors
)[
1
]
=
0x000007e0
;
((
DWORD
*
)
p_info
->
bmiColors
)[
2
]
=
0x0000001f
;
fmt
->
i_chroma
=
VLC_CODEC_RGB16
;
fmt
->
i_rmask
=
0xf800
;
fmt
->
i_gmask
=
0x07e0
;
fmt
->
i_bmask
=
0x001f
;
break
;
case
24
:
p_header
->
biBitCount
=
24
;
p_header
->
biCompression
=
BI_RGB
;
((
DWORD
*
)
p_info
->
bmiColors
)[
0
]
=
0x00ff0000
;
((
DWORD
*
)
p_info
->
bmiColors
)[
1
]
=
0x0000ff00
;
((
DWORD
*
)
p_info
->
bmiColors
)[
2
]
=
0x000000ff
;
fmt
->
i_chroma
=
VLC_CODEC_RGB24
;
fmt
->
i_rmask
=
0x00ff0000
;
fmt
->
i_gmask
=
0x0000ff00
;
fmt
->
i_bmask
=
0x000000ff
;
break
;
case
32
:
p_header
->
biBitCount
=
32
;
p_header
->
biCompression
=
BI_RGB
;
((
DWORD
*
)
p_info
->
bmiColors
)[
0
]
=
0x00ff0000
;
((
DWORD
*
)
p_info
->
bmiColors
)[
1
]
=
0x0000ff00
;
((
DWORD
*
)
p_info
->
bmiColors
)[
2
]
=
0x000000ff
;
fmt
->
i_chroma
=
VLC_CODEC_RGB32
;
fmt
->
i_rmask
=
0x00ff0000
;
fmt
->
i_gmask
=
0x0000ff00
;
fmt
->
i_bmask
=
0x000000ff
;
break
;
default:
msg_Err
(
p_vout
,
"screen depth %i not supported"
,
p_vout
->
p_sys
->
i_depth
);
return
;
break
;
msg_Err
(
vd
,
"screen depth %i not supported"
,
sys
->
i_depth
);
return
VLC_EGENERIC
;
}
fmt
->
i_width
=
width
;
fmt
->
i_height
=
height
;
uint8_t
*
p_pic_buffer
;
int
i_pic_pitch
;
#ifdef MODULE_NAME_IS_wingapi
GXOpenDisplay
(
sys
->
hvideownd
,
GX_FULLSCREEN
);
EventThreadUpdateTitle
(
sys
->
event
,
VOUT_TITLE
" (WinGAPI output)"
);
/* Filled by pool::lock() */
p_pic_buffer
=
NULL
;
i_pic_pitch
=
0
;
#else
/* Initialize offscreen bitmap */
BITMAPINFO
*
bi
=
&
sys
->
bitmapinfo
;
memset
(
bi
,
0
,
sizeof
(
BITMAPINFO
)
+
3
*
sizeof
(
RGBQUAD
));
if
(
sys
->
i_depth
>
8
)
{
((
DWORD
*
)
bi
->
bmiColors
)[
0
]
=
fmt
->
i_rmask
;
((
DWORD
*
)
bi
->
bmiColors
)[
1
]
=
fmt
->
i_gmask
;
((
DWORD
*
)
bi
->
bmiColors
)[
2
]
=
fmt
->
i_bmask
;;
}
p_header
->
biWidth
=
p_vout
->
render
.
i_width
;
p_header
->
biHeight
=
-
p_vout
->
render
.
i_height
;
p_header
->
biClrImportant
=
0
;
p_header
->
biClrUsed
=
0
;
p_header
->
biXPelsPerMeter
=
0
;
p_header
->
biYPelsPerMeter
=
0
;
p_vout
->
p_sys
->
i_pic_pixel_pitch
=
p_header
->
biBitCount
/
8
;
p_vout
->
p_sys
->
i_pic_pitch
=
p_header
->
biBitCount
*
p_header
->
biWidth
/
8
;
BITMAPINFOHEADER
*
bih
=
&
sys
->
bitmapinfo
.
bmiHeader
;
bih
->
biSize
=
sizeof
(
BITMAPINFOHEADER
);
bih
->
biSizeImage
=
0
;
bih
->
biPlanes
=
1
;
bih
->
biCompression
=
(
sys
->
i_depth
==
15
||
sys
->
i_depth
==
16
)
?
BI_BITFIELDS
:
BI_RGB
;
bih
->
biBitCount
=
sys
->
i_depth
;
bih
->
biWidth
=
fmt
->
i_width
;
bih
->
biHeight
=
-
fmt
->
i_height
;
bih
->
biClrImportant
=
0
;
bih
->
biClrUsed
=
0
;
bih
->
biXPelsPerMeter
=
0
;
bih
->
biYPelsPerMeter
=
0
;
i_pic_pitch
=
bih
->
biBitCount
*
bih
->
biWidth
/
8
;
sys
->
off_bitmap
=
CreateDIBSection
(
window_dc
,
(
BITMAPINFO
*
)
bih
,
DIB_RGB_COLORS
,
&
p_pic_buffer
,
NULL
,
0
);
sys
->
off_dc
=
CreateCompatibleDC
(
window_dc
);
SelectObject
(
sys
->
off_dc
,
sys
->
off_bitmap
);
ReleaseDC
(
sys
->
hvideownd
,
window_dc
);
EventThreadUpdateTitle
(
sys
->
event
,
VOUT_TITLE
" (WinGDI output)"
);
#endif
p_vout
->
p_sys
->
off_bitmap
=
CreateDIBSection
(
window_dc
,
(
BITMAPINFO
*
)
p_header
,
DIB_RGB_COLORS
,
&
p_vout
->
p_sys
->
p_pic_buffer
,
NULL
,
0
);
/* */
picture_resource_t
rsc
;
memset
(
&
rsc
,
0
,
sizeof
(
rsc
));
#ifdef MODULE_NAME_IS_wingapi
rsc
.
p_sys
=
malloc
(
sizeof
(
*
rsc
.
p_sys
));
if
(
!
rsc
.
p_sys
)
return
VLC_EGENERIC
;
rsc
.
p_sys
->
vd
=
vd
;
#endif
rsc
.
p
[
0
].
p_pixels
=
p_pic_buffer
;
rsc
.
p
[
0
].
i_lines
=
fmt
->
i_height
;
rsc
.
p
[
0
].
i_pitch
=
i_pic_pitch
;;
picture_t
*
picture
=
picture_NewFromResource
(
fmt
,
&
rsc
);
if
(
picture
)
{
picture_pool_configuration_t
cfg
;
memset
(
&
cfg
,
0
,
sizeof
(
cfg
));
cfg
.
picture_count
=
1
;
cfg
.
picture
=
&
picture
;
#ifdef MODULE_NAME_IS_wingapi
cfg
.
lock
=
Lock
;
cfg
.
unlock
=
Unkock
;
#endif
sys
->
pool
=
picture_pool_NewExtended
(
&
cfg
);
}
else
{
free
(
rsc
.
p_sys
);
sys
->
pool
=
NULL
;
}
p_vout
->
p_sys
->
off_dc
=
CreateCompatibleDC
(
window_dc
);
UpdateRects
(
vd
,
NULL
,
NULL
,
true
);
SelectObject
(
p_vout
->
p_sys
->
off_dc
,
p_vout
->
p_sys
->
off_bitmap
);
ReleaseDC
(
p_vout
->
p_sys
->
hvideownd
,
window_dc
);
return
VLC_SUCCESS
;
}
static
void
Clean
(
vout_display_t
*
vd
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
if
(
sys
->
pool
)
picture_pool_Delete
(
sys
->
pool
);
sys
->
pool
=
NULL
;
#ifdef MODULE_NAME_IS_wingapi
GXCloseDisplay
();
#else
if
(
sys
->
off_dc
)
DeleteDC
(
sys
->
off_dc
);
if
(
sys
->
off_bitmap
)
DeleteObject
(
sys
->
off_bitmap
);
#endif
}
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