[vlc-devel] [PATCH 05/23] directx_va: pass the surface count to pf_create_decoder_surfaces

Steve Lhomme robux4 at videolabs.io
Wed Jun 21 14:14:50 CEST 2017


So it doesn't have to rely on the internal count in directx_sys_t
---
 modules/codec/avcodec/d3d11va.c    | 40 ++++++++++++++++++--------------------
 modules/codec/avcodec/directx_va.c | 20 ++++++++++---------
 modules/codec/avcodec/directx_va.h |  3 ++-
 modules/codec/avcodec/dxva2.c      | 25 +++++++++++-------------
 4 files changed, 43 insertions(+), 45 deletions(-)

diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index 4f903bf6f8..b3efb174fa 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -146,7 +146,8 @@ static void DxDestroyVideoService(vlc_va_t *);
 static int DxGetInputList(vlc_va_t *, input_list_t *);
 static int DxSetupOutput(vlc_va_t *, const GUID *, const video_format_t *);
 
-static int DxCreateDecoderSurfaces(vlc_va_t *, int codec_id, const video_format_t *fmt);
+static int DxCreateDecoderSurfaces(vlc_va_t *, int codec_id,
+                                   const video_format_t *fmt, unsigned surface_count);
 static void DxDestroySurfaces(vlc_va_t *);
 static void SetupAVCodecContext(vlc_va_t *);
 
@@ -742,7 +743,8 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
 /**
  * It creates a Direct3D11 decoder using the given video format
  */
-static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_format_t *fmt)
+static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
+                                   const video_format_t *fmt, unsigned surface_count)
 {
     vlc_va_sys_t *sys = va->sys;
     directx_sys_t *dx_sys = &va->sys->dx_sys;
@@ -763,7 +765,6 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
         isXboxHardware(dx_sys->d3ddev))
     {
         msg_Warn(va, "%dx%d resolution not supported by your hardware", dx_sys->surface_width, dx_sys->surface_height);
-        dx_sys->surface_count = 0;
         return VLC_EGENERIC;
     }
 #endif
@@ -792,27 +793,25 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
 
     if (sys->b_extern_pool)
     {
-#if D3D11_DIRECT_DECODE
-        dx_sys->surface_count = 0;
-#else
+#if !D3D11_DIRECT_DECODE
         size_t surface_idx;
-        for (surface_idx = 0; surface_idx < dx_sys->surface_count; surface_idx++) {
+        for (surface_idx = 0; surface_idx < surface_count; surface_idx++) {
             picture_t *pic = decoder_NewPicture( (decoder_t*) va->obj.parent );
             sys->extern_pics[surface_idx] = pic;
             dx_sys->hw_surface[surface_idx] = NULL;
             if (pic==NULL)
             {
-                msg_Warn(va, "not enough decoder pictures %d out of %d", surface_idx, dx_sys->surface_count);
+                msg_Warn(va, "not enough decoder pictures %d out of %d", surface_idx, surface_count);
                 sys->b_extern_pool = false;
                 break;
             }
 
             D3D11_TEXTURE2D_DESC texDesc;
             ID3D11Texture2D_GetDesc(pic->p_sys->texture[KNOWN_DXGI_INDEX], &texDesc);
-            if (texDesc.ArraySize < dx_sys->surface_count)
+            if (texDesc.ArraySize < surface_count)
             {
                 msg_Warn(va, "not enough decoding slices in the texture (%d/%d)",
-                         texDesc.ArraySize, dx_sys->surface_count);
+                         texDesc.ArraySize, surface_count);
                 sys->b_extern_pool = false;
                 break;
             }
@@ -877,7 +876,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
         texDesc.Format = sys->render;
         texDesc.SampleDesc.Count = 1;
         texDesc.MiscFlags = 0;
-        texDesc.ArraySize = dx_sys->surface_count;
+        texDesc.ArraySize = surface_count;
         texDesc.Usage = D3D11_USAGE_DEFAULT;
         texDesc.BindFlags = D3D11_BIND_DECODER;
         texDesc.CPUAccessFlags = 0;
@@ -888,22 +887,21 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
         ID3D11Texture2D *p_texture;
         hr = ID3D11Device_CreateTexture2D( dx_sys->d3ddev, &texDesc, NULL, &p_texture );
         if (FAILED(hr)) {
-            msg_Err(va, "CreateTexture2D %d failed. (hr=0x%0lx)", dx_sys->surface_count, hr);
-            dx_sys->surface_count = 0;
+            msg_Err(va, "CreateTexture2D %d failed. (hr=0x%0lx)", surface_count, hr);
             return VLC_EGENERIC;
         }
 
-        unsigned surface_count = dx_sys->surface_count;
-        for (dx_sys->surface_count = 0; dx_sys->surface_count < surface_count; dx_sys->surface_count++) {
-            sys->extern_pics[dx_sys->surface_count] = NULL;
-            viewDesc.Texture2D.ArraySlice = dx_sys->surface_count;
+        unsigned i;
+        for (i = 0; i < surface_count; i++) {
+            sys->extern_pics[i] = NULL;
+            viewDesc.Texture2D.ArraySlice = i;
 
             hr = ID3D11VideoDevice_CreateVideoDecoderOutputView( dx_sys->d3ddec,
                                                                  (ID3D11Resource*) p_texture,
                                                                  &viewDesc,
-                                                                 &dx_sys->hw_surface[dx_sys->surface_count] );
+                                                                 &dx_sys->hw_surface[i] );
             if (FAILED(hr)) {
-                msg_Err(va, "CreateVideoDecoderOutputView %d failed. (hr=0x%0lx)", dx_sys->surface_count, hr);
+                msg_Err(va, "CreateVideoDecoderOutputView %d failed. (hr=0x%0lx)", i, hr);
                 ID3D11Texture2D_Release(p_texture);
                 return VLC_EGENERIC;
             }
@@ -911,12 +909,12 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
             if (texDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE)
             {
                 ID3D11Texture2D *textures[D3D11_MAX_SHADER_VIEW] = {p_texture, p_texture};
-                AllocateShaderView(VLC_OBJECT(va), dx_sys->d3ddev, textureFmt, textures, dx_sys->surface_count, &sys->resourceView[dx_sys->surface_count * D3D11_MAX_SHADER_VIEW]);
+                AllocateShaderView(VLC_OBJECT(va), dx_sys->d3ddev, textureFmt, textures, i, &sys->resourceView[i * D3D11_MAX_SHADER_VIEW]);
             }
         }
     }
     msg_Dbg(va, "ID3D11VideoDecoderOutputView succeed with %d surfaces (%dx%d)",
-            dx_sys->surface_count, dx_sys->surface_width, dx_sys->surface_height);
+            surface_count, dx_sys->surface_width, dx_sys->surface_height);
 
     D3D11_VIDEO_DECODER_DESC decoderDesc;
     ZeroMemory(&decoderDesc, sizeof(decoderDesc));
