📄 video_out_dx.c
字号:
static int dxrgb_setup (vo_instance_t * _instance, unsigned int width, unsigned int height, unsigned int chroma_width, unsigned int chroma_height, vo_setup_result_t * result){ dx_instance_t * instance = (dx_instance_t *) _instance; HDC hdc; int bpp; if (common_setup (instance, width, height)) return 1; hdc = GetDC (NULL); bpp = GetDeviceCaps (hdc, BITSPIXEL); ReleaseDC (NULL, hdc); result->convert = mpeg2convert_rgb (MPEG2CONVERT_RGB, bpp); return 0;}static LPDIRECTDRAWSURFACE2 alloc_frame (dx_instance_t * instance){ DDSURFACEDESC ddsd; LPDIRECTDRAWSURFACE2 surface; memset (&ddsd, 0, sizeof (DDSURFACEDESC)); ddsd.dwSize = sizeof (DDSURFACEDESC); ddsd.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT); ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS; ddsd.dwHeight = instance->height; ddsd.dwWidth = instance->width; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; surface = alloc_surface (instance, &ddsd); if (surface == NULL) fprintf (stderr, "Can not create directDraw frame surface\n"); return surface;}static void * surface_addr (LPDIRECTDRAWSURFACE2 surface, int * stride){ DDSURFACEDESC ddsd; memset (&ddsd, 0, sizeof (DDSURFACEDESC)); ddsd.dwSize = sizeof (DDSURFACEDESC); IDirectDrawSurface2_Lock (surface, NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); IDirectDrawSurface2_Unlock (surface, NULL); *stride = ddsd.lPitch; return ddsd.lpSurface;}static void dx_setup_fbuf (vo_instance_t * _instance, uint8_t ** buf, void ** id){ dx_instance_t * instance = (dx_instance_t *) _instance; int stride; *id = instance->frame[instance->index++] = alloc_frame (instance); buf[0] = surface_addr (*id, &stride); buf[1] = NULL; buf[2] = NULL;}static void dxrgb_draw_frame (vo_instance_t * _instance, uint8_t * const * buf, void * id){ dx_instance_t * instance = (dx_instance_t *) _instance; LPDIRECTDRAWSURFACE2 surface = (LPDIRECTDRAWSURFACE2) id; DDBLTFX ddbltfx; check_events (instance); memset (&ddbltfx, 0, sizeof (DDBLTFX)); ddbltfx.dwSize = sizeof (DDBLTFX); ddbltfx.dwDDFX = DDBLTFX_NOTEARING; if (DDERR_SURFACELOST == IDirectDrawSurface2_Blt (instance->display, &instance->window_coords, surface, NULL, DDBLT_WAIT, &ddbltfx)) { /* restore surface and try again */ IDirectDrawSurface2_Restore (instance->display); IDirectDrawSurface2_Blt (instance->display, &instance->window_coords, surface, NULL, DDBLT_WAIT, &ddbltfx); }}static vo_instance_t * common_open (int setup (vo_instance_t *, unsigned int, unsigned int, unsigned int, unsigned int, vo_setup_result_t *), void setup_fbuf (vo_instance_t *, uint8_t **, void **), void draw (vo_instance_t *, uint8_t * const *, void * id)){ dx_instance_t * instance; instance = malloc (sizeof (dx_instance_t)); if (instance == NULL) return NULL; memset (instance, 0, sizeof (dx_instance_t)); instance->vo.setup = setup; instance->vo.setup_fbuf = setup_fbuf; instance->vo.set_fbuf = NULL; instance->vo.start_fbuf = NULL; instance->vo.draw = draw; instance->vo.discard = NULL; instance->vo.close = NULL; //dx_close; return (vo_instance_t *) instance;}vo_instance_t * vo_dxrgb_open (void){ return common_open (dxrgb_setup, dx_setup_fbuf, dxrgb_draw_frame);}static LPDIRECTDRAWSURFACE2 alloc_overlay (dx_instance_t * instance){ DDSURFACEDESC ddsd; LPDIRECTDRAWSURFACE2 surface; memset (&ddsd, 0, sizeof (DDSURFACEDESC)); ddsd.dwSize = sizeof (DDSURFACEDESC); ddsd.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT); ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS; ddsd.dwHeight = instance->height; ddsd.dwWidth = instance->width; ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; ddsd.ddpfPixelFormat.dwFourCC = FOURCC_YV12; ddsd.dwFlags |= DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;#if USE_OVERLAY_TRIPLE_BUFFERING ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP;#endif ddsd.dwBackBufferCount = 2; surface = alloc_surface (instance, &ddsd); if (surface == NULL) fprintf (stderr, "Can not create directDraw frame surface\n"); return surface;}static int dx_setup (vo_instance_t * _instance, unsigned int width, unsigned int height, unsigned int chroma_width, unsigned int chroma_height, vo_setup_result_t * result){ dx_instance_t * instance = (dx_instance_t *) _instance; LPDIRECTDRAWSURFACE2 surface; DDSURFACEDESC ddsd; if (common_setup (instance, width, height)) return 1; instance->overlay = alloc_overlay (instance); if (!instance->overlay) return 1; update_overlay (instance); surface = instance->overlay; /* Get the back buffer */ memset (&ddsd.ddsCaps, 0, sizeof (DDSCAPS)); ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; if (DD_OK != IDirectDrawSurface2_GetAttachedSurface (instance->overlay, &ddsd.ddsCaps, &surface)) surface = instance->overlay; instance->yuv[0] = surface_addr (surface, &instance->stride); instance->yuv[2] = instance->yuv[0] + instance->stride * instance->height; instance->yuv[1] = instance->yuv[2] + (instance->stride * instance->height >> 2); result->convert = NULL; return 0;}static void copy_yuv_picture (dx_instance_t * instance, uint8_t * const * buf, void * id){ uint8_t * dest[3]; int width, i; dest[0] = instance->yuv[0]; dest[1] = instance->yuv[1]; dest[2] = instance->yuv[2]; width = instance->width; for (i = 0; i < instance->height >> 1; i++) { memcpy (dest[0], buf[0] + 2 * i * width, width); dest[0] += instance->stride; memcpy (dest[0], buf[0] + (2 * i + 1) * width, width); dest[0] += instance->stride; memcpy (dest[1], buf[1] + i * (width >> 1), width >> 1); dest[1] += instance->stride >> 1; memcpy (dest[2], buf[2] + i * (width >> 1), width >> 1); dest[2] += instance->stride >> 1; }}static void dx_draw_frame (vo_instance_t * _instance, uint8_t * const * buf, void * id){ dx_instance_t * instance = (dx_instance_t *) _instance; check_events (instance); copy_yuv_picture (instance, buf, id); if (DDERR_SURFACELOST == IDirectDrawSurface2_Flip (instance->overlay, NULL, DDFLIP_WAIT)) { /* restore surfaces and try again */ IDirectDrawSurface2_Restore (instance->display); IDirectDrawSurface2_Restore (instance->overlay); IDirectDrawSurface2_Flip (instance->overlay, NULL, DDFLIP_WAIT); }}vo_instance_t * vo_dx_open (void){ return common_open (dx_setup, NULL, dx_draw_frame);}#if 0static void dx_close (vo_instance_t * _instance){ dx_instance_t * instance; int i; instance = (dx_instance_t *) _instance; if (instance->using_overlay && instance->overlay) { IDirectDrawSurface2_Release (instance->overlay); instance->overlay = NULL; } else for (i = 0; i < 3; i++) { if (instance->frame[i].p_surface != NULL) IDirectDrawSurface2_Release (instance->frame[i].p_surface); instance->frame[i].p_surface = NULL; } if (instance->clipper != NULL) IDirectDrawClipper_Release (instance->clipper); if (instance->display != NULL) IDirectDrawSurface2_Release (instance->display); if (instance->ddraw != NULL) IDirectDraw2_Release (instance->ddraw); if (instance->hddraw_dll != NULL) FreeLibrary (instance->hddraw_dll); if (instance->window != NULL) DestroyWindow (instance->window);}#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -