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

📄 directx.c

📁 VLC媒体播放程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    if( hmon )    {        var_Get( p_vout, "directx-device", &device );        if( ( !device.psz_string || !*device.psz_string ) &&            hmon == p_vout->p_sys->hmonitor )        {            if( device.psz_string ) free( device.psz_string );        }        else if( strcmp( psz_drivername, device.psz_string ) == 0 )        {            MONITORINFO monitor_info;            monitor_info.cbSize = sizeof( MONITORINFO );            if( p_vout->p_sys->GetMonitorInfo( hmon, &monitor_info ) )            {                RECT rect;                /* Move window to the right screen */                GetWindowRect( p_vout->p_sys->hwnd, &rect );                if( !IntersectRect( &rect, &rect, &monitor_info.rcWork ) )                {                    rect.left = monitor_info.rcWork.left;                    rect.top = monitor_info.rcWork.top;                    msg_Dbg( p_vout, "DirectXEnumCallback: Setting window "                             "position to %d,%d", rect.left, rect.top );                    SetWindowPos( p_vout->p_sys->hwnd, NULL,                                  rect.left, rect.top, 0, 0,                                  SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );                }            }            p_vout->p_sys->hmonitor = hmon;            if( device.psz_string ) free( device.psz_string );        }        else        {            if( device.psz_string ) free( device.psz_string );            return TRUE; /* Keep enumerating */        }        msg_Dbg( p_vout, "selecting %s, %s", psz_desc, psz_drivername );        p_vout->p_sys->p_display_driver = malloc( sizeof(GUID) );        if( p_vout->p_sys->p_display_driver )            memcpy( p_vout->p_sys->p_display_driver, p_guid, sizeof(GUID) );    }    return TRUE; /* Keep enumerating */}/***************************************************************************** * DirectXInitDDraw: Takes care of all the DirectDraw initialisations ***************************************************************************** * This function initialise and allocate resources for DirectDraw. *****************************************************************************/static int DirectXInitDDraw( vout_thread_t *p_vout ){    HRESULT dxresult;    HRESULT (WINAPI *OurDirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *);    HRESULT (WINAPI *OurDirectDrawEnumerateEx)( LPDDENUMCALLBACKEXA, LPVOID,                                                DWORD );    LPDIRECTDRAW p_ddobject;    msg_Dbg( p_vout, "DirectXInitDDraw" );    /* Load direct draw DLL */    p_vout->p_sys->hddraw_dll = LoadLibrary("DDRAW.DLL");    if( p_vout->p_sys->hddraw_dll == NULL )    {        msg_Warn( p_vout, "DirectXInitDDraw failed loading ddraw.dll" );        goto error;    }    OurDirectDrawCreate =      (void *)GetProcAddress(p_vout->p_sys->hddraw_dll, "DirectDrawCreate");    if( OurDirectDrawCreate == NULL )    {        msg_Err( p_vout, "DirectXInitDDraw failed GetProcAddress" );        goto error;    }    OurDirectDrawEnumerateEx =      (void *)GetProcAddress( p_vout->p_sys->hddraw_dll,                              "DirectDrawEnumerateExA" );    if( OurDirectDrawEnumerateEx && p_vout->p_sys->MonitorFromWindow )    {        vlc_value_t device;        var_Get( p_vout, "directx-device", &device );        if( device.psz_string )        {            msg_Dbg( p_vout, "directx-device: %s", device.psz_string );            free( device.psz_string );        }        p_vout->p_sys->hmonitor =            p_vout->p_sys->MonitorFromWindow( p_vout->p_sys->hwnd,                                              MONITOR_DEFAULTTONEAREST );        /* Enumerate displays */        OurDirectDrawEnumerateEx( DirectXEnumCallback, p_vout,                                  DDENUM_ATTACHEDSECONDARYDEVICES );    }    /* Initialize DirectDraw now */    dxresult = OurDirectDrawCreate( p_vout->p_sys->p_display_driver,                                    &p_ddobject, NULL );    if( dxresult != DD_OK )    {        msg_Err( p_vout, "DirectXInitDDraw cannot initialize DDraw" );        goto error;    }    /* Get the IDirectDraw2 interface */    dxresult = IDirectDraw_QueryInterface( p_ddobject, &IID_IDirectDraw2,                                        (LPVOID *)&p_vout->p_sys->p_ddobject );    /* Release the unused interface */    IDirectDraw_Release( p_ddobject );    if( dxresult != DD_OK )    {        msg_Err( p_vout, "cannot get IDirectDraw2 interface" );        goto error;    }    /* Set DirectDraw Cooperative level, ie what control we want over Windows     * display */    dxresult = IDirectDraw2_SetCooperativeLevel( p_vout->p_sys->p_ddobject,                                                 NULL, DDSCL_NORMAL );    if( dxresult != DD_OK )    {        msg_Err( p_vout, "cannot set direct draw cooperative level" );        goto error;    }    /* Get the size of the current display device */    if( p_vout->p_sys->hmonitor && p_vout->p_sys->GetMonitorInfo )    {        MONITORINFO monitor_info;        monitor_info.cbSize = sizeof( MONITORINFO );        p_vout->p_sys->GetMonitorInfo( p_vout->p_sys->hmonitor,                                       &monitor_info );        p_vout->p_sys->rect_display = monitor_info.rcMonitor;    }    else    {        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);    }    msg_Dbg( p_vout, "screen dimensions (%ix%i,%ix%i)",             p_vout->p_sys->rect_display.left,             p_vout->p_sys->rect_display.top,             p_vout->p_sys->rect_display.right,             p_vout->p_sys->rect_display.bottom );    /* Probe the capabilities of the hardware */    DirectXGetDDrawCaps( p_vout );    msg_Dbg( p_vout, "End DirectXInitDDraw" );    return VLC_SUCCESS; error:    if( p_vout->p_sys->p_ddobject )        IDirectDraw2_Release( p_vout->p_sys->p_ddobject );    if( p_vout->p_sys->hddraw_dll )        FreeLibrary( p_vout->p_sys->hddraw_dll );    p_vout->p_sys->hddraw_dll = NULL;    p_vout->p_sys->p_ddobject = NULL;    return VLC_EGENERIC;}/***************************************************************************** * DirectXCreateDisplay: create the DirectDraw display. ***************************************************************************** * Create and initialize display according to preferences specified in the vout * thread fields. *****************************************************************************/static int DirectXCreateDisplay( vout_thread_t *p_vout ){    HRESULT              dxresult;    DDSURFACEDESC        ddsd;    LPDIRECTDRAWSURFACE  p_display;    msg_Dbg( p_vout, "DirectXCreateDisplay" );    /* Now get the primary surface. This surface is what you actually see     * on your screen */    memset( &ddsd, 0, sizeof( DDSURFACEDESC ));    ddsd.dwSize = sizeof(DDSURFACEDESC);    ddsd.dwFlags = DDSD_CAPS;    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;    dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,                                           &ddsd, &p_display, NULL );    if( dxresult != DD_OK )    {        msg_Err( p_vout, "cannot get primary surface (error %li)", dxresult );        return VLC_EGENERIC;    }    dxresult = IDirectDrawSurface_QueryInterface( p_display,                                         &IID_IDirectDrawSurface2,                                         (LPVOID *)&p_vout->p_sys->p_display );    /* Release the old interface */    IDirectDrawSurface_Release( p_display );    if ( dxresult != DD_OK )    {        msg_Err( p_vout, "cannot query IDirectDrawSurface2 interface "                         "(error %li)", dxresult );        return VLC_EGENERIC;    }    /* The clipper will be used only in non-overlay mode */    DirectXCreateClipper( p_vout );    /* Make sure the colorkey will be painted */    p_vout->p_sys->i_colorkey = 1;    p_vout->p_sys->i_rgb_colorkey =        DirectXFindColorkey( p_vout, p_vout->p_sys->i_colorkey );    /* Create the actual brush */    SetClassLong( p_vout->p_sys->hvideownd, GCL_HBRBACKGROUND,                  (LONG)CreateSolidBrush( p_vout->p_sys->i_rgb_colorkey ) );    InvalidateRect( p_vout->p_sys->hvideownd, NULL, TRUE );    DirectXUpdateRects( p_vout, VLC_TRUE );    return VLC_SUCCESS;}/***************************************************************************** * DirectXCreateClipper: Create a clipper that will be used when blitting the *                       RGB surface to the main display. ***************************************************************************** * This clipper prevents us to modify by mistake anything on the screen * which doesn't belong to our window. For example when a part of our video * window is hidden by another window. *****************************************************************************/static int DirectXCreateClipper( vout_thread_t *p_vout ){    HRESULT dxresult;    msg_Dbg( p_vout, "DirectXCreateClipper" );    /* Create the clipper */    dxresult = IDirectDraw2_CreateClipper( p_vout->p_sys->p_ddobject, 0,                                           &p_vout->p_sys->p_clipper, NULL );    if( dxresult != DD_OK )    {        msg_Warn( p_vout, "cannot create clipper (error %li)", dxresult );        goto error;    }    /* Associate the clipper to the window */    dxresult = IDirectDrawClipper_SetHWnd( p_vout->p_sys->p_clipper, 0,                                           p_vout->p_sys->hvideownd );    if( dxresult != DD_OK )    {        msg_Warn( p_vout, "cannot attach clipper to window (error %li)",                          dxresult );        goto error;    }    /* associate the clipper with the surface */    dxresult = IDirectDrawSurface_SetClipper(p_vout->p_sys->p_display,                                             p_vout->p_sys->p_clipper);    if( dxresult != DD_OK )    {        msg_Warn( p_vout, "cannot attach clipper to surface (error %li)",                          dxresult );        goto error;    }    return VLC_SUCCESS; error:    if( p_vout->p_sys->p_clipper )    {        IDirectDrawClipper_Release( p_vout->p_sys->p_clipper );    }    p_vout->p_sys->p_clipper = NULL;    return VLC_EGENERIC;}/***************************************************************************** * DirectXCreateSurface: create an YUV overlay or RGB surface for the video. ***************************************************************************** * The best method of display is with an YUV overlay because the YUV->RGB * conversion is done in hardware. * You can also create a plain RGB surface. * ( Maybe we could also try an RGB overlay surface, which could have hardware * scaling and which would also be faster in window mode because you don't * need to do any blitting to the main display...) *****************************************************************************/static int DirectXCreateSurface( vout_thread_t *p_vout,                                 LPDIRECTDRAWSURFACE2 *pp_surface_final,                                 int i_chroma, int b_overlay,                                 int i_backbuffers ){    HRESULT dxresult;    LPDIRECTDRAWSURFACE p_surface;    DDSURFACEDESC ddsd;    /* Create the video surface */    if( b_overlay )    {        /* Now try to create the YUV overlay surface.         * This overlay will be displayed on top of the primary surface.         * A color key is used to determine whether or not the overlay will be         * displayed, ie the overlay will be displayed in place of the primary         * surface wherever the primary surface will have this color.         * The video window has been created with a background of this color so         * the overlay will be only displayed on top of this window */        memset( &ddsd, 0, sizeof( DDSURFACEDESC ));        ddsd.dwSize = sizeof(DDSURFACEDESC);        ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);        ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;        ddsd.ddpfPixelFormat.dwFourCC = i_chroma;        ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;        ddsd.dwFlags |= (i_backbuffers ? DDSD_BACKBUFFERCOUNT : 0);        ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;        ddsd.ddsCaps.dwCaps |= (i_backbuffers ? DDSCAPS_COMPLEX | DDSCAPS_FLIP                                : 0 );        ddsd.dwHeight = p_vout->render.i_height;        ddsd.dwWidth = p_vout->render.i_width;        ddsd.dwBackBufferCount = i_backbuffers;        dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,                                               &ddsd, &p_surface, NULL );        if( dxresult != DD_OK )

⌨️ 快捷键说明

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