diff --git a/modules/codec/avcodec/directx_va.c b/modules/codec/avcodec/directx_va.c
index 5e4b849899..e7ca04cfc8 100644
--- a/modules/codec/avcodec/directx_va.c
+++ b/modules/codec/avcodec/directx_va.c
@@ -282,10 +282,12 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys, AVCodecContext *avctx)
 {
     int surface_alignment = 16;
     unsigned surface_count = 2;
+    unsigned i = dx_sys->surface_count;
+    int err = VLC_EGENERIC;
 
     if (dx_sys->width == avctx->coded_width && dx_sys->height == avctx->coded_height
      && dx_sys->decoder != NULL)
-        goto ok;
+        goto done;
 
     /* */
     DestroyVideoDecoder(va, dx_sys);
@@ -324,8 +326,6 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys, AVCodecContext *avctx)
     if (surface_count > MAX_SURFACE_COUNT)
         return VLC_EGENERIC;
 
-    dx_sys->surface_count = surface_count;
-
 #define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1))
     dx_sys->width  = avctx->coded_width;
     dx_sys->height = avctx->coded_height;
@@ -340,7 +340,7 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys, AVCodecContext *avctx)
     fmt.i_frame_rate = avctx->framerate.num;
     fmt.i_frame_rate_base = avctx->framerate.den;
 
-    if (dx_sys->pf_create_decoder_surfaces(va, dx_sys->codec_id, &fmt))
+    if (dx_sys->pf_create_decoder_surfaces(va, dx_sys->codec_id, &fmt, surface_count))
         return VLC_EGENERIC;
 
     if (avctx->coded_width != dx_sys->surface_width ||
@@ -349,21 +349,23 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys, AVCodecContext *avctx)
                   dx_sys->surface_width, dx_sys->surface_height,
                   avctx->coded_width, avctx->coded_height);
 
-    for (unsigned i = 0; i < dx_sys->surface_count; i++) {
+    for (i = 0; i < surface_count; i++) {
         vlc_va_surface_t *surface = malloc(sizeof(*surface));
         if (unlikely(surface==NULL))
         {
-            dx_sys->surface_count = i;
-            return VLC_ENOMEM;
+            err = VLC_ENOMEM;
+            goto done;
         }
         atomic_init(&surface->refcount, 1);
         dx_sys->surface[i] = surface;
     }
 
     dx_sys->pf_setup_avcodec_ctx(va);
+    err = VLC_SUCCESS;
 
-ok:
-    return VLC_SUCCESS;
+done:
+    dx_sys->surface_count = i;
+    return err;
 }
 
 void DestroyVideoDecoder(vlc_va_t *va, directx_sys_t *dx_sys)
