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

📄 directx.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * vout.c: Windows DirectX video output display method ***************************************************************************** * Copyright (C) 2001-2004 VideoLAN * $Id: directx.c 11257 2005-06-02 17:06:00Z fkuehne $ * * 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., 59 Temple Place - Suite 330, Boston, MA  02111, 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 */#include <stdlib.h>                                                /* free() */#include <string.h>                                            /* strerror() */#include <vlc/vlc.h>#include <vlc/intf.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"/***************************************************************************** * DirectDraw GUIDs. * Defining them here allows us to get rid of the dxguid library during * the linking stage. *****************************************************************************/#include <initguid.h>DEFINE_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 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 *, vlc_bool_t );/* 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 char *ppsz_dev[] = { "" };static char *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,              VLC_TRUE );    add_bool( "directx-use-sysmem", 0, NULL, SYSMEM_TEXT, SYSMEM_LONGTEXT,              VLC_TRUE );    add_bool( "directx-3buffering", 1, NULL, TRIPLEBUF_TEXT,              TRIPLEBUF_LONGTEXT, VLC_TRUE );    add_string( "directx-device", "", NULL, DEVICE_TEXT, DEVICE_LONGTEXT,                VLC_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,              VLC_TRUE );    set_description( _("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 )    {        msg_Err( p_vout, "out of memory" );        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 = Display;    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_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 );    p_vout->p_sys->b_cursor_hidden = 0;    p_vout->p_sys->i_lastmoved = mdate();    /* 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 DirectXEventThread, 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, "DirectX Events Thread",                           E_(DirectXEventThread), 0, 1 ) )    {        msg_Err( p_vout, "cannot create DirectXEventThread" );        vlc_object_destroy( 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, "DirectXEventThread failed" );        goto error;    }    vlc_object_attach( p_vout->p_sys->p_event, p_vout );    msg_Dbg( p_vout, "DirectXEventThread running" );    /* Initialise DirectDraw */    if( DirectXInitDDraw( p_vout ) )    {        msg_Err( p_vout, "cannot initialize DirectDraw" );        goto error;    }    /* Create the directx display */    if( DirectXCreateDisplay( p_vout ) )    {        msg_Err( p_vout, "cannot initialize 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 );    return VLC_SUCCESS; error:    CloseVideo( VLC_OBJECT(p_vout) );    return VLC_EGENERIC;}/***************************************************************************** * Init: initialize DirectX video thread output method ***************************************************************************** * This function create the directx surfaces needed by the output thread. * It is called at the beginning of the thread. *****************************************************************************/static int Init( vout_thread_t *p_vout ){    int i_chroma_backup;    vlc_value_t val;    /* Get a few default parameters */    var_Get( p_vout, "overlay", &val );    p_vout->p_sys->b_using_overlay = val.b_bool;    var_Get( p_vout, "directx-use-sysmem", &val );    p_vout->p_sys->b_use_sysmem = val.b_bool;    var_Get( p_vout, "directx-hw-yuv", &val );    p_vout->p_sys->b_hw_yuv = val.b_bool;    var_Get( p_vout, "directx-3buffering", &val );    p_vout->p_sys->b_3buf_overlay = val.b_bool;    /* Initialise DirectDraw if not already done.     * We do this here because on multi-monitor systems we may have to     * re-create the directdraw surfaces. */    if( !p_vout->p_sys->p_ddobject &&        DirectXInitDDraw( p_vout ) != VLC_SUCCESS )    {

⌨️ 快捷键说明

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