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

📄 directx.c

📁 VLC媒体播放程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * vout.c: Windows DirectX video output display method ***************************************************************************** * Copyright (C) 2001-2004 VideoLAN * $Id: directx.c,v 1.36 2004/02/26 13:58:23 gbazin Exp $ * * Authors: Gildas Bazin <gbazin@netcourrier.com> * * 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 <multimon.h>#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 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 );/* Object variables callbacks */static int OnTopCallback( vlc_object_t *, char const *,                          vlc_value_t, vlc_value_t, void * );static int FindDevicesCallback( 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 bufferring 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 multimonitor 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\"." )static char *ppsz_dev[] = { "" };static char *ppsz_dev_text[] = { N_("Default") };vlc_module_begin();    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") );    set_description( _("DirectX video output") );    set_capability( "video output", 100 );    add_shortcut( "directx" );    set_callbacks( OpenVideo, CloseVideo );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, text;    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;    }    /* 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 = NULL;    p_vout->p_sys->i_changes = 0;    SetRectEmpty( &p_vout->p_sys->rect_display  );    /* 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( "USER32" ) ) )    {        p_vout->p_sys->MonitorFromWindow =            GetProcAddress( huser32, "MonitorFromWindow" );        p_vout->p_sys->GetMonitorInfo =            GetProcAddress( huser32, "GetMonitorInfoA" );    }    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 );    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",                           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;    }    /* Add a variable to indicate if the window should be on top of others */    var_Create( p_vout, "video-on-top", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );    text.psz_string = _("Always on top");    var_Change( p_vout, "video-on-top", VLC_VAR_SETTEXT, &text, NULL );    var_Get( p_vout, "video-on-top", &val );    p_vout->p_sys->b_on_top_change = val.b_bool;    var_AddCallback( p_vout, "video-on-top", OnTopCallback, NULL );    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 )    {        msg_Err( p_vout, "cannot initialize DirectDraw" );        return VLC_EGENERIC;    }    /* Create the directx display */    if( !p_vout->p_sys->p_display &&        DirectXCreateDisplay( p_vout ) != VLC_SUCCESS )    {        msg_Err( p_vout, "cannot initialize DirectDraw" );        return VLC_EGENERIC;    }    /* Initialize the output structure.     * Since DirectDraw can do rescaling for us, stick to the default     * coordinates and aspect. */    p_vout->output.i_width  = p_vout->render.i_width;    p_vout->output.i_height = p_vout->render.i_height;    p_vout->output.i_aspect = p_vout->render.i_aspect;#define MAX_DIRECTBUFFERS 1    /* Right now we use only 1 directbuffer because we don't want the     * video decoder to decode directly into direct buffers as they are     * created into video memory and video memory is _really_ slow */    /* Choose the chroma we will try first. */    switch( p_vout->render.i_chroma )    {        case VLC_FOURCC('Y','U','Y','2'):        case VLC_FOURCC('Y','U','N','V'):            p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');            break;

⌨️ 快捷键说明

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