Index: AUTHORS =================================================================== --- AUTHORS (revision 27943) +++ AUTHORS (working copy) @@ -627,6 +627,9 @@ * Windows support improvements * Cygwin installer package +Petrov, Georgi (gogothebee) + * Direct3D VO driver + Pietrzak, Dariusz (Eyck) * Debian packaging support (see debian/* and the documentation) * support for vplayer subtitle format Index: libvo/vo_direct3d.c =================================================================== --- libvo/vo_direct3d.c (revision 0) +++ libvo/vo_direct3d.c (revision 0) @@ -0,0 +1,682 @@ +/* + * Copyright (c) 2008 Georgi Petrov (gogothebee) + * + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" +#include "fastmemcpy.h" +#include "mp_msg.h" +#include "w32_common.h" + +static const vo_info_t info = +{ + "Direct3D 9 Renderer", + "direct3d", + "Georgi Petrov (gogothebee) ", + "" +}; + +/* + * Link essential libvo functions: preinit, config, control, draw_frame, + * draw_slice, draw_osd, flip_page, check_events, uninit and + * the structure info. + */ +const LIBVO_EXTERN(direct3d) + + +/* Global variables. Each one starts with "g". Pointers include "p". + * I try to keep their count low. + */ + +int gIsPaused; /**< 1 = Movie is paused, + 0 = Movie is not paused */ +int gIsD3DConfigFinished; /**< Synchronization "semaphore". 1 when + instance of D3DConfigure is finished */ +RECT gFullScrMovieRect; /**< Rect (upscaled) of the movie when displayed + in fullscreen */ +int gSrcWidth; /**< Source (movie) width */ +int gSrcHeight; /**< Source (movie) heigth */ +float gAspectRatio; /**< Movie aspect ratio. Used to calculate + scaling while preserving aspect ratio */ +LPDIRECT3D9 gpD3DHandle; /**< Direct3D Handle */ +LPDIRECT3DDEVICE9 gpD3DDevice; /**< The Direct3D Adapter */ +IDirect3DSurface9 *gpD3DSurface; /**< Offscreen Direct3D Surface. MPlayer + renders inside it. Uses colorspace + MovieSrcFmt */ +IDirect3DSurface9 *gpD3DBackBuf; /**< Video card's back buffer (used to + display next frame) */ +D3DFORMAT gMovieSrcFmt; /**< Movie colorspace format (depends on + the movie's codec) */ +D3DFORMAT gDesktopFmt; /**< Desktop (screen) colorspace format. + Usually XRGB */ +typedef struct +{ + const unsigned int MPlayerFormat; /**< Given by MPlayer */ + const D3DFORMAT FourCC; /**< Required by D3D's test function */ +} DisplayFormatTable; + +/* Map table from reported MPlayer format to the required + FourCC. This is needed to perform the format query. */ + +static const DisplayFormatTable gDisplayFormatTable[] = +{ + {IMGFMT_YV12, MAKEFOURCC('Y','V','1','2')}, + {IMGFMT_I420, MAKEFOURCC('I','4','2','0')}, + {IMGFMT_IYUV, MAKEFOURCC('I','Y','U','V')}, + {IMGFMT_YVU9, MAKEFOURCC('Y','V','U','9')}, + {IMGFMT_YUY2, MAKEFOURCC('Y','U','Y','2')}, + {IMGFMT_UYVY, MAKEFOURCC('U','Y','V','Y')} +}; + +#define DISPLAY_FORMAT_TABLE_ENTRIES \ + (sizeof(gDisplayFormatTable) / sizeof(gDisplayFormatTable[0])) + +/**************************************************************************** + * * + * * + * * + * Direct3D specific implementation functions * + * * + * * + * * + ****************************************************************************/ + +/** @brief Calculate scaled fullscreen movie rectangle with + * preserved aspect ratio. + * @return TRUE on success, FALSE on failure + */ +void CalculateFullscreenRect (void) +{ + int ScaledHeight = 0; + int ScaledWidth = 0; + /* If we've created fullscreen context, we should calculate stretched + * movie's RECT, otherwise it will fill the whole fullscreen with + * wrong aspect ratio */ + + if (gSrcWidth > gSrcHeight) + { + ScaledHeight = (int) ((float) vo_dwidth / gAspectRatio); + gFullScrMovieRect.left = 0; + gFullScrMovieRect.right = vo_dwidth; + gFullScrMovieRect.top = + ((vo_screenheight - ScaledHeight) / 2); + gFullScrMovieRect.bottom = + gFullScrMovieRect.top + ScaledHeight; + } else if (gSrcHeight > gSrcWidth) + { + ScaledWidth = (int) ((float) vo_dheight * gAspectRatio); + gFullScrMovieRect.top = 0; + gFullScrMovieRect.bottom = vo_dheight; + gFullScrMovieRect.left = + ((vo_screenwidth - ScaledWidth) / 2); + gFullScrMovieRect.right = + gFullScrMovieRect.left + ScaledWidth; + + } else /* Perfect square */ + { + gFullScrMovieRect.top = 0; + gFullScrMovieRect.left = 0; + gFullScrMovieRect.right = vo_dheight; + gFullScrMovieRect.bottom = vo_dwidth; + } + mp_msg(MSGT_VO,MSGL_V, + "Fullscreen Movie Rect: t: %ld, l: %ld, r: %ld, b:%ld\r\n", + gFullScrMovieRect.top, gFullScrMovieRect.left, + gFullScrMovieRect.right, gFullScrMovieRect.bottom); + +} + +/** @brief Destroy D3D Context related to the current window. + * @return TRUE on success, FALSE on failure + */ +void D3DDestroyContext (void) +{ + mp_msg(MSGT_VO,MSGL_V,"D3DDestroyContext called\r\n"); + /* Let's destroy the old (if any) D3D Content */ + + if (gpD3DSurface != NULL) + { + IDirect3DSurface9_Release (gpD3DSurface); + gpD3DSurface = NULL; + } + + if (gpD3DDevice != NULL) + { + IDirect3DDevice9_Release (gpD3DDevice); + gpD3DDevice = NULL; + } + + /* The following is not a memory leak. pD3DBackBuf is not malloc'ed + * but just holds a pointer to the back buffer. Nobody gets hurt from + * setting it to NULL. + */ + gpD3DBackBuf = NULL; +} + + +/** @brief (Re)Initialize Direct3D. Kill and recreate context. + * @return TRUE on success, FALSE on failure + * The first function called to init D3D context. + */ +int D3DConfigure (void) +{ + D3DPRESENT_PARAMETERS PresentParams; + D3DDISPLAYMODE DisplayMode; + + mp_msg(MSGT_VO,MSGL_V,"D3DConfigure CALLED\n"); + + D3DDestroyContext(); + + /* Get the current desktop display mode, so we can set up a back buffer + * of the same format. */ + if (FAILED (IDirect3D9_GetAdapterDisplayMode (gpD3DHandle, + D3DADAPTER_DEFAULT, + &DisplayMode))) + { + mp_msg(MSGT_VO,MSGL_ERR, + "Could not read adapter display mode.\n"); + return FALSE; + } + + /* Write current Desktop's colorspace format in the global storage. */ + gDesktopFmt = DisplayMode.Format; + + /* Prepare Direct3D initialization parameters. */ + memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS)); + PresentParams.Windowed = TRUE; + PresentParams.SwapEffect = D3DSWAPEFFECT_COPY; + PresentParams.Flags = D3DPRESENTFLAG_VIDEO; + PresentParams.hDeviceWindow = vo_w32_window; /* w32_common var */ + PresentParams.BackBufferWidth = 0; /* Fill up window Width */ + PresentParams.BackBufferHeight = 0; /* Fill up window Height */ + PresentParams.MultiSampleType = D3DMULTISAMPLE_NONE; + /* D3DPRESENT_INTERVAL_ONE = vsync */ + PresentParams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + PresentParams.BackBufferFormat = gDesktopFmt; + PresentParams.BackBufferCount = 1; + PresentParams.EnableAutoDepthStencil = FALSE; + + /* vo_w32_window is w32_common variable. It's a handle to the window. */ + if (FAILED (IDirect3D9_CreateDevice(gpD3DHandle, + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, vo_w32_window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + /* D3DDEVCAPS HWTRANSFORMANDLIGHT */ + &PresentParams, &gpD3DDevice))) + { + mp_msg(MSGT_VO,MSGL_ERR, + "Could not create the D3D device\n"); + return FALSE; + } + + mp_msg(MSGT_VO,MSGL_V, + "New BackBuffer: Width: %d, Height:%d. VO Dest Width:%d, Height: %d\n", + PresentParams.BackBufferWidth, PresentParams.BackBufferHeight, + vo_dwidth, vo_dheight); + + if (FAILED (IDirect3DDevice9_CreateOffscreenPlainSurface( + gpD3DDevice, gSrcWidth, gSrcHeight, + gMovieSrcFmt, D3DPOOL_DEFAULT, &gpD3DSurface, NULL))) + { + mp_msg(MSGT_VO,MSGL_ERR, + "IDirect3D9_CreateOffscreenPlainSurface Failed.\n"); + return FALSE; + } + + if (FAILED (IDirect3DDevice9_GetBackBuffer (gpD3DDevice, 0, 0, + D3DBACKBUFFER_TYPE_MONO, + &(gpD3DBackBuf)))) + { + mp_msg(MSGT_VO,MSGL_ERR,"Back Buffer address get failed\n"); + return FALSE; + } + + /* Fill the Surface with black color. */ + IDirect3DDevice9_ColorFill(gpD3DDevice, gpD3DSurface, NULL, + D3DCOLOR_ARGB(0xFF, 0, 0, 0) ); + + if (vo_fs == 1) + CalculateFullscreenRect (); + + return TRUE; +} + +/** @brief Uninitialize Direct3D and close the window. + * @return N/A + */ +void D3DUninit(void) +{ + mp_msg(MSGT_VO,MSGL_V,"D3DUninit called\r\n"); + + /* Block further calls to D3DConfigure(). */ + gIsD3DConfigFinished = 0; + + /* Destroy D3D Context inside the window. */ + D3DDestroyContext(); + + /* Stop the whole D3D. */ + if (NULL != gpD3DHandle) + { + mp_msg(MSGT_VO,MSGL_V,"Calling IDirect3D9_Release\r\n"); + IDirect3D9_Release (gpD3DHandle); + } +} + +/** @brief Render a frame on the screen. + * @param mpi Mpi structure with the decoded frame inside + * @return VO_TRUE on success, VO_ERROR on failure + */ +static uint32_t D3DRenderFrame (mp_image_t *mpi) +{ + D3DLOCKED_RECT stLockedRect; /**< Offscreen surface we lock in order + to copy MPlayer's frame inside it.*/ + + /* Uncomment when direct rendering is implemented. + * if (mpi->flags & MP_IMGFLAG_DIRECT) ... + */ + + if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) + return VO_TRUE; + + if (mpi->flags & MP_IMGFLAG_PLANAR) + { /* Copy a planar frame. */ + draw_slice(mpi->planes,mpi->stride,mpi->w,mpi->h,0,0); + return VO_TRUE; + } + + /* If the previous if failed, we should draw a packed frame */ + + if (FAILED (IDirect3DSurface9_LockRect(gpD3DSurface, + &stLockedRect, NULL, 0))) + { + mp_msg(MSGT_VO,MSGL_ERR,"Surface lock failure\n"); + return VO_FALSE; + } + + memcpy_pic(stLockedRect.pBits, mpi->planes[0], mpi->stride[0], + mpi->height, stLockedRect.Pitch, mpi->stride[0]); + + if (FAILED (IDirect3DDevice9_StretchRect (gpD3DDevice, + gpD3DSurface,NULL, + gpD3DBackBuf, + vo_fs == 1 ? + &gFullScrMovieRect : NULL, + D3DTEXF_LINEAR))) + { + mp_msg(MSGT_VO,MSGL_ERR, + "Unable to copy the frame to the back buffer\n"); + return VO_ERROR; + } + + return VO_TRUE; +} + + +/** @brief Query if movie's colorspace is supported by the HW. + * @return 0 on failure, device capabilities (not probed + * currently) on success. + */ +static int query_format (uint32_t MovieFormat) +{ + int i; + for (i=0; i < DISPLAY_FORMAT_TABLE_ENTRIES; i++) + { + if (gDisplayFormatTable[i].MPlayerFormat == MovieFormat) + { + /* Test conversion from Movie colorspace to + * display's target colorspace. */ + if (FAILED (IDirect3D9_CheckDeviceFormatConversion( + gpD3DHandle, + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + gDisplayFormatTable[i].FourCC, + gDesktopFmt))) + return 0; + + gMovieSrcFmt = gDisplayFormatTable[i].FourCC; + mp_msg(MSGT_VO,MSGL_V,"Accepted Colorspace %s\n", + vo_format_name(gDisplayFormatTable[i].MPlayerFormat)); + return (VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW + /*| VFCAP_OSD*/ | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN); + + } + } + + return 0; +} + +/**************************************************************************** + * * + * * + * * + * libvo Control / Callback functions * + * * + * * + * * + ****************************************************************************/ + + + + +/** @brief libvo Callback: Preinitialize the video card. + * @return TRUE on success, FALSE on failure + * + * Preinit the hardware just enough to be queried about + * supported formats. + */ +static int preinit(const char *arg) +{ + D3DDISPLAYMODE DisplayMode; + /* Set to zero all global variables. */ + gIsPaused = 0; + gIsD3DConfigFinished = 0; + gpD3DHandle = NULL; + gpD3DDevice = NULL; + gpD3DSurface = NULL; + gpD3DBackBuf = NULL; + + /* FIXME + > Please use subopt-helper.h for this, see vo_gl.c:preinit for + > an example of how to use it. + */ + + if ((gpD3DHandle = Direct3DCreate9 (D3D_SDK_VERSION)) == NULL) + { + mp_msg(MSGT_VO,MSGL_ERR,"Unable to initialize Direct3D\n"); + return -1; + } + + if (FAILED (IDirect3D9_GetAdapterDisplayMode (gpD3DHandle, + D3DADAPTER_DEFAULT, + &DisplayMode))) + { + mp_msg(MSGT_VO,MSGL_ERR,"Could not read display mode\n"); + return -1; + } + + /* Store in gDesktopFmt the user desktop's colorspace. Usually XRGB. */ + gDesktopFmt = DisplayMode.Format; + + mp_msg(MSGT_VO,MSGL_V,"DisplayMode.Width %d, DisplayMode.Height %d\n", + DisplayMode.Width, DisplayMode.Height); + + /* w32_common framework call. Configures window on the screen, gets + * fullscreen dimensions and does other useful stuff. + */ + if (vo_w32_init() == 0) + { + mp_msg(MSGT_VO,MSGL_V,"Unable to configure onscreen window\r\n"); + return -1; + } + + /* Allow the first call to D3DConfigure. */ + gIsD3DConfigFinished = 1; + + return 0; +} + + + +/** @brief libvo Callback: Handle control requests. + * @return VO_TRUE on success, VO_NOTIMPL when not + * implemented + */ +static int control(uint32_t request, void *data, ...) +{ + switch (request) + { + case VOCTRL_QUERY_FORMAT: + return query_format (*(uint32_t*) data); + case VOCTRL_GET_IMAGE: /* Direct Rendering. Not implemented yet. */ + mp_msg(MSGT_VO,MSGL_V, + "Direct Rendering request. Not implemented yet\n"); + return VO_NOTIMPL; + case VOCTRL_DRAW_IMAGE: + D3DRenderFrame (data); + return VO_TRUE; + case VOCTRL_FULLSCREEN: + vo_w32_fullscreen(); + D3DConfigure(); + return VO_TRUE; + case VOCTRL_RESET: + return VO_NOTIMPL; + case VOCTRL_PAUSE: + gIsPaused = 1; + return VO_TRUE; + case VOCTRL_RESUME: + gIsPaused = 0; + return VO_TRUE; + case VOCTRL_GUISUPPORT: + return VO_NOTIMPL; + case VOCTRL_SET_EQUALIZER: + return VO_NOTIMPL; + case VOCTRL_GET_EQUALIZER: + return VO_NOTIMPL; + case VOCTRL_ONTOP: + vo_w32_ontop(); + return VO_TRUE; + case VOCTRL_BORDER: + vo_w32_border(); + return VO_TRUE; + case VOCTRL_UPDATE_SCREENINFO: + w32_update_xinerama_info(); + return VO_TRUE; + } + return VO_FALSE; +} + +/** @brief libvo Callback: Configre the Direct3D adapter. + * @param width Movie source width + * @param height Movie source height + * @param d_width Screen (destination) width + * @param d_height Screen (destination) height + * @param options Options bitmap + * @param title Windows title + * @param format Movie colorspace format (using Mplayer's + * defines, e.g. IMGFMT_YUY2) + * @return 0 on success, VO_ERROR on failure + */ +static int config(uint32_t width, uint32_t height, uint32_t d_width, + uint32_t d_height, uint32_t options, char *title, + uint32_t format) +{ + gSrcWidth = width; + gSrcHeight = height; + + /* w32_common framework call. Creates window on the screen with + * the given coordinates. + */ + if (vo_w32_config(d_width, d_height, options) == 0) + { + mp_msg(MSGT_VO,MSGL_V,"Unable to create onscreen window\r\n"); + return VO_ERROR; + } + + gAspectRatio = (float)d_width / (float)d_height; + + if (gIsD3DConfigFinished == 1) + { + gIsD3DConfigFinished = 0; + if (D3DConfigure () == FALSE) + { + gIsD3DConfigFinished = 1; + return VO_ERROR; + } + gIsD3DConfigFinished = 1; + } + return 0; /* Success */ +} + +/** @brief libvo Callback: Flip next already drawn frame on the + * screen. + * @return N/A + */ +static void flip_page(void) +{ + if (FAILED (IDirect3DDevice9_Present (gpD3DDevice, 0, 0, 0, 0))) + { + mp_msg(MSGT_VO,MSGL_V, + "Video adapter became uncooperative.\n"); + mp_msg(MSGT_VO,MSGL_ERR,"Trying to reinitialize it...\n"); + if (D3DConfigure() == FALSE) + { + mp_msg(MSGT_VO,MSGL_V,"Reinitialization Failed.\n"); + return; + } + if (FAILED (IDirect3DDevice9_Present (gpD3DDevice, 0, 0, 0, 0))) + { + mp_msg(MSGT_VO,MSGL_V,"Reinitialization Failed.\n"); + return; + } + else + mp_msg(MSGT_VO,MSGL_V,"Video adapter reinitialized.\n"); + + } +} + +/** @brief libvo Callback: Draw OSD/Subtitles, + * @return N/A + */ +static void draw_osd(void) +{ +} + +/** @brief libvo Callback: Uninitializes all pointers and closes + * all D3D related stuff, + * @return N/A + */ +static void uninit(void) +{ + mp_msg(MSGT_VO,MSGL_V,"Uninitialization\r\n"); + + /* Release everything related to D3D, */ + D3DUninit(); + + /* w32_common framework call. Uninitialize all window-handling specific + * stuff. + */ + vo_w32_uninit(); +} + +/** @brief libvo Callback: Handles video window events. + * @return N/A + */ +static void check_events(void) +{ + int Flags; + /* w32_common framework call. Handles video window events. + * Updates global libvo's vo_dwidth/vo_dheight upon resize + * with the new window width/height. I copy them to gConfig + */ + Flags = vo_w32_check_events(); + if (Flags & VO_EVENT_RESIZE) + D3DConfigure(); + + if ((Flags & VO_EVENT_EXPOSE) && gIsPaused == TRUE) + flip_page(); +} + +/** @brief libvo Callback: Draw slice + * @return 0 on success + */ +static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y ) +{ + D3DLOCKED_RECT stLockedRect; /**< Offscreen surface we lock in order + to copy MPlayer's frame inside it.*/ + char *Src; /**< Pointer to the source image */ + char *Dst; /**< Pointer to the destination image */ + int UVstride; /**< Stride of the U/V planes */ + + if (FAILED (IDirect3DSurface9_LockRect(gpD3DSurface, + &stLockedRect, NULL, 0))) + { + mp_msg(MSGT_VO,MSGL_V,"Surface lock failure\n"); + return VO_FALSE; + } + + UVstride = stLockedRect.Pitch / 2; + + /* Copy Y */ + Dst = stLockedRect.pBits; + Dst = Dst + stLockedRect.Pitch * y + x; + Src=src[0]; + memcpy_pic(Dst, Src, w, h, stLockedRect.Pitch, stride[0]); + + w/=2;h/=2;x/=2;y/=2; + + /* Copy U */ + Dst = stLockedRect.pBits; + Dst = Dst + stLockedRect.Pitch * gSrcHeight + + UVstride * y + x; + if (gMovieSrcFmt == MAKEFOURCC('Y','V','1','2')) + Src=src[2]; + else + Src=src[1]; + + memcpy_pic(Dst, Src, w, h, UVstride, stride[1]); + + /* Copy V */ + Dst = stLockedRect.pBits; + Dst = Dst + stLockedRect.Pitch * gSrcHeight + + UVstride * (gSrcHeight / 2) + UVstride * y + x; + if (gMovieSrcFmt == MAKEFOURCC('Y','V','1','2')) + Src=src[1]; + else + Src=src[2]; + + memcpy_pic(Dst, Src, w, h, UVstride, stride[2]); + + if (FAILED (IDirect3DSurface9_UnlockRect(gpD3DSurface))) + { + mp_msg(MSGT_VO,MSGL_V,"Surface unlock failure\n"); + return VO_ERROR; + } + + if (FAILED (IDirect3DDevice9_StretchRect (gpD3DDevice, + gpD3DSurface,NULL, + gpD3DBackBuf, + vo_fs == 1 ? + &gFullScrMovieRect : NULL, + D3DTEXF_LINEAR))) + { + mp_msg(MSGT_VO,MSGL_V, + "Unable to copy the frame to the back buffer\n"); + return VO_ERROR; + } + + return 0; /* Success */ +} + +/** @brief libvo Callback: Unused function + * @return N/A + */ +static int draw_frame(uint8_t *src[]) +{ + mp_msg(MSGT_VO,MSGL_V,"draw_frame called\n"); + return VO_FALSE; +} + + + + Index: libvo/video_out.c =================================================================== --- libvo/video_out.c (revision 27943) +++ libvo/video_out.c (working copy) @@ -93,6 +93,7 @@ extern vo_functions_t video_out_caca; extern vo_functions_t video_out_mpegpes; extern vo_functions_t video_out_yuv4mpeg; +extern vo_functions_t video_out_direct3d; extern vo_functions_t video_out_directx; extern vo_functions_t video_out_dxr2; extern vo_functions_t video_out_dxr3; @@ -122,6 +123,9 @@ #ifdef CONFIG_TDFX_VID &video_out_tdfx_vid, #endif +#ifdef CONFIG_DIRECT3D + &video_out_direct3d, +#endif #ifdef CONFIG_DIRECTX &video_out_directx, #endif Index: libvo/w32_common.c =================================================================== --- libvo/w32_common.c (revision 27943) +++ libvo/w32_common.c (working copy) @@ -149,6 +149,24 @@ return DefWindowProc(hWnd, message, wParam, lParam); } +/** @brief Dispatch incoming window events and handle them. + * + * This function should be placed inside libvo's function "check_events". + * + * Global libvo variables changed: + * vo_dwidth: New window client area width + * vo_dheight: New window client area height + * + * @return + * Integer with optionally enabled flags. Important - check resize/expose + * exactly in the order given: + * + * 0 = Nothing changed + * VO_EVENT_RESIZE = The window was resized. Please reinit yout driver's + * render context accordingly. + * VO_EVENT_EXPOSE = The window was exposed. Call flip_frame() to draw inside + * if the movie is paused. + */ int vo_w32_check_events(void) { MSG msg; event_flags = 0; @@ -177,7 +195,19 @@ mon_cnt++; return TRUE; } - +/** @brief Update screen information. + * + * This function should be called in libvo's "control" callback + * with parameter VOCTRL_UPDATE_SCREENINFO. + * + * Global libvo variables changed: + * xinerama_x + * xinerama_y + * vo_screenwidth + * vo_screenheight + * + * @return N/A + */ void w32_update_xinerama_info(void) { xinerama_x = xinerama_y = 0; if (xinerama_screen < -1) { @@ -332,6 +362,17 @@ return 1; } +/** @Brief Configure and create window on the screen. + * + * This function should be called in libvo's "config" callback. + * It configures a window and shows in on the screen. + * + * Global libvo variables changed: + * vo_fs + * vo_vm + * + * @return 0 - Success, 1 - Failure + */ int vo_w32_config(uint32_t width, uint32_t height, uint32_t flags) { // store original size for videomode switching o_dwidth = width; @@ -347,6 +388,22 @@ return createRenderingContext(); } +/** @brief Initialize w32_common framework. + * + * The first function that should be called from the w32_common framework. + * It handles window creation on the screen with proper title and attributes. + * It also initializes framework's internal variables. The function should be + * called after your own preinit initialization and you shouldn't do any + * window management on your own. + * + * Global libvo variables changed: + * vo_w32_window + * vo_depthonscreen + * vo_screenwidth + * vo_screenheight + * + * @return 1 = Success, 0 = Failure + */ int vo_w32_init(void) { HICON mplayerIcon = 0; char exedir[MAX_PATH]; @@ -403,17 +460,49 @@ return 1; } +/** @brief Toogle fullscreen / windowed mode. + * + * Should be called on VOCTRL_FULLSCREEN event. The window is + * always resized after this call, so the rendering context + * should be reinitialized with the new dimensions. + * + * Global libvo variables changed: + * vo_dwidth + * vo_dheight + * vo_fs + * + * @return N/A + */ + void vo_w32_fullscreen(void) { vo_fs = !vo_fs; createRenderingContext(); } -void vo_w32_border(void) { +/** @brief Toogle window border attribute. + * + * Should be called on VOCTRL_BORDER event. + * + * Global libvo variables changed: + * vo_border + * + * @return N/A + */ +void vo_w32_border() { vo_border = !vo_border; createRenderingContext(); } +/** @brief Toogle window ontop attribute. + * + * Should be called on VOCTRL_ONTOP event. + * + * Global libvo variables changed: + * vo_ontop + * + * @return N/A + */ void vo_w32_ontop( void ) { vo_ontop = !vo_ontop; @@ -422,7 +511,15 @@ } } -void vo_w32_uninit(void) { +/** @brief Uninitialize w32_common framework. + * + * Should be called last in video driver's uninit function. First release + * anything build ontop of the created window e.g. rendering context inside + * and call vo_w32_uninit at the end. + * + * @return N/A + */ +void vo_w32_uninit() { mp_msg(MSGT_VO, MSGL_V, "vo: win32: uninit\n"); resetMode(); ShowCursor(1); Index: configure =================================================================== --- configure (revision 27943) +++ configure (working copy) @@ -369,6 +369,7 @@ --enable-caca enable CACA video output [autodetect] --enable-ggi enable GGI video output [autodetect] --enable-ggiwmh enable GGI libggiwmh extension [autodetect] + --enable-direct3d enable Direct3D video output [autodetect] --enable-directx enable DirectX video output [autodetect] --enable-dxr2 enable DXR2 video output [autodetect] --enable-dxr3 enable DXR3/H+ video output [autodetect] @@ -547,6 +548,7 @@ _xv=auto _xvmc=no #auto when complete _sdl=auto +_direct3d=auto _directx=auto _win32waveout=auto _nas=auto @@ -867,6 +869,8 @@ --disable-xvmc) _xvmc=no ;; --enable-sdl) _sdl=yes ;; --disable-sdl) _sdl=no ;; + --enable-direct3d) _direct3d=yes ;; + --disable-direct3d) _direct3d=no ;; --enable-directx) _directx=yes ;; --disable-directx) _directx=no ;; --enable-win32waveout) _win32waveout=yes ;; @@ -4897,6 +4901,27 @@ fi echores "$_win32waveout" +echocheck "Direct3D" +if test "$_direct3d" = auto ; then + cat > $TMPC << EOF +#include +#include +int main(void) { return 0; } +EOF + _direct3d=no + cc_check -ld3d9 && _direct3d=yes +fi +if test "$_direct3d" = yes ; then + _def_direct3d='#define CONFIG_DIRECT3D 1' + _libs_mplayer="$_libs_mplayer -ld3d9" + _vosrc="$_vosrc vo_direct3d.c" + _vomodules="direct3d $_vomodules" +else + _def_direct3d='#undef CONFIG_DIRECT3D' + _novomodules="direct3d $_novomodules" +fi +echores "$_direct3d" + echocheck "Directx" if test "$_directx" = auto ; then cat > $TMPC << EOF @@ -8372,6 +8397,7 @@ $_def_dga $_def_dga1 $_def_dga2 +$_def_direct3d $_def_directfb $_def_directfb_version $_def_directx Index: DOCS/tech/MAINTAINERS =================================================================== --- DOCS/tech/MAINTAINERS (revision 27943) +++ DOCS/tech/MAINTAINERS (working copy) @@ -162,6 +162,7 @@ * vo_cvidix.c - Sascha Sommer * vo_dga.c - None * vo_dfbmga.c - Ville Syrjälä + * vo_direct3d.c - Georgi Petrov * vo_directfb[2].c - Jiri Svoboda * vo_directx.c - Sascha Sommer * vo_dxr2.c - Alban Bedel