📄 directx.c
字号:
&ddpfPixelFormat ); if( ddpfPixelFormat.dwFlags & DDPF_RGB ) { switch( ddpfPixelFormat.dwRGBBitCount ) { case 8: /* FIXME: set the palette */ p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2'); 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].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; 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 ); } } p_vout->p_sys->p_current_surface = 0;}/***************************************************************************** * 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_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'): 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_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.i_height / 2; p_pic->p[V_PLANE].i_pitch = p_pic->p[Y_PLANE].i_pitch / 2; p_pic->p[V_PLANE].i_pixel_pitch = 1; p_pic->p[V_PLANE].i_visible_pitch = p_vout->output.i_width / 2 * p_pic->p[V_PLANE].i_pixel_pitch; p_pic->U_PIXELS = p_pic->V_PIXELS + p_pic->p[V_PLANE].i_lines * p_pic->p[V_PLANE].i_pitch; p_pic->p[U_PLANE].i_lines = p_vout->output.i_height / 2; p_pic->p[U_PLANE].i_pitch = p_pic->p[Y_PLANE].i_pitch / 2; p_pic->p[U_PLANE].i_pixel_pitch = 1; p_pic->p[U_PLANE].i_visible_pitch = p_vout->output.i_width / 2 * p_pic->p[U_PLANE].i_pixel_pitch; p_pic->i_planes = 3; break; case VLC_FOURCC('I','Y','U','V'): 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_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->U_PIXELS = p_pic->Y_PIXELS + p_pic->p[Y_PLANE].i_lines * p_pic->p[Y_PLANE].i_pitch; p_pic->p[U_PLANE].i_lines = p_vout->output.i_height / 2; p_pic->p[U_PLANE].i_pitch = p_pic->p[Y_PLANE].i_pitch / 2; p_pic->p[U_PLANE].i_pixel_pitch = 1; p_pic->p[U_PLANE].i_visible_pitch = p_vout->output.i_width / 2 * p_pic->p[U_PLANE].i_pixel_pitch; p_pic->V_PIXELS = p_pic->U_PIXELS + p_pic->p[U_PLANE].i_lines * p_pic->p[U_PLANE].i_pitch; p_pic->p[V_PLANE].i_lines = p_vout->output.i_height / 2; p_pic->p[V_PLANE].i_pitch = p_pic->p[Y_PLANE].i_pitch / 2; p_pic->p[V_PLANE].i_pixel_pitch = 1; p_pic->p[V_PLANE].i_visible_pitch = p_vout->output.i_width / 2 * p_pic->p[V_PLANE].i_pixel_pitch; p_pic->i_planes = 3; break; case VLC_FOURCC('Y','U','Y','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_pitch = p_pic->p_sys->ddsd.lPitch; 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: /* Unknown chroma, tell the guy to get lost */ msg_Err( p_vout, "never heard of chroma 0x%.8x (%4.4s)", p_vout->output.i_chroma, (char*)&p_vout->output.i_chroma ); return VLC_EGENERIC; } return VLC_SUCCESS;}/***************************************************************************** * DirectXGetDDrawCaps: Probe the capabilities of the hardware ***************************************************************************** * It is nice to know which features are supported by the hardware so we can * find ways to optimize our rendering. *****************************************************************************/static void DirectXGetDDrawCaps( vout_thread_t *p_vout ){ DDCAPS ddcaps; HRESULT dxresult; /* This is just an indication of whether or not we'll support overlay, * but with this test we don't know if we support YUV overlay */ memset( &ddcaps, 0, sizeof( DDCAPS )); ddcaps.dwSize = sizeof(DDCAPS); dxresult = IDirectDraw2_GetCaps( p_vout->p_sys->p_ddobject, &ddcaps, NULL ); if(dxresult != DD_OK ) { msg_Warn( p_vout, "cannot get caps" ); } else { BOOL bHasOverlay, bHasOverlayFourCC, bCanDeinterlace, bHasColorKey, bCanStretch, bCanBltFourcc; /* Determine if the hardware supports overlay surfaces */ bHasOverlay = ((ddcaps.dwCaps & DDCAPS_OVERLAY) == DDCAPS_OVERLAY) ? TRUE : FALSE; /* Determine if the hardware supports overlay surfaces */ bHasOverlayFourCC = ((ddcaps.dwCaps & DDCAPS_OVERLAYFOURCC) == DDCAPS_OVERLAYFOURCC) ? TRUE : FALSE; /* Determine if the hardware supports overlay deinterlacing */ bCanDeinterlace = ((ddcaps.dwCaps & DDCAPS2_CANFLIPODDEVEN) == 0 ) ? TRUE : FALSE; /* Determine if the hardware supports colorkeying */ bHasColorKey = ((ddcaps.dwCaps & DDCAPS_COLORKEY) == DDCAPS_COLORKEY) ? TRUE : FALSE; /* Determine if the hardware supports scaling of the overlay surface */ bCanStretch = ((ddcaps.dwCaps & DDCAPS_OVERLAYSTRETCH) == DDCAPS_OVERLAYSTRETCH) ? TRUE : FALSE; /* Determine if the hardware supports color conversion during a blit */ bCanBltFourcc = ((ddcaps.dwCaps & DDCAPS_BLTFOURCC ) == DDCAPS_BLTFOURCC) ? TRUE : FALSE; msg_Dbg( p_vout, "DirectDraw Capabilities: overlay=%i yuvoverlay=%i " "can_deinterlace_overlay=%i colorkey=%i stretch=%i " "bltfourcc=%i", bHasOverlay, bHasOverlayFourCC, bCanDeinterlace, bHasColorKey, bCanStretch, bCanBltFourcc ); /* Don't ask for troubles */ if( !bCanBltFourcc ) p_vout->p_sys->b_hw_yuv = FALSE; }}/***************************************************************************** * DirectXLockSurface: Lock surface and get picture data pointer ***************************************************************************** * This function locks a surface and get the surface descriptor which amongst * other things has the pointer to the picture data. *****************************************************************************/static int DirectXLockSurface( vout_thread_t *p_vout, picture_t *p_pic ){ HRESULT dxresult; /* Lock the surface to get a valid pointer to the picture buffer */ memset( &p_pic->p_sys->ddsd, 0, sizeof( DDSURFACEDESC )); p_pic->p_sys->ddsd.dwSize = sizeof(DDSURFACEDESC); dxresult = IDirectDrawSurface2_Lock( p_pic->p_sys->p_surface, NULL, &p_pic->p_sys->ddsd, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL ); if( dxresult != DD_OK ) { if( dxresult == DDERR_INVALIDPARAMS ) { /* DirectX 3 doesn't support the DDLOCK_NOSYSLOCK flag, resulting * in an invalid params error */ dxresult = IDirectDrawSurface2_Lock( p_pic->p_sys->p_surface, NULL, &p_pic->p_sys->ddsd, DDLOCK_WAIT, NULL); } if( dxresult == DDERR_SURFACELOST ) { /* Your surface can be lost so be sure * to check this and restore it if needed */ /* When using overlays with back-buffers, we need to restore * the front buffer so the back-buffers get restored as well. */ if( p_vout->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -