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

📄 directx.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
                                 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_visible_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 );            }            DirectDrawUpdateOverlay( 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;            bool b_result = 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 = 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 = 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,                                                &ddpfPixelFormat );            if( ddpfPixelFormat.dwFlags & DDPF_RGB )            {                switch( ddpfPixelFormat.dwRGBBitCount )                {                case 8:                    p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2');                    p_vout->output.pf_setpalette = SetPalette;                    break;                case 15:                    p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5');                    break;                case 16:                    p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6');                    break;                case 24:                    p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4');                    break;                case 32:                    p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2');                    break;                default:                    msg_Err( p_vout, "unknown screen depth" );                    return VLC_EGENERIC;                }                p_vout->output.i_rmask = ddpfPixelFormat.dwRBitMask;                p_vout->output.i_gmask = ddpfPixelFormat.dwGBitMask;                p_vout->output.i_bmask = ddpfPixelFormat.dwBBitMask;            }            p_vout->p_sys->b_hw_yuv = 0;            i_ret = DirectXCreateSurface( p_vout, &p_surface,                                          p_vout->output.i_chroma,                                          0 /* no overlay */,                                          0 /* no back buffers */ );            if( i_ret && !p_vout->p_sys->b_use_sysmem )            {                /* Give it a last try with b_use_sysmem enabled */                p_vout->p_sys->b_use_sysmem = 1;                i_ret = DirectXCreateSurface( p_vout, &p_surface,                                              p_vout->output.i_chroma,                                              0 /* no overlay */,                                              0 /* no back buffers */ );            }        }        if( i_ret == VLC_SUCCESS )        {            /* 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;            }            p_pic[0].p_sys->p_surface = p_pic[0].p_sys->p_front_surface                = p_surface;            I_OUTPUTPICTURES = 1;            msg_Dbg( p_vout, "created plain surface of chroma:%.4s",                     (char *)&p_vout->output.i_chroma );        }    }    /* Now that we've got all our direct-buffers, we can finish filling in the     * picture_t structures */    for( i = 0; i < I_OUTPUTPICTURES; i++ )    {        p_pic[i].i_status = DESTROYED_PICTURE;        p_pic[i].i_type   = DIRECT_PICTURE;        p_pic[i].b_slow   = true;        p_pic[i].pf_lock  = DirectXLockSurface;        p_pic[i].pf_unlock = DirectXUnlockSurface;        PP_OUTPUTPICTURE[i] = &p_pic[i];        if( DirectXLockSurface( p_vout, &p_pic[i] ) != VLC_SUCCESS )        {            /* AAARRGG */            FreePictureVec( p_vout, p_pic, I_OUTPUTPICTURES );            I_OUTPUTPICTURES = 0;            msg_Err( p_vout, "cannot lock surface" );            return VLC_EGENERIC;        }        DirectXUnlockSurface( p_vout, &p_pic[i] );    }    msg_Dbg( p_vout, "End NewPictureVec (%s)",             I_OUTPUTPICTURES ? "succeeded" : "failed" );    return VLC_SUCCESS;}/***************************************************************************** * FreePicture: destroy a picture vector allocated with NewPictureVec ***************************************************************************** * *****************************************************************************/static void FreePictureVec( vout_thread_t *p_vout, picture_t *p_pic,                            int i_num_pics ){    int i;    vlc_mutex_lock( &p_vout->p_sys->lock );    p_vout->p_sys->p_current_surface = 0;    vlc_mutex_unlock( &p_vout->p_sys->lock );    for( i = 0; i < i_num_pics; i++ )    {        DirectXCloseSurface( p_vout, p_pic[i].p_sys->p_front_surface );        for( i = 0; i < i_num_pics; i++ )        {            free( p_pic[i].p_sys );        }    }}/***************************************************************************** * UpdatePictureStruct: updates the internal data in the picture_t structure ***************************************************************************** * This will setup stuff for use by the video_output thread *****************************************************************************/static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,                                int i_chroma ){    switch( p_vout->output.i_chroma )    {        case VLC_FOURCC('R','G','B','2'):        case VLC_FOURCC('R','V','1','5'):        case VLC_FOURCC('R','V','1','6'):        case VLC_FOURCC('R','V','2','4'):        case VLC_FOURCC('R','V','3','2'):            p_pic->p->p_pixels = p_pic->p_sys->ddsd.lpSurface;            p_pic->p->i_lines = p_vout->output.i_height;            p_pic->p->i_visible_lines = p_vout->output.i_height;            p_pic->p->i_pitch = p_pic->p_sys->ddsd.lPitch;            switch( p_vout->output.i_chroma )            {                case VLC_FOURCC('R','G','B','2'):                    p_pic->p->i_pixel_pitch = 1;                    break;                case VLC_FOURCC('R','V','1','5'):                case VLC_FOURCC('R','V','1','6'):                    p_pic->p->i_pixel_pitch = 2;                    break;                case VLC_FOURCC('R','V','2','4'):                    p_pic->p->i_pixel_pitch = 3;                    break;                case VLC_FOURCC('R','V','3','2'):                    p_pic->p->i_pixel_pitch = 4;                    break;                default:                    return VLC_EGENERIC;            }            p_pic->p->i_visible_pitch = p_vout->output.i_width *              p_pic->p->i_pixel_pitch;            p_pic->i_planes = 1;            break;        case VLC_FOURCC('Y','V','1','2'):        case VLC_FOURCC('I','4','2','0'):            /* U and V inverted compared to I420             * Fixme: this should be handled by the vout core */            p_vout->output.i_chroma = VLC_FOURCC('I','4','2','0');            p_pic->Y_PIXELS = p_pic->p_sys->ddsd.lpSurface;            p_pic->p[Y_PLANE].i_lines = p_vout->output.i_height;            p_pic->p[Y_PLANE].i_visible_lines = p_vout->output.i_height;            p_pic->p[Y_PLANE].i_pitch = p_pic->p_sys->ddsd.lPitch;            p_pic->p[Y_PLANE].i_pixel_pitch = 1;            p_pic->p[Y_PLANE].i_visible_pitch = p_vout->output.i_width *              p_pic->p[Y_PLANE].i_pixel_pitch;            p_pic->V_PIXELS =  p_pic->Y_PIXELS              + p_pic->p[Y_PLANE].i_lines * p_pic->p[Y_PLANE].i_pitch;            p_pic->p[V_PLANE].i_lines = p_vout->output

⌨️ 快捷键说明

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