📄 directx.c
字号:
{ 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 ){ HRESULT dxresult; if( (p_vout->p_sys->p_display == NULL) ) { msg_Warn( p_vout, "no display!" ); return; } /* Our surface can be lost so be sure to check this * and restore it if need be */ if( IDirectDrawSurface2_IsLost( p_vout->p_sys->p_display ) == DDERR_SURFACELOST ) { if( IDirectDrawSurface2_Restore( p_vout->p_sys->p_display ) == DD_OK && p_vout->p_sys->b_using_overlay ) DirectDrawUpdateOverlay( p_vout ); } if( !p_vout->p_sys->b_using_overlay ) { DDBLTFX ddbltfx; /* We ask for the "NOTEARING" option */ memset( &ddbltfx, 0, sizeof(DDBLTFX) ); ddbltfx.dwSize = sizeof(DDBLTFX); ddbltfx.dwDDFX = DDBLTFX_NOTEARING; /* Blit video surface to display */ dxresult = IDirectDrawSurface2_Blt( p_vout->p_sys->p_display, &p_vout->p_sys->rect_dest_clipped, p_pic->p_sys->p_surface, &p_vout->p_sys->rect_src_clipped, DDBLT_ASYNC, &ddbltfx ); if( dxresult != DD_OK ) { msg_Warn( p_vout, "could not blit surface (error %li)", dxresult ); return; } } else /* using overlay */ { /* Flip the overlay buffers if we are using back buffers */ if( p_pic->p_sys->p_front_surface == p_pic->p_sys->p_surface ) { return; } dxresult = IDirectDrawSurface2_Flip( p_pic->p_sys->p_front_surface, NULL, DDFLIP_WAIT ); if( dxresult != DD_OK ) { msg_Warn( p_vout, "could not flip overlay (error %li)", dxresult ); } /* set currently displayed pic */ p_vout->p_sys->p_current_surface = p_pic->p_sys->p_front_surface; /* Lock surface to get all the required info */ if( DirectXLockSurface( p_vout, p_pic ) ) { /* AAARRGG */ msg_Warn( p_vout, "cannot lock surface" ); return; } DirectXUnlockSurface( p_vout, p_pic ); }}/*** this function is only used once when the first picture is received** this function will show the video window once video is ready for** display.*/static void FirstDisplay( vout_thread_t *p_vout, picture_t *p_pic ){ /* get initial picture rendered on overlay surface */ Display(p_vout, p_pic); IDirectDraw_WaitForVerticalBlank(p_vout->p_sys->p_ddobject, DDWAITVB_BLOCKBEGIN, NULL); if( p_vout->p_sys->b_using_overlay ) { /* set the colorkey as the backgound brush for the video window */ SetClassLong( p_vout->p_sys->hvideownd, GCL_HBRBACKGROUND, (LONG)CreateSolidBrush( p_vout->p_sys->i_rgb_colorkey ) ); } /* ** Video window is initially hidden, show it now since we got a ** picture to show. */ SetWindowPos( p_vout->p_sys->hvideownd, NULL, 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;}/* following functions are local *//***************************************************************************** * DirectXEnumCallback: Device enumeration ***************************************************************************** * This callback function is called by DirectDraw once for each * available DirectDraw device. *****************************************************************************/BOOL WINAPI DirectXEnumCallback( GUID* p_guid, LPTSTR psz_desc, LPTSTR psz_drivername, VOID* p_context, HMONITOR hmon ){ vout_thread_t *p_vout = (vout_thread_t *)p_context; vlc_value_t device; msg_Dbg( p_vout, "DirectXEnumCallback: %s, %s", psz_desc, psz_drivername ); if( hmon ) { var_Get( p_vout, "directx-device", &device ); if( ( !device.psz_string || !*device.psz_string ) && hmon == p_vout->p_sys->hmonitor ) { free( device.psz_string ); } else if( strcmp( psz_drivername, device.psz_string ) == 0 ) { MONITORINFO monitor_info; monitor_info.cbSize = sizeof( MONITORINFO ); if( p_vout->p_sys->GetMonitorInfo( hmon, &monitor_info ) ) { RECT rect; /* Move window to the right screen */ GetWindowRect( p_vout->p_sys->hwnd, &rect ); if( !IntersectRect( &rect, &rect, &monitor_info.rcWork ) ) { rect.left = monitor_info.rcWork.left; rect.top = monitor_info.rcWork.top; msg_Dbg( p_vout, "DirectXEnumCallback: setting window " "position to %ld,%ld", rect.left, rect.top ); SetWindowPos( p_vout->p_sys->hwnd, NULL, rect.left, rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); } } p_vout->p_sys->hmonitor = hmon; free( device.psz_string ); } else { free( device.psz_string ); return TRUE; /* Keep enumerating */ } msg_Dbg( p_vout, "selecting %s, %s", psz_desc, psz_drivername ); p_vout->p_sys->p_display_driver = malloc( sizeof(GUID) ); if( p_vout->p_sys->p_display_driver ) memcpy( p_vout->p_sys->p_display_driver, p_guid, sizeof(GUID) ); } return TRUE; /* Keep enumerating */}/***************************************************************************** * DirectXInitDDraw: Takes care of all the DirectDraw initialisations ***************************************************************************** * This function initialise and allocate resources for DirectDraw. *****************************************************************************/static int DirectXInitDDraw( vout_thread_t *p_vout ){ HRESULT dxresult; HRESULT (WINAPI *OurDirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *); HRESULT (WINAPI *OurDirectDrawEnumerateEx)( LPDDENUMCALLBACKEXA, LPVOID, DWORD ); LPDIRECTDRAW p_ddobject; msg_Dbg( p_vout, "DirectXInitDDraw" ); /* Load direct draw DLL */ p_vout->p_sys->hddraw_dll = LoadLibrary(_T("DDRAW.DLL")); if( p_vout->p_sys->hddraw_dll == NULL ) { msg_Warn( p_vout, "DirectXInitDDraw failed loading ddraw.dll" ); goto error; } OurDirectDrawCreate = (void *)GetProcAddress( p_vout->p_sys->hddraw_dll, _T("DirectDrawCreate") ); if( OurDirectDrawCreate == NULL ) { msg_Err( p_vout, "DirectXInitDDraw failed GetProcAddress" ); goto error; } OurDirectDrawEnumerateEx = (void *)GetProcAddress( p_vout->p_sys->hddraw_dll,#ifndef UNICODE "DirectDrawEnumerateExA" );#else _T("DirectDrawEnumerateExW") );#endif if( OurDirectDrawEnumerateEx && p_vout->p_sys->MonitorFromWindow ) { vlc_value_t device; var_Get( p_vout, "directx-device", &device ); if( device.psz_string ) { msg_Dbg( p_vout, "directx-device: %s", device.psz_string ); free( device.psz_string ); } p_vout->p_sys->hmonitor = p_vout->p_sys->MonitorFromWindow( p_vout->p_sys->hwnd, MONITOR_DEFAULTTONEAREST ); /* Enumerate displays */ OurDirectDrawEnumerateEx( DirectXEnumCallback, p_vout, 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" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -