[vlc-commits] d3d9: share the full d3d9_handle_t in the decoder device

Steve Lhomme git at videolan.org
Thu Nov 21 13:51:16 CET 2019


vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Thu Nov 21 08:25:22 2019 +0100| [ea8773fe924a9f3725ea08a69b5c2105fceef877] | committer: Steve Lhomme

d3d9: share the full d3d9_handle_t in the decoder device

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ea8773fe924a9f3725ea08a69b5c2105fceef877
---

 modules/codec/avcodec/dxva2.c          | 14 +++-----
 modules/hw/d3d9/d3d9_device.c          | 13 +++----
 modules/video_chroma/d3d9_fmt.h        |  2 +-
 modules/video_output/win32/direct3d9.c | 63 ++++++++++++++++++++--------------
 4 files changed, 48 insertions(+), 44 deletions(-)

diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 3caa648a31..fa58161cab 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -113,7 +113,6 @@ static const d3d9_format_t *D3dFindFormat(D3DFORMAT format)
 struct vlc_va_sys_t
 {
     /* Direct3D */
-    d3d9_handle_t          hd3d;
     d3d9_device_t          d3d_dev;
 
     vlc_video_context      *vctx;
@@ -267,11 +266,9 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, const AVPixFmtDescriptor *des
     if (unlikely(sys == NULL))
         return VLC_ENOMEM;
 
-    D3D9_CloneExternal(&sys->hd3d, d3d9_decoder->device);
-    HRESULT hr = D3D9_CreateDevice(va, &sys->hd3d, d3d9_decoder->adapter, &sys->d3d_dev);
+    HRESULT hr = D3D9_CreateDevice(va, &d3d9_decoder->hd3d, d3d9_decoder->adapter, &sys->d3d_dev);
     if ( FAILED(hr) )
     {
-        D3D9_Destroy(&sys->hd3d);
         free( sys );
         return VLC_EGENERIC;
     }
@@ -281,7 +278,6 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, const AVPixFmtDescriptor *des
     if (likely(sys->vctx == NULL))
     {
         D3D9_ReleaseDevice(&sys->d3d_dev);
-        D3D9_Destroy(&sys->hd3d);
         free( sys );
         return VLC_EGENERIC;
     }
@@ -309,7 +305,6 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, const AVPixFmtDescriptor *des
         msg_Warn(va, "cannot load DXVA2 decoder DLL");
         if (sys->vctx)
             vlc_video_context_Release(sys->vctx);
-        D3D9_Destroy( &sys->hd3d );
         free( sys );
         return VLC_EGENERIC;
     }
@@ -344,7 +339,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, const AVPixFmtDescriptor *des
         goto error;
 
     D3DADAPTER_IDENTIFIER9 d3dai;
