static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9 *iface, UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer) { struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface); struct wined3d_surface *wined3d_surface = NULL; struct d3d9_surface *surface_impl; HRESULT hr = D3D_OK; TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n", iface, backbuffer_idx, backbuffer_type, backbuffer); wined3d_mutex_lock(); if ((wined3d_surface = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, backbuffer_idx, (enum wined3d_backbuffer_type)backbuffer_type))) { surface_impl = wined3d_surface_get_parent(wined3d_surface); *backbuffer = &surface_impl->IDirect3DSurface9_iface; IDirect3DSurface9_AddRef(*backbuffer); } else { hr = D3DERR_INVALIDCALL; } wined3d_mutex_unlock(); return hr; }
static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 *iface, D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface) { struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); struct wined3d_resource *sub_resource; struct d3d9_surface *surface_impl; UINT sub_resource_idx; DWORD level_count; TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface); wined3d_mutex_lock(); level_count = wined3d_texture_get_level_count(texture->wined3d_texture); if (level >= level_count) { wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } sub_resource_idx = level_count * face + level; if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx))) { wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } surface_impl = wined3d_resource_get_parent(sub_resource); *surface = &surface_impl->IDirect3DSurface9_iface; IDirect3DSurface9_AddRef(*surface); wined3d_mutex_unlock(); return D3D_OK; }
static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9Ex *iface, UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer) { struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); struct wined3d_texture *wined3d_texture; struct d3d9_surface *surface_impl; HRESULT hr = D3D_OK; TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n", iface, backbuffer_idx, backbuffer_type, backbuffer); /* backbuffer_type is ignored by native. */ if (!backbuffer) { WARN("The output pointer is NULL, returning D3DERR_INVALIDCALL.\n"); return D3DERR_INVALIDCALL; } wined3d_mutex_lock(); if ((wined3d_texture = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, backbuffer_idx))) { surface_impl = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0); *backbuffer = &surface_impl->IDirect3DSurface9_iface; IDirect3DSurface9_AddRef(*backbuffer); } else { /* Do not set *backbuffer = NULL, see tests/device.c, test_swapchain(). */ hr = D3DERR_INVALIDCALL; } wined3d_mutex_unlock(); return hr; }
static int dxva2_get_buffer(AVCodecContext *s, AVFrame *frame, int flags) { HwAccelContext *hac = s->opaque; DXVA2Context *ctx = hac->hwaccel_ctx; int i, old_unused = -1; LPDIRECT3DSURFACE9 surface; DXVA2SurfaceWrapper *w = NULL; av_assert0(frame->format == AV_PIX_FMT_DXVA2_VLD); for (i = 0; i < ctx->num_surfaces; i++) { surface_info *info = &ctx->surface_infos[i]; if (!info->used && (old_unused == -1 || info->age < ctx->surface_infos[old_unused].age)) old_unused = i; } if (old_unused == -1) { av_log(NULL, AV_LOG_ERROR, "No free DXVA2 surface!\n"); return AVERROR(ENOMEM); } i = old_unused; av_log(NULL, AV_LOG_DEBUG, "dxva2_get_buffer:%d\n",i); surface = ctx->surfaces[i]; w = av_mallocz(sizeof(*w)); if (!w) return AVERROR(ENOMEM); frame->buf[0] = av_buffer_create((uint8_t*)surface, 0, dxva2_release_buffer, w, AV_BUFFER_FLAG_READONLY); if (!frame->buf[0]) { av_free(w); return AVERROR(ENOMEM); } w->ctx = ctx; w->surface = surface; IDirect3DSurface9_AddRef(w->surface); w->decoder = ctx->decoder; IDirectXVideoDecoder_AddRef(w->decoder); ctx->surface_infos[i].used = 1; ctx->surface_infos[i].age = ctx->surface_age++; frame->data[3] = (uint8_t *)surface; return 0; }
/* IDirect3DSurface9 IUnknown parts follow: */ static HRESULT WINAPI IDirect3DSurface9Impl_QueryInterface(LPDIRECT3DSURFACE9 iface, REFIID riid, LPVOID* ppobj) { IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface; TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj); if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3DResource9) || IsEqualGUID(riid, &IID_IDirect3DSurface9)) { IDirect3DSurface9_AddRef(iface); *ppobj = This; return S_OK; } WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj); *ppobj = NULL; return E_NOINTERFACE; }
static HRESULT WINAPI d3d9_surface_QueryInterface(IDirect3DSurface9 *iface, REFIID riid, void **out) { TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); if (IsEqualGUID(riid, &IID_IDirect3DSurface9) || IsEqualGUID(riid, &IID_IDirect3DResource9) || IsEqualGUID(riid, &IID_IUnknown)) { IDirect3DSurface9_AddRef(iface); *out = iface; return S_OK; } WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); *out = NULL; return E_NOINTERFACE; }
struct mp_image *dxva2_new_ref(IDirectXVideoDecoder *decoder, LPDIRECT3DSURFACE9 d3d9_surface, int w, int h) { if (!decoder || !d3d9_surface) return NULL; struct dxva2_surface *surface = talloc_zero(NULL, struct dxva2_surface); // Add additional references to the libraries which might otherwise be freed // before the surface, which is observed to lead to bad behaviour surface->d3dlib = LoadLibrary(L"d3d9.dll"); surface->dxva2lib = LoadLibrary(L"dxva2.dll"); if (!surface->d3dlib || !surface->dxva2lib) goto fail; surface->surface = d3d9_surface; IDirect3DSurface9_AddRef(surface->surface); surface->decoder = decoder; IDirectXVideoDecoder_AddRef(surface->decoder); struct mp_image *mpi = mp_image_new_custom_ref(&(struct mp_image){0},
static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetCubeMapSurface(IDirect3DCubeTexture9 *iface, D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9 **ppCubeMapSurface) { IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface; IWineD3DSurface *mySurface = NULL; HRESULT hr; TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, FaceType, Level, ppCubeMapSurface); wined3d_mutex_lock(); hr = IWineD3DCubeTexture_GetCubeMapSurface(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES)FaceType, Level, &mySurface); if (SUCCEEDED(hr) && ppCubeMapSurface) { *ppCubeMapSurface = IWineD3DCubeTexture_GetParent(mySurface); IDirect3DSurface9_AddRef(*ppCubeMapSurface); IWineD3DCubeTexture_Release(mySurface); } wined3d_mutex_unlock(); return hr; }
static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface, UINT level, IDirect3DSurface9 **surface) { struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); struct wined3d_resource *sub_resource; struct d3d9_surface *surface_impl; TRACE("iface %p, level %u, surface %p.\n", iface, level, surface); wined3d_mutex_lock(); if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) { wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } surface_impl = wined3d_resource_get_parent(sub_resource); *surface = &surface_impl->IDirect3DSurface9_iface; IDirect3DSurface9_AddRef(*surface); wined3d_mutex_unlock(); return D3D_OK; }
static struct mp_image *dxva2_new_ref(IDirectXVideoDecoder *decoder, IDirect3DSurface9 *d3d9_surface, int w, int h) { if (!decoder || !d3d9_surface) return NULL; struct dxva2_surface *surface = talloc_zero(NULL, struct dxva2_surface); surface->surface = d3d9_surface; IDirect3DSurface9_AddRef(surface->surface); surface->decoder = decoder; IDirectXVideoDecoder_AddRef(surface->decoder); struct mp_image *mpi = mp_image_new_custom_ref(NULL, surface, dxva2_release_img); if (!mpi) abort(); mp_image_setfmt(mpi, IMGFMT_DXVA2); mp_image_set_size(mpi, w, h); mpi->planes[3] = (void *)surface->surface; return mpi; }
static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetCubeMapSurface(IDirect3DCubeTexture9 *iface, D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface) { IDirect3DCubeTexture9Impl *texture = impl_from_IDirect3DCubeTexture9(iface); struct wined3d_resource *sub_resource; UINT sub_resource_idx; TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface); wined3d_mutex_lock(); sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx))) { wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } *surface = wined3d_resource_get_parent(sub_resource); IDirect3DSurface9_AddRef(*surface); wined3d_mutex_unlock(); return D3D_OK; }
static struct mp_image *dxva2_allocate_image(struct lavc_ctx *s, int img_w, int img_h) { DXVA2Context *ctx = s->hwdec_priv; int i, old_unused = -1; for (i = 0; i < ctx->num_surfaces; i++) { surface_info *info = &ctx->surface_infos[i]; if (!info->used && (old_unused == -1 || info->age < ctx->surface_infos[old_unused].age)) old_unused = i; } if (old_unused == -1) { MP_ERR(ctx, "No free DXVA2 surface!\n"); return NULL; } i = old_unused; DXVA2SurfaceWrapper *w = av_mallocz(sizeof(*w)); if (!w) return NULL; w->ctx = ctx; w->surface = ctx->surfaces[i];; IDirect3DSurface9_AddRef(w->surface); w->decoder = ctx->decoder; IDirectXVideoDecoder_AddRef(w->decoder); ctx->surface_infos[i].used = 1; ctx->surface_infos[i].age = ctx->surface_age++; struct mp_image mpi = {0}; mp_image_setfmt(&mpi, IMGFMT_DXVA2); mp_image_set_size(&mpi, img_w, img_h); mpi.planes[3] = (void *)w->surface; return mp_image_new_custom_ref(&mpi, w, dxva2_release_img); }
static HRESULT WINAPI IDirect3DSwapChain9Impl_GetBackBuffer(IDirect3DSwapChain9 *iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 **ppBackBuffer) { IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface; IWineD3DSurface *mySurface = NULL; HRESULT hr; TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n", iface, iBackBuffer, Type, ppBackBuffer); wined3d_mutex_lock(); hr = IWineD3DSwapChain_GetBackBuffer(This->wineD3DSwapChain, iBackBuffer, (WINED3DBACKBUFFER_TYPE)Type, &mySurface); if (SUCCEEDED(hr) && mySurface) { *ppBackBuffer = IWineD3DSurface_GetParent(mySurface); IDirect3DSurface9_AddRef(*ppBackBuffer); IWineD3DSurface_Release(mySurface); } wined3d_mutex_unlock(); /* Do not touch the **ppBackBuffer pointer otherwise! (see device test) */ return hr; }
static HRESULT WINAPI IDirect3DSwapChain9Impl_GetBackBuffer(IDirect3DSwapChain9 *iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 **ppBackBuffer) { IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface; struct wined3d_surface *wined3d_surface = NULL; HRESULT hr; TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n", iface, iBackBuffer, Type, ppBackBuffer); wined3d_mutex_lock(); hr = wined3d_swapchain_get_back_buffer(This->wined3d_swapchain, iBackBuffer, (enum wined3d_backbuffer_type)Type, &wined3d_surface); if (SUCCEEDED(hr) && wined3d_surface) { *ppBackBuffer = wined3d_surface_get_parent(wined3d_surface); IDirect3DSurface9_AddRef(*ppBackBuffer); wined3d_surface_decref(wined3d_surface); } wined3d_mutex_unlock(); /* Do not touch the **ppBackBuffer pointer otherwise! (see device test) */ return hr; }