[vlc-devel] [PATCH 06/17] directx_va: remove unused parameter

Steve Lhomme robux4 at videolabs.io
Tue Jun 20 17:45:38 CEST 2017


---
 modules/codec/avcodec/d3d11va.c             | 61 ++++++++++++++++-------------
 modules/codec/avcodec/directx_va.c          |  2 +-
 modules/codec/avcodec/dxva2.c               | 35 +++++++++++------
 modules/codec/avcodec/va_surface.c          | 27 +++++++------
 modules/codec/avcodec/va_surface_internal.h |  9 ++++-
 5 files changed, 79 insertions(+), 55 deletions(-)

diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index 45b46a6f11..3026885e0b 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -236,6 +236,35 @@ done:
     return pic_ctx;
 }
 
+static picture_context_t* NewSurfacePicContext(vlc_va_t *va, vlc_va_surface_t *va_surface, ID3D11VideoDecoderOutputView *surface)
+{
+    ID3D11ShaderResourceView *resourceView[D3D11_MAX_SHADER_VIEW];
+    ID3D11Resource *p_resource;
+    ID3D11VideoDecoderOutputView_GetResource(surface, &p_resource);
+
+    D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
+    ID3D11VideoDecoderOutputView_GetDesc(surface, &viewDesc);
+
+    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(va_surface,
+                                                  surface,
+                                                  p_resource,
+                                                  va->sys->d3dctx,
+                                                  viewDesc.Texture2D.ArraySlice,
+                                                  resourceView);
+    ID3D11Resource_Release(p_resource);
+    if (unlikely(pic_ctx==NULL))
+        return NULL;
+    /* all the resources are acquired during surfaces init, and a second time in
+     * CreatePicContext(), undo one of them otherwise we need an extra release
+     * when the pool is emptied */
+    ReleasePictureSys(&pic_ctx->picsys);
+    va_surface->decoderSurface = surface;
+    return &pic_ctx->s;
+}
+
 static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
 {
 #if D3D11_DIRECT_DECODE
@@ -275,34 +304,9 @@ static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
     else
 #endif
     {
-        ID3D11ShaderResourceView *resourceView[D3D11_MAX_SHADER_VIEW];
-        vlc_va_surface_t *va_surface = va_pool_Get(va, &va->sys->dx_sys.va_pool);
-        if (unlikely(va_surface==NULL))
-            return VLC_EGENERIC;
-
-        ID3D11Resource *p_resource;
-        ID3D11VideoDecoderOutputView_GetResource(va_surface->decoderSurface, &p_resource);
-
-        D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
-        ID3D11VideoDecoderOutputView_GetDesc(va_surface->decoderSurface, &viewDesc);
-
-        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( va_surface,
-                                                              va_surface->decoderSurface,
-                                                              p_resource,
-                                                              va->sys->d3dctx,
-                                                              viewDesc.Texture2D.ArraySlice,
-                                                              resourceView );
-
-        ID3D11Resource_Release(p_resource);
-        if (unlikely(pic_ctx==NULL))
-        {
-            va_surface_Release(va_surface);
-            return VLC_ENOMEM;
-        }
-        pic->context = &pic_ctx->s;
+        int res = va_pool_Get(va, pic, &va->sys->dx_sys.va_pool);
+        if (unlikely(res != VLC_SUCCESS))
+            return res;
     }
     *data = (uint8_t*)((struct va_pic_context *)pic->context)->picsys.decoder;
     return VLC_SUCCESS;
@@ -371,6 +375,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
     dx_sys->va_pool.pf_create_decoder_surfaces = DxCreateDecoderSurfaces;
     dx_sys->va_pool.pf_destroy_surfaces        = DxDestroySurfaces;
     dx_sys->va_pool.pf_setup_avcodec_ctx       = SetupAVCodecContext;
+    dx_sys->va_pool.pf_new_surface_context     = NewSurfacePicContext;
     dx_sys->pf_get_input_list          = DxGetInputList;
     dx_sys->pf_setup_output            = DxSetupOutput;
     dx_sys->psz_decoder_dll            = TEXT("D3D11.DLL");
diff --git a/modules/codec/avcodec/directx_va.c b/modules/codec/avcodec/directx_va.c
index 2e1a262d32..9cae5a1237 100644
--- a/modules/codec/avcodec/directx_va.c
+++ b/modules/codec/avcodec/directx_va.c
@@ -330,7 +330,7 @@ int directx_va_Open(vlc_va_t *va, directx_sys_t *dx_sys,
         msg_Dbg(va, "DLLs loaded");
     }
 
-    if (va_pool_Open(va, &dx_sys->va_pool, ctx, fmt) != VLC_SUCCESS)
+    if (va_pool_Open(va, &dx_sys->va_pool, ctx) != VLC_SUCCESS)
         goto error;
 
     /* */
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 5e69ffa538..5e0f203732 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -193,15 +193,18 @@ static void d3d9_pic_context_destroy(struct picture_context_t *opaque)
     }
 }
 
