[vlc-devel] [PATCH 3/4] [RFC] direct3d9: add a way to (re)store the device in the global context

Steve Lhomme robux4 at videolabs.io
Mon Nov 20 09:54:39 CET 2017


--
replaces https://patches.videolan.org/patch/18703/
- if there was already a value set it's now used, before it would just
  assert or overwrite the old value

It's not fully thread safe, if 2 threads call var_CreateGetAddress at the
same time they will both return NULL even though one of them created the
variable. They will both write their own value. We could live with that
for 3.0 as it's an edge case for an edge case.
---
 modules/codec/avcodec/dxva2.c          |  2 +-
 modules/video_chroma/d3d9_fmt.c        | 27 ++++++++++++++++++++++++++-
 modules/video_chroma/d3d9_fmt.h        |  7 ++++++-
 modules/video_output/win32/direct3d9.c |  6 +++---
 4 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index f6ecc020e7..a394b38730 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -355,7 +355,7 @@ static int D3dCreateDevice(vlc_va_t *va)
 static void D3dDestroyDevice(vlc_va_t *va)
 {
     vlc_va_sys_t *sys = va->sys;
-    D3D9_ReleaseDevice(&sys->d3d_dev);
+    D3D9_ReleaseDevice(va, &sys->d3d_dev);
     D3D9_Destroy( &sys->hd3d );
 }
 /**
diff --git a/modules/video_chroma/d3d9_fmt.c b/modules/video_chroma/d3d9_fmt.c
index 6d82b9ba17..7323cf5b96 100644
--- a/modules/video_chroma/d3d9_fmt.c
+++ b/modules/video_chroma/d3d9_fmt.c
@@ -29,6 +29,8 @@
 
 #include "../codec/avcodec/va_surface.h"
 
+#define D3D9_GLOBAL_DEVICE_NAME  "_d3d9-device"
+
 picture_sys_t *ActivePictureSys(picture_t *p_pic)
 {
     struct va_pic_context *pic_ctx = (struct va_pic_context*)p_pic->context;
@@ -125,19 +127,42 @@ HRESULT D3D9_CreateDevice(vlc_object_t *o, d3d9_handle_t *hd3d, HWND hwnd,
     if (SUCCEEDED(hr))
     {
         out->owner = true;
+        void *old = var_CreateGetAddress(o->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME);
+        if (likely(old==NULL))
+            var_SetAddress(o->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME, out->dev);
+        else
+        {
+            /* there was already one, use this one */
+            /* var_Create increases the internal usage counter so we will need a
+             * var_Destroy too */
+            IDirect3DDevice9_Release(out->dev);
+
+            out->dev = old;
+            IDirect3DDevice9_AddRef(out->dev);
+        }
     }
     return hr;
 }
 
-void D3D9_ReleaseDevice(d3d9_device_t *d3d_dev)
+#undef D3D9_ReleaseDevice
+void D3D9_ReleaseDevice(vlc_object_t *o, d3d9_device_t *d3d_dev)
 {
     if (d3d_dev->dev)
     {
        IDirect3DDevice9_Release(d3d_dev->dev);
        d3d_dev->dev = NULL;
     }
+    if (d3d_dev->owner)
+        var_Destroy(o->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME);
 }
 
+#undef D3D9_GetDevice
+LPDIRECT3DDEVICE9 D3D9_GetDevice(vlc_object_t *obj)
+{
+    return var_InheritAddress(obj, D3D9_GLOBAL_DEVICE_NAME);
+}
+
+
 /**
  * It setup vout_display_sys_t::d3dpp and vout_display_sys_t::rect_display
  * from the default adapter.
diff --git a/modules/video_chroma/d3d9_fmt.h b/modules/video_chroma/d3d9_fmt.h
index 61f043b94b..24f230cba5 100644
--- a/modules/video_chroma/d3d9_fmt.h
+++ b/modules/video_chroma/d3d9_fmt.h
@@ -78,7 +78,12 @@ HRESULT D3D9_CreateDevice(vlc_object_t *, d3d9_handle_t *, HWND,
                           const video_format_t *, d3d9_device_t *out);
 #define D3D9_CreateDevice(a,b,c,d,e) D3D9_CreateDevice( VLC_OBJECT(a), b, c, d, e )
 
-void D3D9_ReleaseDevice(d3d9_device_t *);
+void D3D9_ReleaseDevice(vlc_object_t *, d3d9_device_t *d3d9);
+#define D3D9_ReleaseDevice(a,b)  D3D9_ReleaseDevice( VLC_OBJECT(a), b )
+
+LPDIRECT3DDEVICE9 D3D9_GetDevice(vlc_object_t *);
+#define D3D9_GetDevice(a) D3D9_GetDevice( VLC_OBJECT(a) )
+
 int D3D9_Create(vlc_object_t *, d3d9_handle_t *);
 #define D3D9_Create(a,b) D3D9_Create( VLC_OBJECT(a), b )
 
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index 011100f6b8..4d4b5659d7 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -794,7 +794,7 @@ static int Direct3D9Open(vout_display_t *vd, video_format_t *fmt)
     return VLC_SUCCESS;
 
 error:
-    D3D9_ReleaseDevice(&sys->d3d_dev);
+    D3D9_ReleaseDevice( vd, &sys->d3d_dev );
     return VLC_EGENERIC;
 }
 
@@ -806,7 +806,7 @@ static void Direct3D9Close(vout_display_t *vd)
     vout_display_sys_t *sys = vd->sys;
 
     Direct3D9DestroyResources(vd);
-    D3D9_ReleaseDevice(&sys->d3d_dev);
+    D3D9_ReleaseDevice( vd, &sys->d3d_dev );
 }
 
 /**
@@ -1907,7 +1907,7 @@ GLConvClose(vlc_object_t *obj)
     if (priv->dx_render)
         IDirect3DSurface9_Release(priv->dx_render);
 
-    D3D9_ReleaseDevice(&priv->d3d_dev);
+    D3D9_ReleaseDevice( obj, &priv->d3d_dev );
     D3D9_Destroy(&priv->hd3d);
     free(tc->priv);
 }
-- 
2.14.2



More information about the vlc-devel mailing list