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

📄 direct3d.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
 *****************************************************************************/static int Direct3DVoutResetDevice( vout_thread_t *p_vout ){    LPDIRECT3DDEVICE9       p_d3ddev = p_vout->p_sys->p_d3ddev;    D3DPRESENT_PARAMETERS   d3dpp;    HRESULT hr;    if( VLC_SUCCESS != Direct3DFillPresentationParameters(p_vout, &d3dpp) )        return VLC_EGENERIC;    // release all D3D objects    Direct3DVoutReleaseScene( p_vout );    Direct3DVoutReleasePictures( p_vout );    hr = IDirect3DDevice9_Reset(p_d3ddev, &d3dpp);    if( SUCCEEDED(hr) )    {        // re-create them        if( (VLC_SUCCESS != Direct3DVoutCreatePictures(p_vout, 1))         || (VLC_SUCCESS != Direct3DVoutCreateScene(p_vout)) )        {            msg_Dbg(p_vout, "%s failed !", __FUNCTION__);            return VLC_EGENERIC;        }    }    else {        msg_Err(p_vout, "%s failed ! (hr=%08lX)", __FUNCTION__, hr);        return VLC_EGENERIC;    }    return VLC_SUCCESS;}static D3DFORMAT Direct3DVoutSelectFormat( vout_thread_t *p_vout, D3DFORMAT target,    const D3DFORMAT *formats, size_t count){    LPDIRECT3D9 p_d3dobj = p_vout->p_sys->p_d3dobj;    size_t c;    for( c=0; c<count; ++c )    {        HRESULT hr;        D3DFORMAT format = formats[c];        /* test whether device can create a surface of that format */        hr = IDirect3D9_CheckDeviceFormat(p_d3dobj, D3DADAPTER_DEFAULT,                D3DDEVTYPE_HAL, target, 0, D3DRTYPE_SURFACE, format);        if( SUCCEEDED(hr) )        {            /* test whether device can perform color-conversion            ** from that format to target format            */            hr = IDirect3D9_CheckDeviceFormatConversion(p_d3dobj,                    D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,                    format, target);        }        if( SUCCEEDED(hr) )        {            // found a compatible format            switch( format )            {                case D3DFMT_UYVY:                    msg_Dbg( p_vout, "selected surface pixel format is UYVY");                    break;                case D3DFMT_YUY2:                    msg_Dbg( p_vout, "selected surface pixel format is YUY2");                    break;                case D3DFMT_X8R8G8B8:                    msg_Dbg( p_vout, "selected surface pixel format is X8R8G8B8");                    break;                case D3DFMT_A8R8G8B8:                    msg_Dbg( p_vout, "selected surface pixel format is A8R8G8B8");                    break;                case D3DFMT_R8G8B8:                    msg_Dbg( p_vout, "selected surface pixel format is R8G8B8");                    break;                case D3DFMT_R5G6B5:                    msg_Dbg( p_vout, "selected surface pixel format is R5G6B5");                    break;                case D3DFMT_X1R5G5B5:                    msg_Dbg( p_vout, "selected surface pixel format is X1R5G5B5");                    break;                default:                    msg_Dbg( p_vout, "selected surface pixel format is 0x%0X", format);                    break;            }            return format;        }        else if( D3DERR_NOTAVAILABLE != hr )        {            msg_Err( p_vout, "Could not query adapter supported formats. (hr=0x%lX)", hr);            break;        }    }    return D3DFMT_UNKNOWN;}static D3DFORMAT Direct3DVoutFindFormat(vout_thread_t *p_vout, int i_chroma, D3DFORMAT target){    //if( p_vout->p_sys->b_hw_yuv && ! _got_vista_or_above )    if( p_vout->p_sys->b_hw_yuv )    {    /* it sounds like vista does not support YUV surfaces at all */        switch( i_chroma )        {            case VLC_FOURCC('U','Y','V','Y'):            case VLC_FOURCC('U','Y','N','V'):            case VLC_FOURCC('Y','4','2','2'):            {                static const D3DFORMAT formats[] =                    { D3DFMT_UYVY, D3DFMT_YUY2, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };                return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));            }            case VLC_FOURCC('I','4','2','0'):            case VLC_FOURCC('I','4','2','2'):            case VLC_FOURCC('Y','V','1','2'):            {                /* typically 3D textures don't support planar format                ** fallback to packed version and use CPU for the conversion                */                static const D3DFORMAT formats[] =                    { D3DFMT_YUY2, D3DFMT_UYVY, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };                return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));            }            case VLC_FOURCC('Y','U','Y','2'):            case VLC_FOURCC('Y','U','N','V'):            {                static const D3DFORMAT formats[] =                    { D3DFMT_YUY2, D3DFMT_UYVY, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };                return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));            }        }    }    switch( i_chroma )    {        case VLC_FOURCC('R', 'V', '1', '5'):        {            static const D3DFORMAT formats[] =                { D3DFMT_X1R5G5B5 };            return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));        }        case VLC_FOURCC('R', 'V', '1', '6'):        {            static const D3DFORMAT formats[] =                { D3DFMT_R5G6B5 };            return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));        }        case VLC_FOURCC('R', 'V', '2', '4'):        {            static const D3DFORMAT formats[] =                { D3DFMT_R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8 };            return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));        }        case VLC_FOURCC('R', 'V', '3', '2'):        {            static const D3DFORMAT formats[] =                { D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8 };            return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));        }        default:        {            /* use display default format */            LPDIRECT3D9 p_d3dobj = p_vout->p_sys->p_d3dobj;            D3DDISPLAYMODE d3ddm;            HRESULT hr = IDirect3D9_GetAdapterDisplayMode(p_d3dobj, D3DADAPTER_DEFAULT, &d3ddm );            if( SUCCEEDED(hr))            {                /*                ** some professional cards could use some advanced pixel format as default,                ** make sure we stick with chromas that we can handle internally                */                switch( d3ddm.Format )                {                    case D3DFMT_R8G8B8:                    case D3DFMT_X8R8G8B8:                    case D3DFMT_A8R8G8B8:                    case D3DFMT_R5G6B5:                    case D3DFMT_X1R5G5B5:                        msg_Dbg( p_vout, "defaulting to adapter pixel format");                        return Direct3DVoutSelectFormat(p_vout, target, &d3ddm.Format, 1);                    default:                    {                        /* if we fall here, that probably means that we need to render some YUV format */                        static const D3DFORMAT formats[] =                            { D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };                        msg_Dbg( p_vout, "defaulting to built-in pixel format");                        return Direct3DVoutSelectFormat(p_vout, target, formats, sizeof(formats)/sizeof(D3DFORMAT));                    }                }            }        }    }    return D3DFMT_UNKNOWN;}static int Direct3DVoutSetOutputFormat(vout_thread_t *p_vout, D3DFORMAT format){    switch( format )    {        case D3DFMT_YUY2:            p_vout->output.i_chroma = VLC_FOURCC('Y', 'U', 'Y', '2');            break;        case D3DFMT_UYVY:            p_vout->output.i_chroma = VLC_FOURCC('U', 'Y', 'V', 'Y');            break;        case D3DFMT_R8G8B8:            p_vout->output.i_chroma = VLC_FOURCC('R', 'V', '2', '4');            p_vout->output.i_rmask = 0xff0000;            p_vout->output.i_gmask = 0x00ff00;            p_vout->output.i_bmask = 0x0000ff;            break;        case D3DFMT_X8R8G8B8:        case D3DFMT_A8R8G8B8:            p_vout->output.i_chroma = VLC_FOURCC('R', 'V', '3', '2');            p_vout->output.i_rmask = 0x00ff0000;            p_vout->output.i_gmask = 0x0000ff00;            p_vout->output.i_bmask = 0x000000ff;            break;        case D3DFMT_R5G6B5:            p_vout->output.i_chroma = VLC_FOURCC('R', 'V', '1', '6');            p_vout->output.i_rmask = (0x1fL)<<11;            p_vout->output.i_gmask = (0x3fL)<<5;            p_vout->output.i_bmask = (0x1fL)<<0;            break;        case D3DFMT_X1R5G5B5:            p_vout->output.i_chroma = VLC_FOURCC('R', 'V', '1', '5');            p_vout->output.i_rmask = (0x1fL)<<10;            p_vout->output.i_gmask = (0x1fL)<<5;            p_vout->output.i_bmask = (0x1fL)<<0;            break;        default:            return VLC_EGENERIC;    }    return VLC_SUCCESS;}/***************************************************************************** * Direct3DVoutCreatePictures: allocate a vector of identical pictures ***************************************************************************** * Each picture has an associated offscreen surface in video memory * depending on hardware capabilities the picture chroma will be as close * as possible to the orginal render chroma to reduce CPU conversion overhead * and delegate this work to video card GPU *****************************************************************************/static int Direct3DVoutCreatePictures( vout_thread_t *p_vout, size_t i_num_pics ){    LPDIRECT3DDEVICE9       p_d3ddev  = p_vout->p_sys->p_d3ddev;    D3DFORMAT               format;    HRESULT hr;    size_t c;    // if vout is already running, use current chroma, otherwise choose from upstream    int i_chroma = p_vout->output.i_chroma ? : p_vout->render.i_chroma;    I_OUTPUTPICTURES = 0;    /*    ** find the appropriate D3DFORMAT for the render chroma, the format will be the closest to    ** the requested chroma which is usable by the hardware in an offscreen surface, as they    ** typically support more formats than textures    */    format = Direct3DVoutFindFormat(p_vout, i_chroma, p_vout->p_sys->bbFormat);    if( VLC_SUCCESS != Direct3DVoutSetOutputFormat(p_vout, format) )    {        msg_Err(p_vout, "surface pixel format is not supported.");        return VLC_EGENERIC;    }    for( c=0; c<i_num_pics; )    {        LPDIRECT3DSURFACE9 p_d3dsurf;        picture_t *p_pic = p_vout->p_picture+c;        hr = IDirect3DDevice9_CreateOffscreenPlainSurface(p_d3ddev,                p_vout->render.i_width,                p_vout->render.i_height,                format,                D3DPOOL_DEFAULT,                &p_d3dsurf,                NULL);        if( FAILED(hr) )        {            msg_Err(p_vout, "Failed to create picture surface. (hr=0x%lx)", hr);            Direct3DVoutReleasePictures(p_vout);            return VLC_EGENERIC;        }        /* fill surface with black color */        IDirect3DDevice9_ColorFill(p_d3ddev, p_d3dsurf, NULL, D3DCOLOR_ARGB(0xFF, 0, 0, 0) );         /* assign surface to internal structure */        p_pic->p_sys = (void *)p_d3dsurf;        /* Now that we've got our direct-buffer, we can finish filling in the         * picture_t structures */        switch( p_vout->output.i_chroma )        {            case VLC_FOURCC('R','G','B','2'):                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_pixel_pitch = 1;                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('R','V','1','5'):            case VLC_FOURCC('R','V','1','6'):                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_pixel_pitch = 2;                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('R','V','2','4'):                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_pixel_pitch = 3;                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('R','V','3','2'):                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_pixel_pitch = 4;                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('U','Y','V','Y'):            case VLC_FOURCC('Y','U','Y','2'):                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_pixel_pitch = 2;                p_pic->p->i_visible_pitch = p_vout->output.i_width *                    p_pic->p->i_pixel_pitch;                p_pic->i_planes = 1;                break;            default:                Direct3DVoutReleasePictures(p_vout);                return VLC_EGENERIC;        }        p_pic->i_status = DESTROYED_PICTURE;        p_pic->i_type   = DIRECT_PICTURE;        p_pic->b_slow   = true;        p_pic->pf_lock  = Direct3DVoutLockSurface;        p_pic->pf_unlock = Direct3DVoutUnlockSurface;        PP_OUTPUTPICTURE[c] = p_pic;        I_OUTPUTPICTURES = ++c;    }    msg_Dbg( p_vout, "%u Direct3D pictures created successfully", c );    return VLC_SUCCESS;}/***************************************************************************** * Direct3DVoutReleasePictures: destroy a picture vector ***************************************************************************** * release all video resources used for pictures *****************************************************************************/static void Direct3DVoutReleasePictures( vout_thread_t *p_vout){    size_t i_num_pics = I_OUTPUTPICTURES;    size_t c;    for( c=0; c<i_num_pics; ++c )    {        picture_t *p_pic = p_vout->p_picture+c;        if( p_pic->p_sys )        {

⌨️ 快捷键说明

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