-static struct picture_context_t *CreatePicContext(vlc_va_surface_t *);
+static struct va_pic_context *CreatePicContext(vlc_va_surface_t *, 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 CreatePicContext(src_ctx->va_surface);
+    struct va_pic_context *pic_ctx = CreatePicContext(src_ctx->va_surface, src_ctx->picsys.surface);
+    if (unlikely(pic_ctx==NULL))
+        return NULL;
+    return &pic_ctx->s;
 }
 
-static struct picture_context_t *CreatePicContext(vlc_va_surface_t *va_surface)
+static struct va_pic_context *CreatePicContext(vlc_va_surface_t *va_surface, IDirect3DSurface9 *surface)
 {
     struct va_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
     if (unlikely(pic_ctx==NULL))
@@ -210,8 +213,18 @@ static struct picture_context_t *CreatePicContext(vlc_va_surface_t *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 = va_surface->decoderSurface;
+    pic_ctx->picsys.surface = surface;
     AcquirePictureSys(&pic_ctx->picsys);
+    return pic_ctx;
+}
+
+static picture_context_t* NewSurfacePicContext(vlc_va_t *va, vlc_va_surface_t *va_surface, IDirect3DSurface9 *surface)
+{
+    VLC_UNUSED(va);
+    struct va_pic_context *pic_ctx = CreatePicContext(va_surface, surface);
+    if (unlikely(pic_ctx==NULL))
+        return NULL;
+    va_surface->decoderSurface = surface;
     return &pic_ctx->s;
 }
 
@@ -229,15 +242,10 @@ static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
         return VLC_EGENERIC;
     }
 
-    vlc_va_surface_t *va_surface = va_pool_Get(va, &sys->dx_sys.va_pool);
-    if (unlikely(va_surface==NULL))
-        return VLC_EGENERIC;
-    pic->context = CreatePicContext(va_surface);
-    va_surface_Release(va_surface);
-    if (unlikely(pic->context==NULL))
-        return VLC_EGENERIC;
-    *data = (uint8_t*)va_surface->decoderSurface;
-    return VLC_SUCCESS;
+    int res = va_pool_Get(va, pic, &sys->dx_sys.va_pool);
+    if (likely(res==VLC_SUCCESS))
+        *data = (uint8_t*)((struct va_pic_context*)pic->context)->picsys.surface;
+    return res;
 }
 
 static void Close(vlc_va_t *va, void *ctx)
@@ -309,6 +317,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
     dx_sys->va_pool.pf_create_decoder_surfaces = DxCreateVideoDecoder;
     dx_sys->va_pool.pf_destroy_surfaces        = DxDestroyVideoDecoder;
     dx_sys->va_pool.pf_setup_avcodec_ctx       = SetupAVCodecContext;
+    dx_sys->va_pool.pf_new_surface_context     = NewSurfacePicContext;
     dx_sys->pf_get_input_list          = DxGetInputList;
     dx_sys->pf_setup_output            = DxSetupOutput;
     dx_sys->psz_decoder_dll            = TEXT("DXVA2.DLL");
diff --git a/modules/codec/avcodec/va_surface.c b/modules/codec/avcodec/va_surface.c
index 46d70677ad..d9e13c5114 100644
--- a/modules/codec/avcodec/va_surface.c
+++ b/modules/codec/avcodec/va_surface.c
@@ -33,6 +33,7 @@
 #include <vlc_common.h>
 #include <vlc_codecs.h>
 #include <vlc_codec.h>
