Commit 284900dc authored by Laurent Aimar's avatar Laurent Aimar

Converted wingdi/wingapi to vout display.

parent 72974fc1
...@@ -24,16 +24,16 @@ SOURCES_glwin32 = \ ...@@ -24,16 +24,16 @@ SOURCES_glwin32 = \
SOURCES_wingdi = \ SOURCES_wingdi = \
wingdi.c \ wingdi.c \
vout.h \ common.h \
events_vo.h \ events.h \
events_vo.c \ events.c \
common_vo.c \ common.c \
$(NULL) $(NULL)
SOURCES_wingapi = \ SOURCES_wingapi = \
wingdi.c \ wingdi.c \
vout.h \ vout.h \
events_vo.h \ events.h \
events_vo.c \ events.c \
common_vo.c \ common.c \
$(NULL) $(NULL)
...@@ -169,7 +169,7 @@ void CommonManage(vout_display_t *vd) ...@@ -169,7 +169,7 @@ void CommonManage(vout_display_t *vd)
/* FIXME I find such #ifdef quite weirds. Are they really needed ? */ /* 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, SetWindowPos(sys->hwnd, 0, 0, 0,
rect_parent.right - rect_parent.left, rect_parent.right - rect_parent.left,
rect_parent.bottom - rect_parent.top, rect_parent.bottom - rect_parent.top,
...@@ -186,15 +186,6 @@ void CommonManage(vout_display_t *vd) ...@@ -186,15 +186,6 @@ void CommonManage(vout_display_t *vd)
rect_parent.right - rect_parent.left, rect_parent.right - rect_parent.left,
rect_parent.bottom - rect_parent.top, 0); 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 #endif
} }
} }
...@@ -271,7 +262,9 @@ void UpdateRects(vout_display_t *vd, ...@@ -271,7 +262,9 @@ void UpdateRects(vout_display_t *vd,
EventThreadUpdateWindowPosition(sys->event, &has_moved, &is_resized, EventThreadUpdateWindowPosition(sys->event, &has_moved, &is_resized,
point.x, point.y, point.x, point.y,
rect.right, rect.bottom); 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; return;
/* Update the window position and size */ /* Update the window position and size */
...@@ -283,6 +276,10 @@ void UpdateRects(vout_display_t *vd, ...@@ -283,6 +276,10 @@ void UpdateRects(vout_display_t *vd,
vout_display_PlacePicture(&place, source, &place_cfg, true); vout_display_PlacePicture(&place, source, &place_cfg, true);
EventThreadUpdateSourceAndPlace(sys->event, source, &place); 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) if (sys->hvideownd)
SetWindowPos(sys->hvideownd, 0, SetWindowPos(sys->hvideownd, 0,
......
...@@ -187,39 +187,24 @@ struct vout_display_sys_t ...@@ -187,39 +187,24 @@ struct vout_display_sys_t
bool desktop_requested; bool desktop_requested;
#endif #endif
#ifdef MODULE_NAME_IS_wingdi #if defined(MODULE_NAME_IS_wingdi) || defined(MODULE_NAME_IS_wingapi)
int i_depth; int i_depth;
/* Our offscreen bitmap and its framebuffer */ /* Our offscreen bitmap and its framebuffer */
HDC off_dc; HDC off_dc;
HBITMAP off_bitmap; 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 picture_pool_t *pool;
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;
struct
{
BITMAPINFO bitmapinfo; BITMAPINFO bitmapinfo;
RGBQUAD red; RGBQUAD red;
RGBQUAD green; RGBQUAD green;
RGBQUAD blue; RGBQUAD blue;
};
# ifdef MODULE_NAME_IS_wingapi
HINSTANCE gapi_dll; /* handle of the opened gapi dll */ HINSTANCE gapi_dll; /* handle of the opened gapi dll */
/* GAPI functions */ /* GAPI functions */
...@@ -230,6 +215,7 @@ struct vout_display_sys_t ...@@ -230,6 +215,7 @@ struct vout_display_sys_t
GXDisplayProperties (*GXGetDisplayProperties)(); GXDisplayProperties (*GXGetDisplayProperties)();
int (*GXSuspend)(); int (*GXSuspend)();
int (*GXResume)(); int (*GXResume)();
# endif
#endif #endif
}; };
......
...@@ -29,580 +29,415 @@ ...@@ -29,580 +29,415 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" # include "config.h"
#endif #endif
#include <assert.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_playlist.h> #include <vlc_playlist.h>
#include <vlc_vout.h> #include <vlc_vout_display.h>
#include <windows.h> #include <windows.h>
#include <commctrl.h> #include <commctrl.h>
#include "vout.h" #include "common.h"
#define MAX_DIRECTBUFFERS 10
#ifndef WS_NONAVDONEBUTTON #ifndef WS_NONAVDONEBUTTON
#define WS_NONAVDONEBUTTON 0 # define WS_NONAVDONEBUTTON 0
#endif #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 * );
#endif
static void SetPalette( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * );
static void InitBuffers ( vout_thread_t * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
*****************************************************************************/ *****************************************************************************/
static int Open (vlc_object_t *);
static void Close(vlc_object_t *);
vlc_module_begin () vlc_module_begin ()
set_category( CAT_VIDEO ) set_category(CAT_VIDEO)
set_subcategory( SUBCAT_VIDEO_VOUT ) set_subcategory(SUBCAT_VIDEO_VOUT)
#ifdef MODULE_NAME_IS_wingapi #ifdef MODULE_NAME_IS_wingapi
set_shortname( "Windows GAPI" ) set_shortname("Windows GAPI")
set_description( N_("Windows GAPI video output") ) set_description(N_("Windows GAPI video output"))
set_capability( "video output", 20 ) set_capability("vout display", 20)
#else #else
set_shortname( "Windows GDI" ) set_shortname("Windows GDI")
set_description( N_("Windows GDI video output") ) set_description(N_("Windows GDI video output"))
set_capability( "video output", 10 ) set_capability("vout display", 10)
#endif #endif
set_callbacks( OpenVideo, CloseVideo ) set_callbacks(Open, Close)
vlc_module_end () 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) ); vd->sys = sys = calloc(1, sizeof(*sys));
if( !p_vout->p_sys ) return VLC_ENOMEM; if (!sys)
return VLC_ENOMEM;
#ifdef MODULE_NAME_IS_wingapi #ifdef MODULE_NAME_IS_wingapi
/* Load GAPI */ /* Load GAPI */
p_vout->p_sys->gapi_dll = LoadLibrary( _T("GX.DLL") ); sys->gapi_dll = LoadLibrary(_T("GX.DLL"));
if( p_vout->p_sys->gapi_dll == NULL ) if (!sys->gapi_dll) {
{ msg_Warn(vd, "failed loading gx.dll");
msg_Warn( p_vout, "failed loading gx.dll" ); free(sys);
free( p_vout->p_sys );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
GXOpenDisplay = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, GXOpenDisplay = (void *)GetProcAddress(sys->gapi_dll,
_T("?GXOpenDisplay@@YAHPAUHWND__@@K@Z") ); _T("?GXOpenDisplay@@YAHPAUHWND__@@K@Z"));
GXCloseDisplay = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, GXCloseDisplay = (void *)GetProcAddress(sys->gapi_dll,
_T("?GXCloseDisplay@@YAHXZ") ); _T("?GXCloseDisplay@@YAHXZ"));
GXBeginDraw = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, GXBeginDraw = (void *)GetProcAddress(sys->gapi_dll,
_T("?GXBeginDraw@@YAPAXXZ") ); _T("?GXBeginDraw@@YAPAXXZ"));
GXEndDraw = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, GXEndDraw = (void *)GetProcAddress(sys->gapi_dll,
_T("?GXEndDraw@@YAHXZ") ); _T("?GXEndDraw@@YAHXZ"));
GXGetDisplayProperties = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, GXGetDisplayProperties = (void *)GetProcAddress(sys->gapi_dll,
_T("?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ") ); _T("?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ"));
GXSuspend = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, GXSuspend = (void *)GetProcAddress(sys->gapi_dll,
_T("?GXSuspend@@YAHXZ") ); _T("?GXSuspend@@YAHXZ"));
GXResume = GetProcAddress( p_vout->p_sys->gapi_dll, GXResume = GetProcAddress(sys->gapi_dll,
_T("?GXResume@@YAHXZ") ); _T("?GXResume@@YAHXZ"));
if( !GXOpenDisplay || !GXCloseDisplay || !GXBeginDraw || !GXEndDraw || if (!GXOpenDisplay || !GXCloseDisplay ||
!GXGetDisplayProperties || !GXSuspend || !GXResume ) !GXBeginDraw || !GXEndDraw ||
{ !GXGetDisplayProperties || !GXSuspend || !GXResume) {
msg_Err( p_vout, "failed GetProcAddress on gapi.dll" ); msg_Err(vd, "failed GetProcAddress on gapi.dll");
free( p_vout->p_sys ); free(sys);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
msg_Dbg( p_vout, "GAPI DLL loaded" ); msg_Dbg(vd, "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;
#endif #endif
p_vout->pf_init = Init; if (CommonInit(vd))
p_vout->pf_end = End; goto error;
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( p_vout ) ) /* */
video_format_t fmt = vd->fmt;
if (Init(vd, &fmt, fmt.i_width, fmt.i_height))
goto error; 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; return VLC_SUCCESS;
error: error:
CloseVideo( VLC_OBJECT(p_vout) ); Close(VLC_OBJECT(vd));
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/***************************************************************************** /* */
* CloseVideo: deactivate the GDI video output static void Close(vlc_object_t *object)
*****************************************************************************/
static void CloseVideo ( vlc_object_t *p_this )
{ {
vout_thread_t * p_vout = (vout_thread_t *)p_this; vout_display_t *vd = (vout_display_t *)object;
CommonClean( p_vout );
#ifdef MODULE_NAME_IS_wingapi
FreeLibrary( p_vout->p_sys->gapi_dll );
#endif
free( p_vout->p_sys );
}
/*****************************************************************************
* Init: initialize video thread output method
*****************************************************************************/
static int Init( vout_thread_t *p_vout )
{
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]; Clean(vd);
#ifdef MODULE_NAME_IS_wingapi CommonClean(vd);
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;
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;
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES++ ] = p_pic;
/* Change the window title bar text */
#ifdef MODULE_NAME_IS_wingapi #ifdef MODULE_NAME_IS_wingapi
EventThreadUpdateTitle( p_vout->p_sys->p_event, VOUT_TITLE " (WinGAPI output)" ); FreeLibrary(vd->sys->gapi_dll);
#else
EventThreadUpdateTitle( p_vout->p_sys->p_event, VOUT_TITLE " (WinGDI output)" );
#endif #endif
UpdateRects( p_vout, true );
return VLC_SUCCESS; free(vd->sys);
} }
/***************************************************************************** /* */
* End: terminate video thread output method static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
*****************************************************************************/
static void End( vout_thread_t *p_vout )
{ {
#ifdef MODULE_NAME_IS_wingapi VLC_UNUSED(count);
GXCloseDisplay(); return vd->sys->pool;
#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;
}
CommonManage( p_vout );
return VLC_SUCCESS;
} }
static void Display(vout_display_t *vd, picture_t *picture)
/*****************************************************************************
* Render: render previously calculated output
*****************************************************************************/
static void Render( vout_thread_t *p_vout, picture_t *p_pic )
{ {
/* No need to do anything, the fake direct buffers stay as they are */ vout_display_sys_t *sys = vd->sys;
(void)p_vout;
(void)p_pic;
}
/*****************************************************************************
* 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 #ifdef MODULE_NAME_IS_wingapi
static void DisplayGDI( vout_thread_t *p_vout, picture_t *p_pic ) /* */
{ #else
VLC_UNUSED( p_pic ); #define rect_src vd->sys->rect_src
#define rect_src_clipped vd->sys->rect_src_clipped
vout_sys_t *p_sys = p_vout->p_sys; #define rect_dest vd->sys->rect_dest
#define rect_dest_clipped vd->sys->rect_dest_clipped
RECT rect_dst = rect_dest_clipped; RECT rect_dst = rect_dest_clipped;
HDC hdc = GetDC( p_sys->hvideownd ); HDC hdc = GetDC(sys->hvideownd);
OffsetRect( &rect_dst, -rect_dest.left, -rect_dest.top ); OffsetRect(&rect_dst, -rect_dest.left, -rect_dest.top);
SelectObject( p_sys->off_dc, p_sys->off_bitmap ); SelectObject(sys->off_dc, sys->off_bitmap);
if( rect_dest_clipped.right - rect_dest_clipped.left != if (rect_dest_clipped.right - rect_dest_clipped.left !=
rect_src_clipped.right - rect_src_clipped.left || rect_src_clipped.right - rect_src_clipped.left ||
rect_dest_clipped.bottom - rect_dest_clipped.top != rect_dest_clipped.bottom - rect_dest_clipped.top !=
rect_src_clipped.bottom - rect_src_clipped.top ) rect_src_clipped.bottom - rect_src_clipped.top) {
{ StretchBlt(hdc, rect_dst.left, rect_dst.top,
StretchBlt( hdc, rect_dst.left, rect_dst.top,
rect_dst.right, rect_dst.bottom, rect_dst.right, rect_dst.bottom,
p_sys->off_dc, rect_src_clipped.left, rect_src_clipped.top, sys->off_dc,
rect_src_clipped.right, rect_src_clipped.bottom, SRCCOPY ); rect_src_clipped.left, rect_src_clipped.top,
} rect_src_clipped.right, rect_src_clipped.bottom,
else SRCCOPY);
{ } else {
BitBlt( hdc, rect_dst.left, rect_dst.top, BitBlt(hdc, rect_dst.left, rect_dst.top,
rect_dst.right, rect_dst.bottom, rect_dst.right, rect_dst.bottom,
p_sys->off_dc, rect_src_clipped.left, sys->off_dc,
rect_src_clipped.top, SRCCOPY ); rect_src_clipped.left, rect_src_clipped.top,
SRCCOPY);
} }
ReleaseDC( p_sys->hvideownd, hdc ); ReleaseDC(sys->hvideownd, hdc);
#undef rect_src
#undef rect_src_clipped
#undef rect_dest
#undef rect_dest_clipped
#endif
/* TODO */
picture_Release(picture);
CommonDisplay(vd);
} }
static int Control(vout_display_t *vd, int query, va_list args)
{
switch (query) {
case VOUT_DISPLAY_RESET_PICTURES:
assert(0);
return VLC_EGENERIC;
default:
return CommonControl(vd, query, args);
}
static void FirstDisplayGDI( vout_thread_t *p_vout, picture_t *p_pic ) }
static void Manage(vout_display_t *vd)
{ {
/* CommonManage(vd);
** 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;
} }
#else #ifdef MODULE_NAME_IS_wingapi
struct picture_sys_t {
vout_display_t *vd;
};
static int GAPILockSurface( vout_thread_t *p_vout, picture_t *p_pic ) static int Lock(picture_t *picture)
{ {
vout_sys_t *p_sys = p_vout->p_sys; vout_display_t *vd = picture->p_sys->vd;
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; 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; 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()) ) /* */
{ GXDisplayProperties gxdisplayprop = GXGetDisplayProperties();
#ifndef NDEBUG uint8_t *p_pic_buffer = GXBeginDraw();
msg_Err( p_vout, "GXBeginDraw error %d ", GetLastError() ); if (!sys->p_pic_buffer) {
#endif msg_Err(vd, "GXBeginDraw error %d ", GetLastError());
return VLC_EGENERIC; return VLC_EGENERIC;
} }
p_pic_buffer += sys->rect_dest.top * gxdisplayprop.cbyPitch +
sys->rect_dest.left * gxdisplayprop.cbxPitch;
p_src += (dest_rect.left - video_rect.left) * gxdisplayprop.cbxPitch + /* */
(dest_rect.top - video_rect.top) * p_pic->p->i_pitch; picture->p[0].i_pitch = gxdisplayprop.cbyPitch;
p_dest += dest_rect.left * gxdisplayprop.cbxPitch + picture->p[0].p_pixels = p_pic_buffer;
dest_rect.top * gxdisplayprop.cbyPitch;
i_width = dest_rect.right - dest_rect.left;
i_height = dest_rect.bottom - dest_rect.top;
p_pic->p->p_pixels = p_dest;
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static void Unlock(picture_t *picture)
static int GAPIUnlockSurface( vout_thread_t *p_vout, picture_t *p_pic )
{ {
GXEndDraw(); 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 #endif
#undef rect_src static int Init(vout_display_t *vd,
#undef rect_src_clipped video_format_t *fmt, int width, int height)
#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 )
{ {
BITMAPINFOHEADER *p_header = &p_vout->p_sys->bitmapinfo.bmiHeader; vout_display_sys_t *sys = vd->sys;
BITMAPINFO *p_info = &p_vout->p_sys->bitmapinfo;
HDC window_dc = GetDC( p_vout->p_sys->hvideownd );
/* Get screen properties */ /* */
RECT *display = &sys->rect_display;
display->left = 0;
display->top = 0;
#ifdef MODULE_NAME_IS_wingapi #ifdef MODULE_NAME_IS_wingapi
GXDisplayProperties gx_displayprop = GXGetDisplayProperties(); display->right = GXGetDisplayProperties().cxWidth;
p_vout->p_sys->i_depth = gx_displayprop.cBPP; display->bottom = GXGetDisplayProperties().cyHeight;
#else #else
p_vout->p_sys->i_depth = GetDeviceCaps( window_dc, PLANES ) * display->right = GetSystemMetrics(SM_CXSCREEN);;
GetDeviceCaps( window_dc, BITSPIXEL ); display->bottom = GetSystemMetrics(SM_CYSCREEN);;
#endif #endif
msg_Dbg( p_vout, "GDI depth is %i", p_vout->p_sys->i_depth );
#ifdef MODULE_NAME_IS_wingapi /* Initialize an offscreen bitmap for direct buffer operations. */
GXOpenDisplay( p_vout->p_sys->hvideownd, GX_FULLSCREEN );
/* */
HDC window_dc = GetDC(sys->hvideownd);
/* */
#ifdef MODULE_NAME_IS_wingapi
GXDisplayProperties gx_displayprop = GXGetDisplayProperties();
sys->i_depth = gx_displayprop.cBPP;
#else #else
/* Initialize offscreen bitmap */ sys->i_depth = GetDeviceCaps(window_dc, PLANES) *
memset( p_info, 0, sizeof( BITMAPINFO ) + 3 * sizeof( RGBQUAD ) ); GetDeviceCaps(window_dc, BITSPIXEL);
#endif
p_header->biSize = sizeof( BITMAPINFOHEADER ); /* */
p_header->biSizeImage = 0; msg_Dbg(vd, "GDI depth is %i", sys->i_depth);
p_header->biPlanes = 1; switch (sys->i_depth) {
switch( p_vout->p_sys->i_depth )
{
case 8: case 8:
p_header->biBitCount = 8; fmt->i_chroma = VLC_CODEC_RGB8;
p_header->biCompression = BI_RGB;
/* FIXME: we need a palette here */
break; break;
case 15: case 15:
p_header->biBitCount = 15; fmt->i_chroma = VLC_CODEC_RGB15;
p_header->biCompression = BI_BITFIELDS;//BI_RGB; fmt->i_rmask = 0x7c00;
((DWORD*)p_info->bmiColors)[0] = 0x00007c00; fmt->i_gmask = 0x03e0;
((DWORD*)p_info->bmiColors)[1] = 0x000003e0; fmt->i_bmask = 0x001f;
((DWORD*)p_info->bmiColors)[2] = 0x0000001f;
break; break;
case 16: case 16:
p_header->biBitCount = 16; fmt->i_chroma = VLC_CODEC_RGB16;
p_header->biCompression = BI_BITFIELDS;//BI_RGB; fmt->i_rmask = 0xf800;
((DWORD*)p_info->bmiColors)[0] = 0x0000f800; fmt->i_gmask = 0x07e0;
((DWORD*)p_info->bmiColors)[1] = 0x000007e0; fmt->i_bmask = 0x001f;
((DWORD*)p_info->bmiColors)[2] = 0x0000001f;
break; break;
case 24: case 24:
p_header->biBitCount = 24; fmt->i_chroma = VLC_CODEC_RGB24;
p_header->biCompression = BI_RGB; fmt->i_rmask = 0x00ff0000;
((DWORD*)p_info->bmiColors)[0] = 0x00ff0000; fmt->i_gmask = 0x0000ff00;
((DWORD*)p_info->bmiColors)[1] = 0x0000ff00; fmt->i_bmask = 0x000000ff;
((DWORD*)p_info->bmiColors)[2] = 0x000000ff;
break; break;
case 32: case 32:
p_header->biBitCount = 32; fmt->i_chroma = VLC_CODEC_RGB32;
p_header->biCompression = BI_RGB; fmt->i_rmask = 0x00ff0000;
((DWORD*)p_info->bmiColors)[0] = 0x00ff0000; fmt->i_gmask = 0x0000ff00;
((DWORD*)p_info->bmiColors)[1] = 0x0000ff00; fmt->i_bmask = 0x000000ff;
((DWORD*)p_info->bmiColors)[2] = 0x000000ff;
break; break;
default: default:
msg_Err( p_vout, "screen depth %i not supported", msg_Err(vd, "screen depth %i not supported", sys->i_depth);
p_vout->p_sys->i_depth ); return VLC_EGENERIC;
return; }
break; 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;;
}
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
/* */
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_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; UpdateRects(vd, NULL, NULL, true);
p_vout->p_sys->i_pic_pitch = p_header->biBitCount * p_header->biWidth / 8;
return VLC_SUCCESS;
}
p_vout->p_sys->off_bitmap = static void Clean(vout_display_t *vd)
CreateDIBSection( window_dc, (BITMAPINFO *)p_header, DIB_RGB_COLORS, {
&p_vout->p_sys->p_pic_buffer, NULL, 0 ); vout_display_sys_t *sys = vd->sys;
p_vout->p_sys->off_dc = CreateCompatibleDC( window_dc ); if (sys->pool)
picture_pool_Delete(sys->pool);
sys->pool = NULL;
SelectObject( p_vout->p_sys->off_dc, p_vout->p_sys->off_bitmap ); #ifdef MODULE_NAME_IS_wingapi
ReleaseDC( p_vout->p_sys->hvideownd, window_dc ); GXCloseDisplay();
#else
if (sys->off_dc)
DeleteDC(sys->off_dc);
if (sys->off_bitmap)
DeleteObject(sys->off_bitmap);
#endif #endif
} }
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