static int DirectXCreatePictureResourceYuvOverlay(vout_display_t *vd, const video_format_t *fmt, DWORD fourcc) { vout_display_sys_t *sys = vd->sys; bool allow_3buf = var_InheritBool(vd, "directx-3buffering"); /* The overlay surface that we create won't be used to decode directly * into it because accessing video memory directly is way to slow (remember * that pictures are decoded macroblock per macroblock). Instead the video * will be decoded in picture buffers in system memory which will then be * memcpy() to the overlay surface. */ LPDIRECTDRAWSURFACE2 front_surface; int ret = VLC_EGENERIC; if (allow_3buf) { /* Triple buffering rocks! it doesn't have any processing overhead * (you don't have to wait for the vsync) and provides for a very nice * video quality (no tearing). */ ret = DirectXCreateSurface(vd, &front_surface, fmt, fourcc, true, false, 2); } if (ret) ret = DirectXCreateSurface(vd, &front_surface, fmt, fourcc, true, false, 0); if (ret) return VLC_EGENERIC; msg_Dbg(vd, "YUV overlay surface created successfully"); /* Get the back buffer */ LPDIRECTDRAWSURFACE2 surface; DDSCAPS dds_caps; ZeroMemory(&dds_caps, sizeof(dds_caps)); dds_caps.dwCaps = DDSCAPS_BACKBUFFER; if (IDirectDrawSurface2_GetAttachedSurface(front_surface, &dds_caps, &surface) != DD_OK) { msg_Warn(vd, "Failed to get surface back buffer"); /* front buffer is the same as back buffer */ surface = front_surface; } if (DirectXCheckLockingSurface(front_surface, surface)) { DirectXDestroySurface(front_surface); return VLC_EGENERIC; } /* */ picture_resource_t *rsc = &sys->resource; rsc->p_sys->front_surface = front_surface; rsc->p_sys->surface = surface; rsc->p_sys->fallback = NULL; return VLC_SUCCESS; }
/* recreate_flipping_chain: * Destroys the previous flipping chain and creates a new one. */ static int recreate_flipping_chain(int n_pages) { int w, h, type, n_backbuffers; DDSCAPS ddscaps; HRESULT hr; ASSERT(n_pages > 0); /* set flipping chain characteristics */ w = gfx_directx_forefront_bitmap->w; h = gfx_directx_forefront_bitmap->h; type = flipping_page[0]->flags & DDRAW_SURFACE_TYPE_MASK; n_backbuffers = n_pages - 1; /* release existing flipping chain */ if (flipping_page[0]->id) { hr = IDirectDrawSurface2_Release(flipping_page[0]->id); if (FAILED(hr)) { _TRACE(PREFIX_E "Unable to release the primary surface (%s)", dd_err(hr)); return -1; } } /* create the new flipping chain with the specified characteristics */ flipping_page[0]->id = create_directdraw2_surface(w, h, ddpixel_format, type, n_backbuffers); if (!flipping_page[0]->id) return -1; /* retrieve the backbuffers */ if (n_backbuffers > 0) { memset(&ddscaps, 0, sizeof(DDSCAPS)); /* first backbuffer */ ddscaps.dwCaps = DDSCAPS_BACKBUFFER; hr = IDirectDrawSurface2_GetAttachedSurface(flipping_page[0]->id, &ddscaps, &flipping_page[1]->id); if (FAILED(hr)) { _TRACE(PREFIX_E "Unable to retrieve the first backbuffer (%s)", dd_err(hr)); return -1; } flipping_page[1]->flags = flipping_page[0]->flags; flipping_page[1]->lock_nesting = 0; if (n_backbuffers > 1) { /* second backbuffer */ ddscaps.dwCaps = DDSCAPS_FLIP; hr = IDirectDrawSurface2_GetAttachedSurface(flipping_page[1]->id, &ddscaps, &flipping_page[2]->id); if (FAILED(hr)) { _TRACE(PREFIX_E "Unable to retrieve the second backbuffer (%s)", dd_err(hr)); return -1; } flipping_page[2]->flags = flipping_page[0]->flags; flipping_page[2]->lock_nesting = 0; } } /* attach the global palette if needed */ if (flipping_page[0]->flags & DDRAW_SURFACE_INDEXED) { hr = IDirectDrawSurface2_SetPalette(flipping_page[0]->id, ddpalette); if (FAILED(hr)) { _TRACE(PREFIX_E "Unable to attach the global palette (%s)", dd_err(hr)); return -1; } } return 0; }