[vlc-devel] [PATCH 24/31] decoder: provide the vlc_decoder_device from the vout thread to the VA constructor

Steve Lhomme robux4 at ycbcr.xyz
Fri Jul 5 16:20:03 CEST 2019


This can be used to initialize the VA instead of the picture_sys_t from the
external decoder pool.
---
 modules/codec/avcodec/d3d11va.c | 32 +++++++++++++++++++-------------
 modules/codec/avcodec/dxva2.c   | 27 ++++++++++++++-------------
 modules/codec/avcodec/va.c      |  9 ++++++---
 modules/codec/avcodec/va.h      |  2 ++
 modules/codec/avcodec/vaapi.c   |  2 +-
 modules/codec/avcodec/video.c   |  1 +
 modules/hw/vdpau/avcodec.c      |  2 +-
 7 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index 91df7bc397..c18bd23983 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -59,7 +59,7 @@ typedef picture_sys_d3d11_t VA_PICSYS;
 #include "directx_va.h"
 
 static int Open(vlc_va_t *, AVCodecContext *, enum PixelFormat,
-                const es_format_t *, picture_sys_d3d11_t *p_sys);
+                const es_format_t *, vlc_decoder_device *, picture_sys_d3d11_t *p_sys);
 static void Close(vlc_va_t *, void **);
 
 vlc_module_begin()
@@ -310,7 +310,7 @@ static void Close(vlc_va_t *va, void **ctx)
 }
 
 static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
-                const es_format_t *fmt, picture_sys_d3d11_t *p_sys)
+                const es_format_t *fmt, vlc_decoder_device *dec_device, picture_sys_d3d11_t *p_sys)
 {
     int err = VLC_EGENERIC;
     directx_sys_t *dx_sys;
@@ -358,8 +358,10 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
 
     sys->d3d_dev.d3ddevice = NULL;
     va->sys->render = DXGI_FORMAT_UNKNOWN;
-    if ( p_sys != NULL && p_sys->context != NULL ) {
-        HRESULT hr = D3D11_CreateDeviceExternal(va, p_sys->context, true, &sys->d3d_dev);
+    d3d11_decoder_device_t *d3d11_device = GetD3D11OpaqueDevice( dec_device );
+    if ( d3d11_device != NULL )
+    {
+        HRESULT hr = D3D11_CreateDeviceExternal(va, d3d11_device->device, true, &sys->d3d_dev);
         if (FAILED(hr))
             msg_Err(va, "can't use the provided D3D11 context");
         else
@@ -367,22 +369,26 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
             if (sys->d3d_dev.context_mutex == INVALID_HANDLE_VALUE)
                 msg_Warn(va, "No mutex found to lock the decoder");
             void *d3dvidctx = NULL;
-            hr = ID3D11DeviceContext_QueryInterface(p_sys->context, &IID_ID3D11VideoContext, &d3dvidctx);
+            hr = ID3D11DeviceContext_QueryInterface(sys->d3d_dev.d3dcontext, &IID_ID3D11VideoContext, &d3dvidctx);
             if (FAILED(hr)) {
                msg_Err(va, "Could not Query ID3D11VideoContext Interface from the picture. (hr=0x%lX)", hr);
                D3D11_ReleaseDevice(&sys->d3d_dev);
             } else {
                 sys->d3dvidctx = d3dvidctx;
 
-                assert(p_sys->texture[KNOWN_DXGI_INDEX] != NULL);
-                D3D11_TEXTURE2D_DESC dstDesc;
-                ID3D11Texture2D_GetDesc( p_sys->texture[KNOWN_DXGI_INDEX], &dstDesc);
-                sys->render = dstDesc.Format;
-                if (dstDesc.BindFlags & D3D11_BIND_DECODER)
+                if (p_sys != NULL)
                 {
-                    va->sys->textureWidth = dstDesc.Width;
-                    va->sys->textureHeight = dstDesc.Height;
-                    va->sys->totalTextureSlices = dstDesc.ArraySize;
+                    /* TODO this will go away in push, we decide the decoding format */
+                    assert(p_sys->texture[KNOWN_DXGI_INDEX] != NULL);
+                    D3D11_TEXTURE2D_DESC dstDesc;
+                    ID3D11Texture2D_GetDesc( p_sys->texture[KNOWN_DXGI_INDEX], &dstDesc);
+                    sys->render = dstDesc.Format;
+                    if (dstDesc.BindFlags & D3D11_BIND_DECODER)
+                    {
+                        va->sys->textureWidth = dstDesc.Width;
+                        va->sys->textureHeight = dstDesc.Height;
+                        va->sys->totalTextureSlices = dstDesc.ArraySize;
+                    }
                 }
             }
         }
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 9796823945..a94ca6eaca 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -31,6 +31,7 @@
 #include <vlc_common.h>
 #include <vlc_picture.h>
 #include <vlc_plugin.h>
+#include <vlc_codec.h>
 
 #define DXVA2API_USE_BITFIELDS
 #define COBJMACROS
@@ -46,7 +47,7 @@ typedef picture_sys_d3d9_t VA_PICSYS;
 #include "directx_va.h"
 
 static int Open(vlc_va_t *, AVCodecContext *, enum PixelFormat,
-                const es_format_t *, picture_sys_d3d9_t *p_sys);
+                const es_format_t *, vlc_decoder_device *, picture_sys_d3d9_t *p_sys);
 static void Close(vlc_va_t *, void **);
 
 vlc_module_begin()
@@ -255,7 +256,7 @@ static void Close(vlc_va_t *va, void **ctx)
 }
 
 static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
