static struct mp_image *d3d11va_new_ref(ID3D11VideoDecoderOutputView *view, int w, int h) { if (!view) return NULL; struct d3d11va_surface *surface = talloc_zero(NULL, struct d3d11va_surface); surface->surface = view; ID3D11VideoDecoderOutputView_AddRef(surface->surface); ID3D11VideoDecoderOutputView_GetResource( surface->surface, (ID3D11Resource **)&surface->texture); D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC surface_desc; ID3D11VideoDecoderOutputView_GetDesc(surface->surface, &surface_desc); surface->subindex = surface_desc.Texture2D.ArraySlice; struct mp_image *mpi = mp_image_new_custom_ref(NULL, surface, d3d11va_release_img); if (!mpi) abort(); mp_image_setfmt(mpi, IMGFMT_D3D11VA); mp_image_set_size(mpi, w, h); mpi->planes[0] = NULL; mpi->planes[1] = (void *)surface->texture; mpi->planes[2] = (void *)(intptr_t)surface->subindex; mpi->planes[3] = (void *)surface->surface; return mpi; }
static struct mp_image *alloc_pool(void *pctx, int fmt, int w, int h) { struct vf_instance *vf = pctx; struct vf_priv_s *p = vf->priv; HRESULT hr; ID3D11Texture2D *texture = NULL; D3D11_TEXTURE2D_DESC texdesc = { .Width = w, .Height = h, .Format = p->out_format, .MipLevels = 1, .ArraySize = 1, .SampleDesc = { .Count = 1 }, .Usage = D3D11_USAGE_DEFAULT, .BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, .MiscFlags = p->out_shared ? D3D11_RESOURCE_MISC_SHARED : 0, }; hr = ID3D11Device_CreateTexture2D(p->vo_dev, &texdesc, NULL, &texture); if (FAILED(hr)) return NULL; struct mp_image *mpi = mp_image_new_custom_ref(NULL, texture, release_tex); if (!mpi) abort(); mp_image_setfmt(mpi, p->out_params.imgfmt); mp_image_set_size(mpi, w, h); mpi->params.hw_subfmt = p->out_params.hw_subfmt; mpi->planes[1] = (void *)texture; mpi->planes[2] = (void *)(intptr_t)0; return mpi; }
// This actually returns dummy images, since vda_264 creates it's own AVFrames // to wrap CVPixelBuffers in planes[3]. static struct mp_image *allocate_image(struct lavc_ctx *ctx, int fmt, int w, int h) { struct priv *p = ctx->hwdec_priv; if (fmt != IMGFMT_VDA) return NULL; if (w != p->vda_ctx.width || h != p->vda_ctx.height) init_vda_decoder(ctx); struct mp_image img = {0}; mp_image_setfmt(&img, fmt); mp_image_set_size(&img, w, h); // There is an `assert(!dst->f.buf[0])` in libavcodec/h264.c // Setting the first plane to some dummy value allows to satisfy it img.planes[0] = (void*)"dummy"; return mp_image_new_custom_ref(&img, NULL, NULL); }
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 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); }
mp_image *null_mp_image(void *arg, void(*free)(void*)) { return mp_image_new_custom_ref(&null, arg, free); }