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

📄 direct3d.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
    Direct3DVoutClose( p_vout );}/***************************************************************************** * Manage: handle Sys events ***************************************************************************** * This function should be called regularly by the video output thread. * It returns a non null value if an error occurred. *****************************************************************************/static int Manage( vout_thread_t *p_vout ){    /* If we do not control our window, we check for geometry changes     * ourselves because the parent might not send us its events. */    vlc_mutex_lock( &p_vout->p_sys->lock );    if( p_vout->p_sys->hparent && !p_vout->b_fullscreen )    {        RECT rect_parent;        POINT point;        vlc_mutex_unlock( &p_vout->p_sys->lock );        GetClientRect( p_vout->p_sys->hparent, &rect_parent );        point.x = point.y = 0;        ClientToScreen( p_vout->p_sys->hparent, &point );        OffsetRect( &rect_parent, point.x, point.y );        if( !EqualRect( &rect_parent, &p_vout->p_sys->rect_parent ) )        {            p_vout->p_sys->rect_parent = rect_parent;            SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,                          rect_parent.right - rect_parent.left,                          rect_parent.bottom - rect_parent.top,                          SWP_NOZORDER );        }    }    else    {        vlc_mutex_unlock( &p_vout->p_sys->lock );    }    /*     * Position Change     */    if( p_vout->p_sys->i_changes & DX_POSITION_CHANGE )    {#if 0 /* need that when bicubic filter is available */        RECT rect;        UINT width, height;        GetClientRect(p_vout->p_sys->hvideownd, &rect);        width  = rect.right-rect.left;        height = rect.bottom-rect.top;        if( (width != p_vout->p_sys->d3dpp.BackBufferWidth)         || (height != p_vout->p_sys->d3dpp.BackBufferHeight) )        {            msg_Dbg(p_vout, "resizing device back buffers to (%lux%lu)", width, height);            // need to reset D3D device to resize back buffer            if( VLC_SUCCESS != Direct3DVoutResetDevice(p_vout, width, height) )                return VLC_EGENERIC;        }#endif        p_vout->p_sys->i_changes &= ~DX_POSITION_CHANGE;    }    /* Check for cropping / aspect changes */    if( p_vout->i_changes & VOUT_CROP_CHANGE ||        p_vout->i_changes & VOUT_ASPECT_CHANGE )    {        p_vout->i_changes &= ~VOUT_CROP_CHANGE;        p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;        p_vout->fmt_out.i_x_offset = p_vout->fmt_in.i_x_offset;        p_vout->fmt_out.i_y_offset = p_vout->fmt_in.i_y_offset;        p_vout->fmt_out.i_visible_width = p_vout->fmt_in.i_visible_width;        p_vout->fmt_out.i_visible_height = p_vout->fmt_in.i_visible_height;        p_vout->fmt_out.i_aspect = p_vout->fmt_in.i_aspect;        p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;        p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;        p_vout->output.i_aspect = p_vout->fmt_in.i_aspect;        UpdateRects( p_vout, true );    }    /* We used to call the Win32 PeekMessage function here to read the window     * messages. But since window can stay blocked into this function for a     * long time (for example when you move your window on the screen), I     * decided to isolate PeekMessage in another thread. */    /*     * Fullscreen change     */    if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE        || p_vout->p_sys->i_changes & VOUT_FULLSCREEN_CHANGE )    {        Win32ToggleFullscreen( p_vout );        p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;        p_vout->p_sys->i_changes &= ~VOUT_FULLSCREEN_CHANGE;    }    /*     * Pointer change     */    if( p_vout->b_fullscreen && !p_vout->p_sys->b_cursor_hidden &&        (mdate() - p_vout->p_sys->i_lastmoved) >            p_vout->p_sys->i_mouse_hide_timeout )    {        POINT point;        HWND hwnd;        /* Hide the cursor only if it is inside our window */        GetCursorPos( &point );        hwnd = WindowFromPoint(point);        if( hwnd == p_vout->p_sys->hwnd || hwnd == p_vout->p_sys->hvideownd )        {            PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );        }        else        {            p_vout->p_sys->i_lastmoved = mdate();        }    }    /*     * "Always on top" status change     */    if( p_vout->p_sys->b_on_top_change )    {        vlc_value_t val;        HMENU hMenu = GetSystemMenu( p_vout->p_sys->hwnd, FALSE );        var_Get( p_vout, "video-on-top", &val );        /* Set the window on top if necessary */        if( val.b_bool && !( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )                           & WS_EX_TOPMOST ) )        {            CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,                           MF_BYCOMMAND | MFS_CHECKED );            SetWindowPos( p_vout->p_sys->hwnd, HWND_TOPMOST, 0, 0, 0, 0,                          SWP_NOSIZE | SWP_NOMOVE );        }        else        /* The window shouldn't be on top */        if( !val.b_bool && ( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )                           & WS_EX_TOPMOST ) )        {            CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,                           MF_BYCOMMAND | MFS_UNCHECKED );            SetWindowPos( p_vout->p_sys->hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,                          SWP_NOSIZE | SWP_NOMOVE );        }        p_vout->p_sys->b_on_top_change = false;    }    /* Check if the event thread is still running */    if( !vlc_object_alive (p_vout->p_sys->p_event) )    {        return VLC_EGENERIC; /* exit */    }    return VLC_SUCCESS;}/***************************************************************************** * Display: displays previously rendered output ***************************************************************************** * This function sends the currently rendered image to the display, wait until * it is displayed and switch the two rendering buffers, preparing next frame. *****************************************************************************/static void Display( vout_thread_t *p_vout, picture_t *p_pic ){    LPDIRECT3DDEVICE9       p_d3ddev = p_vout->p_sys->p_d3ddev;    // Present the back buffer contents to the display    // stretching and filtering happens here    HRESULT hr = IDirect3DDevice9_Present(p_d3ddev,                    &(p_vout->p_sys->rect_src_clipped),                    NULL, NULL, NULL);    if( FAILED(hr) )        msg_Dbg( p_vout, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);}/*** this function is only used once when the first picture is received** this function will show the video window once a picture is ready*/static void FirstDisplay( vout_thread_t *p_vout, picture_t *p_pic ){    /* get initial picture presented through D3D */    Display(p_vout, p_pic);    /*    ** Video window is initially hidden, show it now since we got a    ** picture to show.    */    SetWindowPos( p_vout->p_sys->hvideownd, 0, 0, 0, 0, 0,        SWP_ASYNCWINDOWPOS|        SWP_FRAMECHANGED|        SWP_SHOWWINDOW|        SWP_NOMOVE|        SWP_NOSIZE|        SWP_NOZORDER );    /* use and restores proper display function for further pictures */    p_vout->pf_display = Display;}/***************************************************************************** * DirectD3DVoutCreate: Initialize and instance of Direct3D9 ***************************************************************************** * This function initialize Direct3D and analyze available resources from * default adapter. *****************************************************************************/static int Direct3DVoutCreate( vout_thread_t *p_vout ){    HRESULT hr;    LPDIRECT3D9 p_d3dobj;    D3DCAPS9 d3dCaps;    LPDIRECT3D9 (WINAPI *OurDirect3DCreate9)(UINT SDKVersion);    p_vout->p_sys->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL"));    if( NULL == p_vout->p_sys->hd3d9_dll )    {        msg_Warn( p_vout, "cannot load d3d9.dll, aborting" );        return VLC_EGENERIC;    }    OurDirect3DCreate9 =      (void *)GetProcAddress( p_vout->p_sys->hd3d9_dll,                              TEXT("Direct3DCreate9") );    if( OurDirect3DCreate9 == NULL )    {        msg_Err( p_vout, "Cannot locate reference to Direct3DCreate9 ABI in DLL" );        return VLC_EGENERIC;    }    /* Create the D3D object. */    p_d3dobj = OurDirect3DCreate9( D3D_SDK_VERSION );    if( NULL == p_d3dobj )    {       msg_Err( p_vout, "Could not create Direct3D9 instance.");       return VLC_EGENERIC;    }    p_vout->p_sys->p_d3dobj = p_d3dobj;    /*    ** Get device capabilities    */    ZeroMemory(&d3dCaps, sizeof(d3dCaps));    hr = IDirect3D9_GetDeviceCaps(p_d3dobj, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps);    if( FAILED(hr) )    {       msg_Err( p_vout, "Could not read adapter capabilities. (hr=0x%lX)", hr);       return VLC_EGENERIC;    }    /* TODO: need to test device capabilities and select the right render function */    return VLC_SUCCESS;}/***************************************************************************** * DirectD3DVoutRelease: release an instance of Direct3D9 *****************************************************************************/static void Direct3DVoutRelease( vout_thread_t *p_vout ){    if( p_vout->p_sys->p_d3dobj )    {       IDirect3D9_Release(p_vout->p_sys->p_d3dobj);       p_vout->p_sys->p_d3dobj = NULL;    }    if( NULL != p_vout->p_sys->hd3d9_dll )    {        FreeLibrary(p_vout->p_sys->hd3d9_dll);        p_vout->p_sys->hd3d9_dll = NULL;    }}static int Direct3DFillPresentationParameters(vout_thread_t *p_vout, D3DPRESENT_PARAMETERS *d3dpp){    LPDIRECT3D9 p_d3dobj = p_vout->p_sys->p_d3dobj;    D3DDISPLAYMODE d3ddm;    HRESULT hr;    /*    ** Get the current desktop display mode, so we can set up a back    ** buffer of the same format    */    hr = IDirect3D9_GetAdapterDisplayMode(p_d3dobj, D3DADAPTER_DEFAULT, &d3ddm );    if( FAILED(hr))    {       msg_Err( p_vout, "Could not read adapter display mode. (hr=0x%lX)", hr);       return VLC_EGENERIC;    }    /* keep a copy of current desktop format */    p_vout->p_sys->bbFormat = d3ddm.Format;    /* Set up the structure used to create the D3DDevice. */    ZeroMemory( d3dpp, sizeof(D3DPRESENT_PARAMETERS) );    d3dpp->Flags                  = D3DPRESENTFLAG_VIDEO;    d3dpp->Windowed               = TRUE;    d3dpp->hDeviceWindow          = p_vout->p_sys->hvideownd;    d3dpp->BackBufferWidth        = p_vout->output.i_width;    d3dpp->BackBufferHeight       = p_vout->output.i_height;    d3dpp->SwapEffect             = D3DSWAPEFFECT_COPY;    d3dpp->MultiSampleType        = D3DMULTISAMPLE_NONE;    d3dpp->PresentationInterval   = D3DPRESENT_INTERVAL_DEFAULT;    d3dpp->BackBufferFormat       = d3ddm.Format;    d3dpp->BackBufferCount        = 1;    d3dpp->EnableAutoDepthStencil = FALSE;    return VLC_SUCCESS;}/***************************************************************************** * DirectD3DVoutOpen: Takes care of all the Direct3D9 initialisations ***************************************************************************** * This function creates Direct3D device * this must be called from the vout thread for performance reason, as * all Direct3D Device APIs are used in a non multithread safe environment *****************************************************************************/static int Direct3DVoutOpen( vout_thread_t *p_vout ){    LPDIRECT3D9 p_d3dobj = p_vout->p_sys->p_d3dobj;    LPDIRECT3DDEVICE9 p_d3ddev;    D3DPRESENT_PARAMETERS d3dpp;    HRESULT hr;    if( VLC_SUCCESS != Direct3DFillPresentationParameters(p_vout, &d3dpp) )        return VLC_EGENERIC;    // Create the D3DDevice    hr = IDirect3D9_CreateDevice(p_d3dobj, D3DADAPTER_DEFAULT,                                 D3DDEVTYPE_HAL, p_vout->p_sys->hvideownd,                                 D3DCREATE_SOFTWARE_VERTEXPROCESSING|                                 D3DCREATE_MULTITHREADED,                                 &d3dpp, &p_d3ddev );    if( FAILED(hr) )    {       msg_Err(p_vout, "Could not create the D3D device! (hr=0x%lX)", hr);       return VLC_EGENERIC;    }    p_vout->p_sys->p_d3ddev = p_d3ddev;    msg_Dbg( p_vout, "Direct3D device adapter successfully initialized" );    return VLC_SUCCESS;}/***************************************************************************** * DirectD3DClose: release the Direct3D9 device *****************************************************************************/static void Direct3DVoutClose( vout_thread_t *p_vout ){    if( p_vout->p_sys->p_d3ddev )    {       IDirect3DDevice9_Release(p_vout->p_sys->p_d3ddev);       p_vout->p_sys->p_d3ddev = NULL;    }     p_vout->p_sys->hmonitor = NULL;}/***************************************************************************** * DirectD3DClose: reset the Direct3D9 device ***************************************************************************** * All resources must be deallocated before the reset occur, they will be * realllocated once the reset has been performed successfully

⌨️ 快捷键说明

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