[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