+#include <vlc_picture.h>
 
 
 #define D3D_DecoderType     void
@@ -110,7 +111,7 @@ ok:
     return VLC_SUCCESS;
 }
 
-static vlc_va_surface_t *GetSurface(va_pool_t *va_pool)
+static picture_context_t *GetSurface(vlc_va_t *va, va_pool_t *va_pool)
 {
     for (int i = 0; i < va_pool->surface_count; i++) {
         vlc_va_surface_t *surface = va_pool->surface[i];
@@ -118,28 +119,33 @@ static vlc_va_surface_t *GetSurface(va_pool_t *va_pool)
 
         if (atomic_compare_exchange_strong(&surface->refcount, &expected, 2))
         {
-            /* TODO do a copy to allow releasing locally and keep forward alive atomic_fetch_sub(&surface->refs, 1);*/
-            surface->decoderSurface = va_pool->hw_surface[i];
-            return surface;
+            picture_context_t *field = va_pool->pf_new_surface_context(va, surface, va_pool->hw_surface[i]);
+            if (!field)
+            {
+                atomic_fetch_sub(&surface->refcount, 1);
+                continue;
+            }
+            return field;
         }
     }
     return NULL;
 }
 
-vlc_va_surface_t *va_pool_Get(vlc_va_t *va, va_pool_t *va_pool)
+int va_pool_Get(vlc_va_t *va, picture_t *pic, va_pool_t *va_pool)
 {
     unsigned tries = (CLOCK_FREQ + VOUT_OUTMEM_SLEEP) / VOUT_OUTMEM_SLEEP;
-    vlc_va_surface_t *field;
+    picture_context_t *field;
 
-    while ((field = GetSurface(va_pool)) == NULL)
+    while ((field = GetSurface(va, va_pool)) == NULL)
     {
         if (--tries == 0)
-            return NULL;
+            return VLC_ENOITEM;
         /* Pool empty. Wait for some time as in src/input/decoder.c.
          * XXX: Both this and the core should use a semaphore or a CV. */
         msleep(VOUT_OUTMEM_SLEEP);
     }
-    return field;
+    pic->context = field;
+    return VLC_SUCCESS;
 }
 
 void va_surface_AddRef(vlc_va_surface_t *surface)
@@ -163,8 +169,7 @@ void va_pool_Close(vlc_va_t *va, va_pool_t *va_pool)
     va_pool->pf_destroy_device(va);
 }
 
-int va_pool_Open(vlc_va_t *va, va_pool_t *va_pool,
-                    AVCodecContext *ctx, const es_format_t *fmt)
+int va_pool_Open(vlc_va_t *va, va_pool_t *va_pool, AVCodecContext *ctx)
 {
     va_pool->codec_id = ctx->codec_id;
 
diff --git a/modules/codec/avcodec/va_surface_internal.h b/modules/codec/avcodec/va_surface_internal.h
index 169c227477..b1c3e92c71 100644
--- a/modules/codec/avcodec/va_surface_internal.h
+++ b/modules/codec/avcodec/va_surface_internal.h
@@ -74,12 +74,17 @@ typedef struct
      */
     void (*pf_setup_avcodec_ctx)(vlc_va_t *);
 
+    /**
+     * Create a new context for the surface being acquired
+     */
+    picture_context_t* (*pf_new_surface_context)(vlc_va_t *, vlc_va_surface_t *, D3D_DecoderSurface *);
+
 } va_pool_t;
 
-int va_pool_Open(vlc_va_t *, va_pool_t *, AVCodecContext *, const es_format_t *);
+int va_pool_Open(vlc_va_t *, va_pool_t *, AVCodecContext *);
 void va_pool_Close(vlc_va_t *va, va_pool_t *);
 int va_pool_Setup(vlc_va_t *, va_pool_t *, AVCodecContext *, int count, int alignment);
-vlc_va_surface_t *va_pool_Get(vlc_va_t *, va_pool_t *);
+int va_pool_Get(vlc_va_t *, picture_t *, va_pool_t *);
 void va_surface_AddRef(vlc_va_surface_t *surface);
 void va_surface_Release(vlc_va_surface_t *surface);
 
-- 
2.12.1



More information about the vlc-devel mailing list