-                const es_format_t *fmt, picture_sys_d3d9_t *p_sys)
+                const es_format_t *fmt, vlc_decoder_device *dec_device, picture_sys_d3d9_t *p_sys)
 {
     int err = VLC_EGENERIC;
     directx_sys_t *dx_sys;
@@ -269,24 +270,24 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
     if (unlikely(sys == NULL))
         return VLC_ENOMEM;
     /* Load dll*/
-    if (p_sys!=NULL && p_sys->surface!=NULL)
+    d3d9_decoder_device_t *d3d9_decoder = GetD3D9OpaqueDevice( dec_device );
+    if ( d3d9_decoder != NULL )
     {
-        IDirect3DDevice9 *device;
-        if ( FAILED(IDirect3DSurface9_GetDevice( p_sys->surface, &device )) )
+        D3D9_CloneExternal(&sys->hd3d, d3d9_decoder->device);
+        HRESULT hr = D3D9_CreateDevice(va, &sys->hd3d, d3d9_decoder->adapter, &sys->d3d_dev);
+        if ( FAILED(hr) )
         {
+            D3D9_Destroy(&sys->hd3d);
             free( sys );
             goto error;
         }
-        if ( D3D9_CreateExternal(&sys->hd3d, device) != VLC_SUCCESS ||
-             FAILED(D3D9_CreateDeviceExternal( device, &sys->hd3d, &sys->d3d_dev)) )
+        if (p_sys != NULL)
         {
-            IDirect3DDevice9_Release(device);
-            free( sys );
-            goto error;
+            /* TODO this will go away in push, we decide the decoding format */
+            D3DSURFACE_DESC src;
+            if (SUCCEEDED(IDirect3DSurface9_GetDesc(p_sys->surface, &src)))
+                sys->render = src.Format;
         }
-        D3DSURFACE_DESC src;
-        if (SUCCEEDED(IDirect3DSurface9_GetDesc(p_sys->surface, &src)))
-            sys->render = src.Format;
     }
     else if (D3D9_Create(va, &sys->hd3d) != VLC_SUCCESS) {
         msg_Warn(va, "cannot load d3d9.dll");
diff --git a/modules/codec/avcodec/va.c b/modules/codec/avcodec/va.c
index fe9884c714..f0d2005cbf 100644
--- a/modules/codec/avcodec/va.c
+++ b/modules/codec/avcodec/va.c
@@ -26,6 +26,7 @@
 #include <vlc_common.h>
 #include <vlc_modules.h>
 #include <vlc_fourcc.h>
+#include <vlc_codec.h>
 #include <libavutil/pixfmt.h>
 #include <libavcodec/avcodec.h>
 #include "va.h"
@@ -94,12 +95,13 @@ static int vlc_va_Start(void *func, bool forced, va_list ap)
     AVCodecContext *ctx = va_arg(ap, AVCodecContext *);
     enum PixelFormat pix_fmt = va_arg(ap, enum PixelFormat);
     const es_format_t *fmt = va_arg(ap, const es_format_t *);
+    vlc_decoder_device *device = va_arg(ap, vlc_decoder_device *);
     void *p_sys = va_arg(ap, void *);
     int (*open)(vlc_va_t *, AVCodecContext *, enum PixelFormat,
-                const es_format_t *, void *) = func;
+                const es_format_t *, vlc_decoder_device *, void *) = func;
 
     (void) forced;
-    return open(va, ctx, pix_fmt, fmt, p_sys);
+    return open(va, ctx, pix_fmt, fmt, device, p_sys);
 }
 
 static void vlc_va_Stop(void *func, va_list ap)
