⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directx.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * vout.c: Windows DirectX video output display method ***************************************************************************** * Copyright (C) 2001-2004 the VideoLAN team * $Id$ * * Authors: Gildas Bazin <gbazin@videolan.org> * * This program 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. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble: * * This plugin will use YUV overlay if supported, using overlay will result in * the best video quality (hardware interpolation when rescaling the picture) * and the fastest display as it requires less processing. * * If YUV overlay is not supported this plugin will use RGB offscreen video * surfaces that will be blitted onto the primary surface (display) to * effectively display the pictures. This fallback method also enables us to * display video in window mode. * *****************************************************************************/#include <errno.h>                                                 /* ENOMEM */#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_interface.h>#include <vlc_playlist.h>#include <vlc_vout.h>#include <windows.h>#include <ddraw.h>#include <commctrl.h>#ifndef UNDER_CE#   include <multimon.h>#endif#undef GetSystemMetrics#ifndef MONITOR_DEFAULTTONEAREST#   define MONITOR_DEFAULTTONEAREST 2#endif#include "vout.h"/***************************************************************************** * picture_sys_t: direct buffer method descriptor ***************************************************************************** * This structure is part of the picture descriptor, it describes the * DirectX specific properties of a direct buffer. *****************************************************************************/struct picture_sys_t{    LPDIRECTDRAWSURFACE2 p_surface;    LPDIRECTDRAWSURFACE2 p_front_surface;    DDSURFACEDESC        ddsd;};/***************************************************************************** * DirectDraw GUIDs. * Defining them here allows us to get rid of the dxguid library during * the linking stage. *****************************************************************************/#include <initguid.h>#undef GUID_EXT#define GUID_EXTDEFINE_GUID( IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 );DEFINE_GUID( IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 );/***************************************************************************** * 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 void SetPalette( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * );static int  NewPictureVec  ( vout_thread_t *, picture_t *, int );static void FreePictureVec ( vout_thread_t *, picture_t *, int );static int  UpdatePictureStruct( vout_thread_t *, picture_t *, int );static int  DirectXInitDDraw      ( vout_thread_t *p_vout );static void DirectXCloseDDraw     ( vout_thread_t *p_vout );static int  DirectXCreateDisplay  ( vout_thread_t *p_vout );static void DirectXCloseDisplay   ( vout_thread_t *p_vout );static int  DirectXCreateSurface  ( vout_thread_t *p_vout,                                    LPDIRECTDRAWSURFACE2 *, int, int, int );static void DirectXCloseSurface   ( vout_thread_t *p_vout,                                    LPDIRECTDRAWSURFACE2 );static int  DirectXCreateClipper  ( vout_thread_t *p_vout );static void DirectXGetDDrawCaps   ( vout_thread_t *p_vout );static int  DirectXLockSurface    ( vout_thread_t *p_vout, picture_t *p_pic );static int  DirectXUnlockSurface  ( vout_thread_t *p_vout, picture_t *p_pic );static DWORD DirectXFindColorkey( vout_thread_t *p_vout, uint32_t *i_color );void SwitchWallpaperMode( vout_thread_t *, bool );/* Object variables callbacks */static int FindDevicesCallback( vlc_object_t *, char const *,                                vlc_value_t, vlc_value_t, void * );static int WallpaperCallback( vlc_object_t *, char const *,                              vlc_value_t, vlc_value_t, void * );/***************************************************************************** * Module descriptor *****************************************************************************/#define HW_YUV_TEXT N_("Use hardware YUV->RGB conversions")#define HW_YUV_LONGTEXT N_( \    "Try to use hardware acceleration for YUV->RGB conversions. " \    "This option doesn't have any effect when using overlays." )#define SYSMEM_TEXT N_("Use video buffers in system memory")#define SYSMEM_LONGTEXT N_( \    "Create video buffers in system memory instead of video memory. This " \    "isn't recommended as usually using video memory allows to benefit from " \    "more hardware acceleration (like rescaling or YUV->RGB conversions). " \    "This option doesn't have any effect when using overlays." )#define TRIPLEBUF_TEXT N_("Use triple buffering for overlays")#define TRIPLEBUF_LONGTEXT N_( \    "Try to use triple buffering when using YUV overlays. That results in " \    "much better video quality (no flickering)." )#define DEVICE_TEXT N_("Name of desired display device")#define DEVICE_LONGTEXT N_("In a multiple monitor configuration, you can " \    "specify the Windows device name of the display that you want the video " \    "window to open on. For example, \"\\\\.\\DISPLAY1\" or " \    "\"\\\\.\\DISPLAY2\"." )#define WALLPAPER_TEXT N_("Enable wallpaper mode ")#define WALLPAPER_LONGTEXT N_( \    "The wallpaper mode allows you to display the video as the desktop " \    "background. Note that this feature only works in overlay mode and " \    "the desktop must not already have a wallpaper." )static const char *const ppsz_dev[] = { "" };static const char *const ppsz_dev_text[] = { N_("Default") };vlc_module_begin();    set_shortname( "DirectX" );    set_category( CAT_VIDEO );    set_subcategory( SUBCAT_VIDEO_VOUT );    add_bool( "directx-hw-yuv", 1, NULL, HW_YUV_TEXT, HW_YUV_LONGTEXT,              true );    add_bool( "directx-use-sysmem", 0, NULL, SYSMEM_TEXT, SYSMEM_LONGTEXT,              true );    add_bool( "directx-3buffering", 1, NULL, TRIPLEBUF_TEXT,              TRIPLEBUF_LONGTEXT, true );    add_string( "directx-device", "", NULL, DEVICE_TEXT, DEVICE_LONGTEXT,                true );        change_string_list( ppsz_dev, ppsz_dev_text, FindDevicesCallback );        change_action_add( FindDevicesCallback, N_("Refresh list") );    add_bool( "directx-wallpaper", 0, NULL, WALLPAPER_TEXT, WALLPAPER_LONGTEXT,              true );    set_description( N_("DirectX video output") );    set_capability( "video output", 100 );    add_shortcut( "directx" );    set_callbacks( OpenVideo, CloseVideo );    /* FIXME: Hack to avoid unregistering our window class */    linked_with_a_crap_library_which_uses_atexit( );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) );#endif/***************************************************************************** * OpenVideo: allocate DirectX video thread output method ***************************************************************************** * This function allocates and initialize the DirectX vout method. *****************************************************************************/static int OpenVideo( vlc_object_t *p_this ){    vout_thread_t * p_vout = (vout_thread_t *)p_this;    vlc_value_t val;    HMODULE huser32;    /* Allocate structure */    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );    if( p_vout->p_sys == NULL )        return VLC_ENOMEM;    memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );    /* Initialisations */    p_vout->pf_init = Init;    p_vout->pf_end = End;    p_vout->pf_manage = Manage;    p_vout->pf_render = NULL;    p_vout->pf_display = FirstDisplay;    p_vout->p_sys->p_ddobject = NULL;    p_vout->p_sys->p_display = NULL;    p_vout->p_sys->p_current_surface = NULL;    p_vout->p_sys->p_clipper = NULL;    p_vout->p_sys->hwnd = p_vout->p_sys->hvideownd = NULL;    p_vout->p_sys->hparent = p_vout->p_sys->hfswnd = NULL;    p_vout->p_sys->i_changes = 0;    p_vout->p_sys->b_wallpaper = 0;    vlc_mutex_init( &p_vout->p_sys->lock );    SetRectEmpty( &p_vout->p_sys->rect_display );    SetRectEmpty( &p_vout->p_sys->rect_parent );    /* Multimonitor stuff */    p_vout->p_sys->hmonitor = NULL;    p_vout->p_sys->p_display_driver = NULL;    p_vout->p_sys->MonitorFromWindow = NULL;    p_vout->p_sys->GetMonitorInfo = NULL;    if( (huser32 = GetModuleHandle( _T("USER32") ) ) )    {        p_vout->p_sys->MonitorFromWindow = (HMONITOR (WINAPI *)( HWND, DWORD ))            GetProcAddress( huser32, _T("MonitorFromWindow") );        p_vout->p_sys->GetMonitorInfo =#ifndef UNICODE            GetProcAddress( huser32, "GetMonitorInfoA" );#else            GetProcAddress( huser32, _T("GetMonitorInfoW") );#endif    }    var_Create( p_vout, "overlay", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );    var_Create( p_vout, "directx-use-sysmem", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );    var_Create( p_vout, "directx-hw-yuv", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );    var_Create( p_vout, "directx-3buffering", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );    var_Create( p_vout, "directx-device", VLC_VAR_STRING | VLC_VAR_DOINHERIT );    var_Create( p_vout, "video-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT );    var_Create( p_vout, "disable-screensaver", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );    p_vout->p_sys->b_cursor_hidden = 0;    p_vout->p_sys->i_lastmoved = mdate();    p_vout->p_sys->i_mouse_hide_timeout =        var_GetInteger(p_vout, "mouse-hide-timeout") * 1000;    /* Set main window's size */    p_vout->p_sys->i_window_width = p_vout->i_window_width;    p_vout->p_sys->i_window_height = p_vout->i_window_height;    /* Create the Vout EventThread, this thread is created by us to isolate     * the Win32 PeekMessage function calls. We want to do this because     * Windows can stay blocked inside this call for a long time, and when     * this happens it thus blocks vlc's video_output thread.     * DirectXEventThread will take care of the creation of the video     * window (because PeekMessage has to be called from the same thread which     * created the window). */    msg_Dbg( p_vout, "creating DirectXEventThread" );    p_vout->p_sys->p_event =        vlc_object_create( p_vout, sizeof(event_thread_t) );    p_vout->p_sys->p_event->p_vout = p_vout;    if( vlc_thread_create( p_vout->p_sys->p_event, "Vout Events Thread",                           EventThread, 0, 1 ) )    {        msg_Err( p_vout, "cannot create Vout EventThread" );        vlc_object_release( p_vout->p_sys->p_event );        p_vout->p_sys->p_event = NULL;        goto error;    }    if( p_vout->p_sys->p_event->b_error )    {        msg_Err( p_vout, "Vout EventThread failed" );        goto error;    }    vlc_object_attach( p_vout->p_sys->p_event, p_vout );    msg_Dbg( p_vout, "Vout EventThread running" );    /* Initialise DirectDraw */    if( DirectXInitDDraw( p_vout ) )    {        msg_Err( p_vout, "cannot initialize DirectX DirectDraw" );        goto error;    }    /* Create the directx display */    if( DirectXCreateDisplay( p_vout ) )    {        msg_Err( p_vout, "cannot initialize DirectX DirectDraw" );        goto error;    }    /* Variable to indicate if the window should be on top of others */    /* Trigger a callback right now */    var_Get( p_vout, "video-on-top", &val );    var_Set( p_vout, "video-on-top", val );    /* Variable to indicate if the window should be on top of others */    /* Trigger a callback right now */    var_Create( p_vout, "directx-wallpaper", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );    val.psz_string = _("Wallpaper");    var_Change( p_vout, "directx-wallpaper", VLC_VAR_SETTEXT, &val, NULL );    var_AddCallback( p_vout, "directx-wallpaper", WallpaperCallback, NULL );    var_Get( p_vout, "directx-wallpaper", &val );    var_Set( p_vout, "directx-wallpaper", val );    /* disable screensaver by temporarily changing system settings */    p_vout->p_sys->i_spi_lowpowertimeout = 0;    p_vout->p_sys->i_spi_powerofftimeout = 0;    p_vout->p_sys->i_spi_screensavetimeout = 0;    var_Get( p_vout, "disable-screensaver", &val);    if( val.b_bool ) {        msg_Dbg(p_vout, "disabling screen saver");        SystemParametersInfo(SPI_GETLOWPOWERTIMEOUT,            0, &(p_vout->p_sys->i_spi_lowpowertimeout), 0);        if( 0 != p_vout->p_sys->i_spi_lowpowertimeout ) {            SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT, 0, NULL, 0);        }        SystemParametersInfo(SPI_GETPOWEROFFTIMEOUT, 0,            &(p_vout->p_sys->i_spi_powerofftimeout), 0);        if( 0 != p_vout->p_sys->i_spi_powerofftimeout ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -