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

📄 directx.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                                  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 (%lix%li,%lix%li)",             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 );    /* use black brush as the video background color,       if overlay video is used, this will be replaced by the       colorkey when the first picture is received */    SetClassLong( p_vout->p_sys->hvideownd, GCL_HBRBACKGROUND,                  (LONG)GetStockObject( BLACK_BRUSH ) );    InvalidateRect( p_vout->p_sys->hvideownd, NULL, TRUE );    E_(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 )        {            *pp_surface_final = NULL;            return VLC_EGENERIC;        }    }    if( !b_overlay )    {        vlc_bool_t 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( E_(DirectXUpdateOverlay)( 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;}/***************************************************************************** * DirectXUpdateOverlay: 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 E_(DirectXUpdateOverlay)( 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;

⌨️ 快捷键说明

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