@@ -118,6 +120,7 @@ struct vlc_va_priv {
 
 vlc_va_t *vlc_va_New(vlc_object_t *obj, AVCodecContext *avctx,
                      enum PixelFormat pix_fmt, const es_format_t *fmt,
+                     vlc_decoder_device *device,
                      void *sys)
 {
     struct vlc_va_priv *priv = vlc_object_create(obj, sizeof (*priv));
@@ -128,7 +131,7 @@ vlc_va_t *vlc_va_New(vlc_object_t *obj, AVCodecContext *avctx,
     char *modlist = var_InheritString(obj, "avcodec-hw");
 
     priv->module = vlc_module_load(va, "hw decoder", modlist, true,
-                                   vlc_va_Start, va, avctx, pix_fmt, fmt, sys);
+                                   vlc_va_Start, va, avctx, pix_fmt, fmt, device, sys);
     free(modlist);
     if (priv->module == NULL)
     {
diff --git a/modules/codec/avcodec/va.h b/modules/codec/avcodec/va.h
index 97df858389..6b9d99d818 100644
--- a/modules/codec/avcodec/va.h
+++ b/modules/codec/avcodec/va.h
@@ -48,10 +48,12 @@ vlc_fourcc_t vlc_va_GetChroma(enum PixelFormat hwfmt, enum PixelFormat swfmt);
  * Creates an accelerated video decoding back-end for libavcodec.
  * @param obj parent VLC object
  * @param fmt VLC format of the content to decode
+ * @param device use to create the decoder context
  * @return a new VLC object on success, NULL on error.
  */
 vlc_va_t *vlc_va_New(vlc_object_t *obj, AVCodecContext *,
                      enum PixelFormat, const es_format_t *fmt,
+                     vlc_decoder_device *device,
                      void *p_sys);
 
 /**
diff --git a/modules/codec/avcodec/vaapi.c b/modules/codec/avcodec/vaapi.c
index 54e8f16cb2..da90ddd1ab 100644
--- a/modules/codec/avcodec/vaapi.c
+++ b/modules/codec/avcodec/vaapi.c
@@ -146,7 +146,7 @@ static void Delete(vlc_va_t *va, void *hwctx)
 }
 
 static int Create(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
-                  const es_format_t *fmt, void *p_sys)
+                  const es_format_t *fmt, vlc_decoder_device *device, void *p_sys)
 {
     if (pix_fmt != AV_PIX_FMT_VAAPI_VLD || p_sys == NULL)
         return VLC_EGENERIC;
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 0829bfc6ee..a2d7755c1e 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -1738,6 +1738,7 @@ no_reuse:
         assert(!test_pic || test_pic->format.i_chroma == p_dec->fmt_out.video.i_chroma);
         vlc_va_t *va = vlc_va_New(VLC_OBJECT(p_dec), p_context, hwfmt,
                                   &p_dec->fmt_in,
+                                  p_dec->init_device,
                                   test_pic ? test_pic->p_sys : NULL);
         if (test_pic)
             picture_Release(test_pic);
diff --git a/modules/hw/vdpau/avcodec.c b/modules/hw/vdpau/avcodec.c
index 3576b003ca..2f9df8fd4d 100644
--- a/modules/hw/vdpau/avcodec.c
+++ b/modules/hw/vdpau/avcodec.c
@@ -118,7 +118,7 @@ static int Lock(vlc_va_t *va, picture_t *pic, uint8_t **data)
 }
 
 static int Open(vlc_va_t *va, AVCodecContext *avctx, enum PixelFormat pix_fmt,
-                const es_format_t *fmt, void *p_sys)
+                const es_format_t *fmt, vlc_decoder_device *device, void *p_sys)
 {
     if (pix_fmt != AV_PIX_FMT_VDPAU)
         return VLC_EGENERIC;
-- 
2.17.1



More information about the vlc-devel mailing list