[vlc-devel] [PATCH 11/17] directx_va: the context copy is responsible for the va_surface refcount increment
Steve Lhomme
robux4 at videolabs.io
Tue Jun 20 17:45:43 CEST 2017
---
modules/codec/avcodec/d3d11va.c | 18 ++++++++++--------
modules/codec/avcodec/dxva2.c | 15 +++++++++------
modules/codec/avcodec/va_surface.c | 21 ++++++++++++---------
3 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index bf1edd7009..a51763b8bd 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -176,7 +176,7 @@ static int Extract(vlc_va_t *va, picture_t *output, uint8_t *data)
{
VLC_UNUSED(va); VLC_UNUSED(data);
struct va_pic_context *pic_ctx = (struct va_pic_context*)output->context;
- if (!va->sys->b_extern_pool)
+ if (pic_ctx->va_surface)
va_surface_AddRef(pic_ctx->va_surface);
assert(data == (void*)pic_ctx->picsys.decoder);
return VLC_SUCCESS;
@@ -191,8 +191,7 @@ static void d3d11_pic_context_destroy(struct picture_context_t *opaque)
free(pic_ctx);
}
-static struct va_pic_context *CreatePicContext(vlc_va_surface_t *,
- ID3D11VideoDecoderOutputView *,
+static struct va_pic_context *CreatePicContext(ID3D11VideoDecoderOutputView *,
ID3D11Resource *,
ID3D11DeviceContext *,
UINT slice,
@@ -201,15 +200,19 @@ static struct va_pic_context *CreatePicContext(vlc_va_surface_t *,
static struct picture_context_t *d3d11_pic_context_copy(struct picture_context_t *ctx)
{
struct va_pic_context *src_ctx = (struct va_pic_context*)ctx;
- struct va_pic_context *pic_ctx = CreatePicContext(src_ctx->va_surface, src_ctx->picsys.decoder,
+ struct va_pic_context *pic_ctx = CreatePicContext(src_ctx->picsys.decoder,
src_ctx->picsys.resource[0], src_ctx->picsys.context,
src_ctx->picsys.slice_index, src_ctx->picsys.resourceView);
if (unlikely(pic_ctx==NULL))
return NULL;
+ if (src_ctx->va_surface) {
+ pic_ctx->va_surface = src_ctx->va_surface;
+ va_surface_AddRef(pic_ctx->va_surface);
+ }
return &pic_ctx->s;
}
-static struct va_pic_context *CreatePicContext(vlc_va_surface_t *va_surface,
+static struct va_pic_context *CreatePicContext(
ID3D11VideoDecoderOutputView *decoderSurface,
ID3D11Resource *p_resource,
ID3D11DeviceContext *context,
@@ -221,7 +224,6 @@ static struct va_pic_context *CreatePicContext(vlc_va_surface_t *va_surface,
goto done;
pic_ctx->s.destroy = d3d11_pic_context_destroy;
pic_ctx->s.copy = d3d11_pic_context_copy;
- pic_ctx->va_surface = va_surface;
pic_ctx->picsys.context = context;
pic_ctx->picsys.slice_index = slice;
pic_ctx->picsys.decoder = decoderSurface;
@@ -248,7 +250,7 @@ static struct va_pic_context* NewSurfacePicContext(vlc_va_t *va, ID3D11VideoDeco
for (int i=0; i<D3D11_MAX_SHADER_VIEW; i++)
resourceView[i] = va->sys->resourceView[viewDesc.Texture2D.ArraySlice*D3D11_MAX_SHADER_VIEW + i];
- struct va_pic_context *pic_ctx = CreatePicContext(NULL,
+ struct va_pic_context *pic_ctx = CreatePicContext(
surface,
p_resource,
va->sys->d3dctx,
@@ -290,7 +292,7 @@ static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
return VLC_EGENERIC;
}
- pic->context = (picture_context_t*)CreatePicContext( NULL,
+ pic->context = (picture_context_t*)CreatePicContext(
pic->p_sys->decoder,
pic->p_sys->resource[KNOWN_DXGI_INDEX],
va->sys->d3dctx,
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 8794792f44..b950bc6abb 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -193,21 +193,24 @@ static void d3d9_pic_context_destroy(struct picture_context_t *opaque)
}
}
-static struct va_pic_context *CreatePicContext(vlc_va_surface_t *, IDirect3DSurface9 *);
+static struct va_pic_context *CreatePicContext(IDirect3DSurface9 *);
static struct picture_context_t *d3d9_pic_context_copy(struct picture_context_t *ctx)
{
struct va_pic_context *src_ctx = (struct va_pic_context*)ctx;
- return (picture_context_t*)CreatePicContext(src_ctx->va_surface, src_ctx->picsys.surface);
+ struct va_pic_context *pic_ctx = CreatePicContext(src_ctx->picsys.surface);
+ if (unlikely(pic_ctx==NULL))
+ return NULL;
+ pic_ctx->va_surface = src_ctx->va_surface;
+ va_surface_AddRef(pic_ctx->va_surface);
+ return &pic_ctx->s;
}
-static struct va_pic_context *CreatePicContext(vlc_va_surface_t *va_surface, IDirect3DSurface9 *surface)
+static struct va_pic_context *CreatePicContext(IDirect3DSurface9 *surface)
{
struct va_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
if (unlikely(pic_ctx==NULL))
return NULL;
- pic_ctx->va_surface = va_surface;
- va_surface_AddRef(pic_ctx->va_surface);
pic_ctx->s.destroy = d3d9_pic_context_destroy;
pic_ctx->s.copy = d3d9_pic_context_copy;
pic_ctx->picsys.surface = surface;
@@ -218,7 +221,7 @@ static struct va_pic_context *CreatePicContext(vlc_va_surface_t *va_surface, IDi
static struct va_pic_context* NewSurfacePicContext(vlc_va_t *va, IDirect3DSurface9 *surface)
{
VLC_UNUSED(va);
- return CreatePicContext(NULL, surface);
+ return CreatePicContext(surface);
}
static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
diff --git a/modules/codec/avcodec/va_surface.c b/modules/codec/avcodec/va_surface.c
index 860ef9b7f4..445b4eac7e 100644
--- a/modules/codec/avcodec/va_surface.c
+++ b/modules/codec/avcodec/va_surface.c
@@ -96,14 +96,21 @@ int va_pool_Setup(vlc_va_t *va, va_pool_t *va_pool, const AVCodecContext *avctx,
avctx->coded_width, avctx->coded_height);
for (int i = 0; i < va_pool->surface_count; i++) {
- struct va_pic_context *p_ctx = va_pool->pf_new_surface_context(va, va_pool->hw_surface[i]);
- if (unlikely(p_ctx==NULL))
+ struct vlc_va_surface_t *p_surface = malloc(sizeof(*p_surface));
+ if (unlikely(p_surface==NULL))
{
va_pool->surface_count = i;
return VLC_ENOMEM;
}
- atomic_init(&p_ctx->va_surface->refcount, 1);
- va_pool->surface[i] = p_ctx;
+ va_pool->surface[i] = va_pool->pf_new_surface_context(va, va_pool->hw_surface[i]);
+ if (unlikely(va_pool->surface[i]==NULL))
+ {
+ free(p_surface);
+ va_pool->surface_count = i;
+ return VLC_ENOMEM;
+ }
+ va_pool->surface[i]->va_surface = p_surface;
+ atomic_init(&va_pool->surface[i]->va_surface->refcount, 1);
}
va_pool->pf_setup_avcodec_ctx(va);
@@ -121,11 +128,7 @@ static picture_context_t *GetSurface(va_pool_t *va_pool)
if (atomic_compare_exchange_strong(&surface->va_surface->refcount, &expected, 2))
{
picture_context_t *field = surface->s.copy(&surface->s);
- if (!field)
- {
- atomic_fetch_sub(&surface->va_surface->refcount, 1);
- continue;
- }
+ atomic_fetch_sub(&surface->va_surface->refcount, 1);
return field;
}
}
--
2.12.1
More information about the vlc-devel
mailing list