diff --git a/modules/codec/avcodec/directx_va.h b/modules/codec/avcodec/directx_va.h
index 5596864482..d9e5bc15ce 100644
--- a/modules/codec/avcodec/directx_va.h
+++ b/modules/codec/avcodec/directx_va.h
@@ -111,7 +111,8 @@ typedef struct
      * Create the DirectX surfaces in hw_surface and the decoder in decoder
      */
     int (*pf_create_decoder_surfaces)(vlc_va_t *, int codec_id,
-                                      const video_format_t *fmt);
+                                      const video_format_t *fmt,
+                                      unsigned surface_count);
     /**
      * Destroy resources allocated with the surfaces and the associated decoder
      */
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 4632a7b03e..0ebe2df0b9 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -148,8 +148,8 @@ static void DxDestroyVideoService(vlc_va_t *);
 static int DxGetInputList(vlc_va_t *, input_list_t *);
 static int DxSetupOutput(vlc_va_t *, const GUID *, const video_format_t *);
 
-static int DxCreateVideoDecoder(vlc_va_t *,
-                                int codec_id, const video_format_t *);
+static int DxCreateVideoDecoder(vlc_va_t *, int codec_id,
+                                const video_format_t *, unsigned surface_count);
 static void DxDestroyVideoDecoder(vlc_va_t *);
 static int DxResetVideoDecoder(vlc_va_t *);
 static void SetupAVCodecContext(vlc_va_t *);
@@ -640,7 +640,8 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
 /**
  * It creates a DXVA2 decoder using the given video format
  */
-static int DxCreateVideoDecoder(vlc_va_t *va, int codec_id, const video_format_t *fmt)
+static int DxCreateVideoDecoder(vlc_va_t *va, int codec_id,
+                                const video_format_t *fmt, unsigned surface_count)
 {
     vlc_va_sys_t *p_sys = va->sys;
     directx_sys_t *sys = &va->sys->dx_sys;
@@ -649,7 +650,7 @@ static int DxCreateVideoDecoder(vlc_va_t *va, int codec_id, const video_format_t
     hr = IDirectXVideoDecoderService_CreateSurface(sys->d3ddec,
                                                          sys->surface_width,
                                                          sys->surface_height,
-                                                         sys->surface_count - 1,
+                                                         surface_count - 1,
                                                          p_sys->render,
                                                          D3DPOOL_DEFAULT,
                                                          0,
@@ -657,12 +658,11 @@ static int DxCreateVideoDecoder(vlc_va_t *va, int codec_id, const video_format_t
                                                          sys->hw_surface,
                                                          NULL);
     if (FAILED(hr)) {
-        msg_Err(va, "IDirectXVideoAccelerationService_CreateSurface %d failed (hr=0x%0lx)", sys->surface_count - 1, hr);
-        sys->surface_count = 0;
+        msg_Err(va, "IDirectXVideoAccelerationService_CreateSurface %d failed (hr=0x%0lx)", surface_count - 1, hr);
         return VLC_EGENERIC;
     }
     msg_Dbg(va, "IDirectXVideoAccelerationService_CreateSurface succeed with %d surfaces (%dx%d)",
-            sys->surface_count, sys->surface_width, sys->surface_height);
+            surface_count, sys->surface_width, sys->surface_height);
 
     IDirect3DSurface9 *tstCrash;
     hr = IDirectXVideoDecoderService_CreateSurface(sys->d3ddec,
@@ -677,9 +677,8 @@ static int DxCreateVideoDecoder(vlc_va_t *va, int codec_id, const video_format_t
                                                          NULL);
     if (FAILED(hr)) {
         msg_Err(va, "extra buffer impossible, avoid a crash (hr=0x%0lx)", hr);
-        for (unsigned i = 0; i < sys->surface_count; i++)
+        for (unsigned i = 0; i < surface_count; i++)
             IDirect3DSurface9_Release( sys->hw_surface[i] );
-        sys->surface_count = 0;
         return VLC_EGENERIC;
     }
     IDirect3DSurface9_Release(tstCrash);
@@ -721,9 +720,8 @@ static int DxCreateVideoDecoder(vlc_va_t *va, int codec_id, const video_format_t
                                                                     &cfg_count,
                                                                     &cfg_list))) {
         msg_Err(va, "IDirectXVideoDecoderService_GetDecoderConfigurations failed");
-        for (unsigned i = 0; i < sys->surface_count; i++)
+        for (unsigned i = 0; i < surface_count; i++)
             IDirect3DSurface9_Release( sys->hw_surface[i] );
-        sys->surface_count = 0;
         return VLC_EGENERIC;
     }
     msg_Dbg(va, "we got %d decoder configurations", cfg_count);
@@ -766,12 +764,11 @@ static int DxCreateVideoDecoder(vlc_va_t *va, int codec_id, const video_format_t
                                                               &dsc,
                                                               &p_sys->cfg,
                                                               sys->hw_surface,
-                                                              sys->surface_count,
+                                                              surface_count,
                                                               &decoder))) {
         msg_Err(va, "IDirectXVideoDecoderService_CreateVideoDecoder failed");
-        for (unsigned i = 0; i < sys->surface_count; i++)
+        for (unsigned i = 0; i < surface_count; i++)
             IDirect3DSurface9_Release( sys->hw_surface[i] );
-        sys->surface_count = 0;
         return VLC_EGENERIC;
     }
     sys->decoder = decoder;
-- 
2.12.1



More information about the vlc-devel mailing list