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

📄 directx.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* 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 );    UpdateRects( p_vout, 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 )        {            *pp_surface_final = NULL;            return VLC_EGENERIC;        }    }    if( !b_overlay )    {        bool b_rgb_surface =            ( i_chroma == VLC_FOURCC('R','G','B','2') )          || ( i_chroma == VLC_FOURCC('R','V','1','5') )           || ( i_chroma == VLC_FOURCC('R','V','1','6') )            || ( i_chroma == VLC_FOURCC('R','V','2','4') )             || ( i_chroma == VLC_FOURCC('R','V','3','2') );        memset( &ddsd, 0, sizeof( DDSURFACEDESC ) );        ddsd.dwSize = sizeof(DDSURFACEDESC);        ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);        ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS;        ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;        ddsd.dwHeight = p_vout->render.i_height;        ddsd.dwWidth = p_vout->render.i_width;        if( p_vout->p_sys->b_use_sysmem )            ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;        else            ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;        if( !b_rgb_surface )        {            ddsd.dwFlags |= DDSD_PIXELFORMAT;            ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;            ddsd.ddpfPixelFormat.dwFourCC = i_chroma;        }        dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,                                               &ddsd, &p_surface, NULL );        if( dxresult != DD_OK )        {            *pp_surface_final = NULL;            return VLC_EGENERIC;        }    }    /* Now that the surface is created, try to get a newer DirectX interface */    dxresult = IDirectDrawSurface_QueryInterface( p_surface,                                     &IID_IDirectDrawSurface2,                                     (LPVOID *)pp_surface_final );    IDirectDrawSurface_Release( p_surface );    /* Release the old interface */    if ( dxresult != DD_OK )    {        msg_Err( p_vout, "cannot query IDirectDrawSurface2 interface "                         "(error %li)", dxresult );        *pp_surface_final = NULL;        return VLC_EGENERIC;    }    if( b_overlay )    {        /* Check the overlay is useable as some graphics cards allow creating         * several overlays but only one can be used at one time. */        p_vout->p_sys->p_current_surface = *pp_surface_final;        if( DirectDrawUpdateOverlay( p_vout ) != VLC_SUCCESS )        {            IDirectDrawSurface2_Release( *pp_surface_final );            *pp_surface_final = NULL;            msg_Err( p_vout, "overlay unuseable (might already be in use)" );            return VLC_EGENERIC;        }    }    return VLC_SUCCESS;}/***************************************************************************** * DirectDrawUpdateOverlay: Move or resize overlay surface on video display. ***************************************************************************** * This function is used to move or resize an overlay surface on the screen. * Ususally the overlay is moved by the user and thus, by a move or resize * event (in Manage). *****************************************************************************/int DirectDrawUpdateOverlay( vout_thread_t *p_vout ){    DDOVERLAYFX     ddofx;    DWORD           dwFlags;    HRESULT         dxresult;    RECT            rect_src = p_vout->p_sys->rect_src_clipped;    RECT            rect_dest = p_vout->p_sys->rect_dest_clipped;    if( !p_vout->p_sys->b_using_overlay ) return VLC_EGENERIC;    if( p_vout->p_sys->b_wallpaper )    {        int i_x, i_y, i_width, i_height;        rect_src.left = p_vout->fmt_out.i_x_offset;        rect_src.top = p_vout->fmt_out.i_y_offset;        rect_src.right = rect_src.left + p_vout->fmt_out.i_visible_width;        rect_src.bottom = rect_src.top + p_vout->fmt_out.i_visible_height;        rect_dest = p_vout->p_sys->rect_display;        vout_PlacePicture( p_vout, rect_dest.right, rect_dest.bottom,                           &i_x, &i_y, &i_width, &i_height );        rect_dest.left += i_x;        rect_dest.right = rect_dest.left + i_width;        rect_dest.top += i_y;        rect_dest.bottom = rect_dest.top + i_height;    }    vlc_mutex_lock( &p_vout->p_sys->lock );    if( p_vout->p_sys->p_current_surface == NULL )    {        vlc_mutex_unlock( &p_vout->p_sys->lock );        return VLC_EGENERIC;    }    /* The new window dimensions should already have been computed by the     * caller of this function */    /* Position and show the overlay */    memset(&ddofx, 0, sizeof(DDOVERLAYFX));    ddofx.dwSize = sizeof(DDOVERLAYFX);    ddofx.dckDestColorkey.dwColorSpaceLowValue = p_vout->p_sys->i_colorkey;    ddofx.dckDestColorkey.dwColorSpaceHighValue = p_vout->p_sys->i_colorkey;    dwFlags = DDOVER_SHOW | DDOVER_KEYDESTOVERRIDE;    dxresult = IDirectDrawSurface2_UpdateOverlay(                   p_vout->p_sys->p_current_surface,                   &rect_src, p_vout->p_sys->p_display, &rect_dest,                   dwFlags, &ddofx );    vlc_mutex_unlock( &p_vout->p_sys->lock );    if(dxresult != DD_OK)    {        msg_Warn( p_vout, "DirectDrawUpdateOverlay cannot move/resize overlay" );        return VLC_EGENERIC;    }    return VLC_SUCCESS;}/***************************************************************************** * DirectXCloseDDraw: Release the DDraw object allocated by DirectXInitDDraw ***************************************************************************** * This function returns all resources allocated by DirectXInitDDraw. *****************************************************************************/static void DirectXCloseDDraw( vout_thread_t *p_vout ){    msg_Dbg( p_vout, "DirectXCloseDDraw" );    if( p_vout->p_sys->p_ddobject != NULL )    {        IDirectDraw2_Release(p_vout->p_sys->p_ddobject);        p_vout->p_sys->p_ddobject = NULL;    }    if( p_vout->p_sys->hddraw_dll != NULL )    {        FreeLibrary( p_vout->p_sys->hddraw_dll );        p_vout->p_sys->hddraw_dll = NULL;    }    free( p_vout->p_sys->p_display_driver );    p_vout->p_sys->p_display_driver = NULL;    p_vout->p_sys->hmonitor = NULL;}/***************************************************************************** * DirectXCloseDisplay: close and reset the DirectX display device ***************************************************************************** * This function returns all resources allocated by DirectXCreateDisplay. *****************************************************************************/static void DirectXCloseDisplay( vout_thread_t *p_vout ){    msg_Dbg( p_vout, "DirectXCloseDisplay" );    if( p_vout->p_sys->p_clipper != NULL )    {        msg_Dbg( p_vout, "DirectXCloseDisplay clipper" );        IDirectDrawClipper_Release( p_vout->p_sys->p_clipper );        p_vout->p_sys->p_clipper = NULL;    }    if( p_vout->p_sys->p_display != NULL )    {        msg_Dbg( p_vout, "DirectXCloseDisplay display" );        IDirectDrawSurface2_Release( p_vout->p_sys->p_display );        p_vout->p_sys->p_display = NULL;    }}/***************************************************************************** * DirectXCloseSurface: close the YUV overlay or RGB surface. ***************************************************************************** * This function returns all resources allocated for the surface. *****************************************************************************/static void DirectXCloseSurface( vout_thread_t *p_vout,

⌨️ 快捷键说明

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