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

📄 directx.c

📁 VLC媒体播放程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        {            *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( 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 DirectXUpdateOverlay( vout_thread_t *p_vout ){    DDOVERLAYFX     ddofx;    DWORD           dwFlags;    HRESULT         dxresult;    if( p_vout->p_sys->p_current_surface == NULL ||        !p_vout->p_sys->b_using_overlay )        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,                                         &p_vout->p_sys->rect_src_clipped,                                         p_vout->p_sys->p_display,                                         &p_vout->p_sys->rect_dest_clipped,                                         dwFlags, &ddofx );    if(dxresult != DD_OK)    {        msg_Warn( p_vout,                  "DirectXUpdateOverlay cannot move or 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;    }    if( p_vout->p_sys->p_display_driver != 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,                                 LPDIRECTDRAWSURFACE2 p_surface ){    msg_Dbg( p_vout, "DirectXCloseSurface" );    if( p_surface != NULL )    {        IDirectDrawSurface2_Release( p_surface );    }}/***************************************************************************** * NewPictureVec: allocate a vector of identical pictures ***************************************************************************** * Returns 0 on success, -1 otherwise *****************************************************************************/static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,                          int i_num_pics ){    int i;    int i_ret = VLC_SUCCESS;    LPDIRECTDRAWSURFACE2 p_surface;    msg_Dbg( p_vout, "NewPictureVec overlay:%s chroma:%.4s",             p_vout->p_sys->b_using_overlay ? "yes" : "no",             (char *)&p_vout->output.i_chroma );    I_OUTPUTPICTURES = 0;    /* First we try to use an YUV overlay surface.     * The overlay surface that we create won't be used to decode directly     * into it because accessing video memory directly is way to slow (remember     * that pictures are decoded macroblock per macroblock). Instead the video     * will be decoded in picture buffers in system memory which will then be     * memcpy() to the overlay surface. */    if( p_vout->p_sys->b_using_overlay )    {        /* Triple buffering rocks! it doesn't have any processing overhead         * (you don't have to wait for the vsync) and provides for a very nice         * video quality (no tearing). */        if( p_vout->p_sys->b_3buf_overlay )            i_ret = DirectXCreateSurface( p_vout, &p_surface,                                          p_vout->output.i_chroma,                                          p_vout->p_sys->b_using_overlay,                                          2 /* number of backbuffers */ );        if( !p_vout->p_sys->b_3buf_overlay || i_ret != VLC_SUCCESS )        {            /* Try to reduce the number of backbuffers */            i_ret = DirectXCreateSurface( p_vout, &p_surface,                                          p_vout->output.i_chroma,                                          p_vout->p_sys->b_using_overlay,                                          0 /* number of backbuffers */ );        }        if( i_ret == VLC_SUCCESS )        {            DDSCAPS dds_caps;            picture_t front_pic;            picture_sys_t front_pic_sys;            front_pic.p_sys = &front_pic_sys;            /* Allocate internal structure */            p_pic[0].p_sys = malloc( sizeof( picture_sys_t ) );            if( p_pic[0].p_sys == NULL )            {                DirectXCloseSurface( p_vout, p_surface );                return VLC_ENOMEM;            }            /* set front buffer */            p_pic[0].p_sys->p_front_surface = p_surface;            /* Get the back buffer */            memset( &dds_caps, 0, sizeof( DDSCAPS ) );            dds_caps.dwCaps = DDSCAPS_BACKBUFFER;            if( DD_OK != IDirectDrawSurface2_GetAttachedSurface(                                                p_surface, &dds_caps,                                                &p_pic[0].p_sys->p_surface ) )            {                msg_Warn( p_vout, "NewPictureVec could not get back buffer" );                /* front buffer is the same as back buffer */                p_pic[0].p_sys->p_surface = p_surface;            }            p_vout->p_sys->p_current_surface = front_pic.p_sys->p_surface =                p_pic[0].p_sys->p_front_surface;            /* Reset the front buffer memory */            if( DirectXLockSurface( p_vout, &front_pic ) == VLC_SUCCESS )            {                int i,j;                for( i = 0; i < front_pic.i_planes; i++ )                    for( j = 0; j < front_pic.p[i].i_lines; j++)                        memset( front_pic.p[i].p_pixels + j *                                front_pic.p[i].i_pitch, 127,                                front_pic.p[i].i_visible_pitch );                DirectXUnlockSurface( p_vout, &front_pic );            }            DirectXUpdateOverlay( p_vout );            I_OUTPUTPICTURES = 1;            msg_Dbg( p_vout, "YUV overlay created successfully" );        }    }    /* As we can't have an overlay, we'll try to create a plain offscreen     * surface. This surface will reside in video memory because there's a     * better chance then that we'll be able to use some kind of hardware     * acceleration like rescaling, blitting or YUV->RGB conversions.     * We then only need to blit this surface onto the main display when we     * want to display it */    if( !p_vout->p_sys->b_using_overlay )    {        if( p_vout->p_sys->b_hw_yuv )        {            DWORD i_codes;            DWORD *pi_codes;            vlc_bool_t b_result = VLC_FALSE;            /* Check if the chroma is supported first. This is required             * because a few buggy drivers don't mind creating the surface             * even if they don't know about the chroma. */            if( IDirectDraw2_GetFourCCCodes( p_vout->p_sys->p_ddobject,                                             &i_codes, NULL ) == DD_OK )            {                pi_codes = malloc( i_codes * sizeof(DWORD) );                if( pi_codes && IDirectDraw2_GetFourCCCodes(                    p_vout->p_sys->p_ddobject, &i_codes, pi_codes ) == DD_OK )                {                    for( i = 0; i < (int)i_codes; i++ )                    {                        if( p_vout->output.i_chroma == pi_codes[i] )                        {                            b_result = VLC_TRUE;                            break;                        }                    }                }            }            if( b_result )                i_ret = DirectXCreateSurface( p_vout, &p_surface,                                              p_vout->output.i_chroma,                                              0 /* no overlay */,                                              0 /* no back buffers */ );            else                p_vout->p_sys->b_hw_yuv = VLC_FALSE;        }        if( i_ret || !p_vout->p_sys->b_hw_yuv )        {            /* Our last choice is to use a plain RGB surface */            DDPIXELFORMAT ddpfPixelFormat;            ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);            IDirectDrawSurface2_GetPixelFormat( p_vout->p_sys->p_display,

⌨️ 快捷键说明

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