-    if (SUCCEEDED(IDirect3D9_GetAdapterIdentifier(sys->hd3d.obj,
+    if (SUCCEEDED(IDirect3D9_GetAdapterIdentifier(d3d9_decoder->hd3d.obj,
                                                sys->d3d_dev.adapterId, 0, &d3dai))) {
         msg_Info(va, "Using DXVA2 (%.*s, vendor %s(%lx), device %lx, revision %lx)",
                     (int)sizeof(d3dai.Description), d3dai.Description,
@@ -448,8 +443,10 @@ static int DxSetupOutput(vlc_va_t *va, const directx_va_mode_t *mode, const vide
     VLC_UNUSED(fmt);
     vlc_va_sys_t *sys = va->sys;
 
+    d3d9_decoder_device_t *d3d9_decoder = GetD3D9OpaqueContext(sys->vctx);
+
     D3DADAPTER_IDENTIFIER9 identifier;
-    HRESULT hr = IDirect3D9_GetAdapterIdentifier(sys->hd3d.obj, sys->d3d_dev.adapterId, 0, &identifier);
+    HRESULT hr = IDirect3D9_GetAdapterIdentifier(d3d9_decoder->hd3d.obj, sys->d3d_dev.adapterId, 0, &identifier);
     if (FAILED(hr))
         return VLC_EGENERIC;
 
@@ -666,7 +663,6 @@ static void DxDestroyVideoDecoder(void *opaque)
     IDirectXVideoDecoderService_Release(sys->d3ddec);
     IDirect3DDeviceManager9_Release(sys->devmng);
     D3D9_ReleaseDevice(&sys->d3d_dev);
-    D3D9_Destroy( &sys->hd3d );
     if (sys->dxva2_dll)
         FreeLibrary(sys->dxva2_dll);
 
diff --git a/modules/hw/d3d9/d3d9_device.c b/modules/hw/d3d9/d3d9_device.c
index cd5a2770fa..89bbce3984 100644
--- a/modules/hw/d3d9/d3d9_device.c
+++ b/modules/hw/d3d9/d3d9_device.c
@@ -43,7 +43,6 @@ typedef struct {
     void                                     *opaque;
     libvlc_video_direct3d_device_cleanup_cb  cleanupDeviceCb;
 
-    d3d9_handle_t                            hd3d;
     d3d9_decoder_device_t                    dec_device;
 } d3d9_decoder_device;
 
@@ -51,7 +50,7 @@ static void D3D9CloseDecoderDevice(vlc_decoder_device *device)
 {
     d3d9_decoder_device *sys = device->sys;
 
-    D3D9_Destroy( &sys->hd3d );
+    D3D9_Destroy( &sys->dec_device.hd3d );
 
     if ( sys->cleanupDeviceCb )
         sys->cleanupDeviceCb( sys->opaque );
@@ -86,13 +85,13 @@ int D3D9OpenDecoderDevice(vlc_decoder_device *device, vout_window_t *wnd)
             goto error;
         }
 
-        D3D9_CloneExternal( &sys->hd3d, (IDirect3D9*) out.device_context );
+        D3D9_CloneExternal( &sys->dec_device.hd3d, (IDirect3D9*) out.device_context );
         sys->dec_device.adapter = out.adapter;
     }
     else
     {
         /* internal rendering */
-        if (D3D9_Create(device, &sys->hd3d) != VLC_SUCCESS)
+        if (D3D9_Create(device, &sys->dec_device.hd3d) != VLC_SUCCESS)
         {
             msg_Err( device, "Direct3D9 could not be initialized" );
             goto error;
@@ -100,10 +99,10 @@ int D3D9OpenDecoderDevice(vlc_decoder_device *device, vout_window_t *wnd)
 
         d3d9_device_t tmp_d3ddev;
         /* find the best adapter to use, not based on the HWND used */
-        HRESULT hr = D3D9_CreateDevice( device, &sys->hd3d, -1, &tmp_d3ddev );
+        HRESULT hr = D3D9_CreateDevice( device, &sys->dec_device.hd3d, -1, &tmp_d3ddev );
         if ( FAILED(hr) )
         {
-            D3D9_Destroy( &sys->hd3d );
+            D3D9_Destroy( &sys->dec_device.hd3d );
             goto error;
         }
 
@@ -112,8 +111,6 @@ int D3D9OpenDecoderDevice(vlc_decoder_device *device, vout_window_t *wnd)
         D3D9_ReleaseDevice(&tmp_d3ddev);
     }
 
-    sys->dec_device.device = sys->hd3d.obj;
-
     device->ops = &d3d9_dev_ops;
     device->opaque = &sys->dec_device;
     device->type = VLC_DECODER_DEVICE_DXVA2;
diff --git a/modules/video_chroma/d3d9_fmt.h b/modules/video_chroma/d3d9_fmt.h
index a04f8956e3..bfcec0993f 100644
--- a/modules/video_chroma/d3d9_fmt.h
+++ b/modules/video_chroma/d3d9_fmt.h
@@ -72,7 +72,7 @@ typedef struct
 
 typedef struct
 {
-    IDirect3D9    *device;
+    d3d9_handle_t  hd3d;
     int            adapter;
 } d3d9_decoder_device_t;
 
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index b75ac2e323..e73eba54b0 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -145,7 +145,9 @@ struct vout_display_sys_t
     bool allow_hw_yuv;    /* Should we use hardware YUV->RGB conversions */
 
     // core objects
-    d3d9_handle_t           hd3d;
+    d3d9_decoder_device_t  *d3d9_device;
+    vlc_decoder_device     *dec_device; // if d3d9_decoder comes from a decoder device
+
     HINSTANCE               hxdll;      /* handle of the opened d3d9x dll */
     IDirect3DPixelShader9*  d3dx_shader;
     d3d9_device_t           d3d_dev;
@@ -896,7 +898,7 @@ static int Direct3D9CreateResources(vout_display_t *vd, const video_format_t *fm
     sys->d3dregion_format = D3DFMT_UNKNOWN;
     for (int i = 0; i < 2; i++) {
         D3DFORMAT dfmt = i == 0 ? D3DFMT_A8B8G8R8 : D3DFMT_A8R8G8B8;
-        if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(sys->hd3d.obj,
+        if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(sys->d3d9_device->hd3d.obj,
                                                    D3DADAPTER_DEFAULT,
                                                    D3DDEVTYPE_HAL,
                                                    sys->d3d_dev.BufferFormat,
@@ -935,7 +937,7 @@ static int Direct3D9Reset(vout_display_t *vd, const video_format_t *fmtp)
     d3d9_device_t *p_d3d9_dev = &sys->d3d_dev;
 
     D3DPRESENT_PARAMETERS d3dpp;
-    if (D3D9_FillPresentationParameters(&sys->hd3d, p_d3d9_dev, &d3dpp))
+    if (D3D9_FillPresentationParameters(&sys->d3d9_device->hd3d, p_d3d9_dev, &d3dpp))
     {
         msg_Err(vd, "Could not presentation parameters to reset device");
         return VLC_EGENERIC;
@@ -946,7 +948,7 @@ static int Direct3D9Reset(vout_display_t *vd, const video_format_t *fmtp)
 
     /* */
     HRESULT hr;
-    if (sys->hd3d.use_ex){
+    if (sys->d3d9_device->hd3d.use_ex){
         hr = IDirect3DDevice9Ex_ResetEx(p_d3d9_dev->devex, &d3dpp, NULL);
     } else {
         hr = IDirect3DDevice9_Reset(p_d3d9_dev->dev, &d3dpp);
@@ -1348,7 +1350,7 @@ static void Swap(vout_display_t *vd)
     };
 
     HRESULT hr;
-    if (sys->hd3d.use_ex) {
+    if (sys->d3d9_device->hd3d.use_ex) {
         hr = IDirect3DDevice9Ex_PresentEx(p_d3d9_dev->devex, &src, &src, sys->sys.hvideownd, NULL, 0);
     } else {
         hr = IDirect3DDevice9_Present(p_d3d9_dev->dev, &src, &src, sys->sys.hvideownd, NULL);
@@ -1373,8 +1375,10 @@ static void Display(vout_display_t *vd, picture_t *picture)
  */
 static void Direct3D9Destroy(vout_display_sys_t *sys)
 {
-    D3D9_Destroy( &sys->hd3d );
-
+    if (sys->dec_device)
+        vlc_decoder_device_Release(sys->dec_device);
+    else if (sys->d3d9_device)
+        free(sys->d3d9_device);
     if (sys->hxdll)
     {
         FreeLibrary(sys->hxdll);
@@ -1389,7 +1393,7 @@ static int Direct3D9CheckConversion(vout_display_t *vd,
                                    D3DFORMAT src, D3DFORMAT dst)
 {
     vout_display_sys_t *sys = vd->sys;
-    IDirect3D9 *d3dobj = sys->hd3d.obj;
+    IDirect3D9 *d3dobj = sys->d3d9_device->hd3d.obj;
     HRESULT hr;
 
     /* test whether device can create a surface of that format */
@@ -1651,28 +1655,38 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
         sys->startEndRenderingCb = NULL;
     }
 
-    d3d9_decoder_device_t *d3d9_decoder = GetD3D9OpaqueContext(context);
-    if ( d3d9_decoder == NULL )
+    sys->dec_device = context ? vlc_video_context_HoldDevice(context) : NULL;
+    sys->d3d9_device = GetD3D9OpaqueDevice(sys->dec_device);
+    if ( sys->d3d9_device == NULL )
     {
-        // No d3d9 device, we create one
-        if (D3D9_Create(vd, &sys->hd3d) != VLC_SUCCESS)
+        if (sys->dec_device)
+        {
+            vlc_decoder_device_Release(sys->dec_device);
+            sys->dec_device = NULL;
+        }
+        // No d3d9_decoder_device_t, create one
+        sys->d3d9_device = calloc(1, sizeof(*sys->d3d9_device));
+        if (unlikely(sys->d3d9_device == NULL))
+            goto error;
+        if (D3D9_Create(vd, &sys->d3d9_device->hd3d) != VLC_SUCCESS)
+        {
+            free(sys->d3d9_device);
+            sys->d3d9_device = NULL;
             goto error;
+        }
+        sys->d3d9_device->adapter = -1;
     }
-    if (d3d9_decoder != NULL && d3d9_decoder->device != NULL)
-        D3D9_CloneExternal( &sys->hd3d, d3d9_decoder->device );
 
     d3d9_video_context_t *octx = GetD3D9ContextPrivate(context);
     HRESULT hr;
     if (octx != NULL)
-        hr = D3D9_CreateDeviceExternal(octx->dev, &sys->hd3d, &sys->d3d_dev);
+        hr = D3D9_CreateDeviceExternal(octx->dev, &sys->d3d9_device->hd3d, &sys->d3d_dev);
     else
-        hr = D3D9_CreateDevice(vd, &sys->hd3d, d3d9_decoder ? d3d9_decoder->adapter : -1, &sys->d3d_dev);
+        hr = D3D9_CreateDevice(vd, &sys->d3d9_device->hd3d, sys->d3d9_device->adapter, &sys->d3d_dev);
 
     if (FAILED(hr)) {
         msg_Err( vd, "D3D9 Creation failed! (hr=0x%lX)", hr);
-        D3D9_Destroy(&sys->hd3d);
-        free(sys);
-        return VLC_EGENERIC;
+        goto error;
     }
 
     if ( vd->source.i_visible_width  > sys->d3d_dev.caps.MaxTextureWidth ||
@@ -1765,7 +1779,6 @@ struct wgl_vt {
 struct glpriv
 {
     struct wgl_vt vt;
-    d3d9_handle_t hd3d;
     d3d9_device_t d3d_dev;
     HANDLE gl_handle_d3d;
     HANDLE gl_render;
@@ -1872,7 +1885,6 @@ GLConvClose(vlc_object_t *obj)
         IDirect3DSurface9_Release(priv->dx_render);
 
     D3D9_ReleaseDevice(&priv->d3d_dev);
-    D3D9_Destroy(&priv->hd3d);
     free(tc->priv);
 }
 
@@ -1886,7 +1898,8 @@ GLConvOpen(vlc_object_t *obj)
         return VLC_EGENERIC;
 
     d3d9_video_context_t *vctx_sys = GetD3D9ContextPrivate( tc->vctx );
-    if ( vctx_sys == NULL )
+    d3d9_decoder_device_t *d3d9_decoder = GetD3D9OpaqueContext(tc->vctx);
+    if ( vctx_sys == NULL || d3d9_decoder == NULL )
         return VLC_EGENERIC;
 
     if (tc->gl->ext != VLC_GL_EXT_WGL || !tc->gl->wgl.getExtensionsString)
@@ -1920,16 +1933,14 @@ GLConvOpen(vlc_object_t *obj)
     tc->priv = priv;
     priv->vt = vt;
 
-    if (D3D9_Create(obj, &priv->hd3d) != VLC_SUCCESS)
-        goto error;
-    if (!priv->hd3d.use_ex)
+    if (!d3d9_decoder->hd3d.use_ex)
     {
         msg_Warn(obj, "DX/GL interrop only working on d3d9x");
         goto error;
     }
 
     HRESULT hr;
-    hr = D3D9_CreateDeviceExternal(vctx_sys->dev, &priv->hd3d, &priv->d3d_dev );
+    hr = D3D9_CreateDeviceExternal(vctx_sys->dev, &d3d9_decoder->hd3d, &priv->d3d_dev );
     if (FAILED(hr))
         goto error;
 



More information about the vlc-commits mailing list