📄 directx.c
字号:
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 = VLC_FALSE; } /* Check if the event thread is still running */ if( p_vout->p_sys->p_event->b_die ) { 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 ) E_(DirectXUpdateOverlay)( 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 ); }}/* 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 ) { if( device.psz_string ) 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 %d,%d", 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; if( device.psz_string ) free( device.psz_string ); } else { if( device.psz_string ) 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 (%ix%i,%ix%i)", 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" ); /* Now get the primary surface. This surface is what you actually see * on your screen */ memset( &ddsd, 0, sizeof( DDSURFACEDESC )); ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject, &ddsd, &p_display, NULL ); if( dxresult != DD_OK ) { msg_Err( p_vout, "cannot get primary surface (error %li)", dxresult ); return VLC_EGENERIC; } dxresult = IDirectDrawSurface_QueryInterface( p_display, &IID_IDirectDrawSurface2, (LPVOID *)&p_vout->p_sys->p_display ); /* Release the old interface */ IDirectDrawSurface_Release( p_display ); if ( dxresult != DD_OK ) { msg_Err( p_vout, "cannot query IDirectDrawSurface2 interface " "(error %li)", dxresult ); return VLC_EGENERIC; } /* The clipper will be used only in non-overlay mode */ DirectXCreateClipper( p_vout );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -