[vlc-devel] [PATCH 10/11] direct3d9: set the D3D9 Device in the instance so it can be reused

Steve Lhomme robux4 at videolabs.io
Thu Nov 16 11:38:56 CET 2017


So filters that don't have direct access to the vout pool can still use the same
D3D9 device.
Only one can be set at a time.
---
 modules/codec/avcodec/dxva2.c          | 11 +++++++++++
 modules/video_chroma/d3d9_fmt.h        |  3 +++
 modules/video_output/win32/direct3d9.c | 11 ++++++++++-
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 7bfe6a9273..93ea410f8f 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -123,6 +123,8 @@ struct vlc_va_sys_t
     IDirect3DDeviceManager9  *devmng;
     HANDLE                   device;
 
+    bool                     external_device;
+
     /* Video service */
     D3DFORMAT                    render;
 
@@ -299,6 +301,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
         if (SUCCEEDED(IDirect3DSurface9_GetDesc(p_sys->surface, &src)))
             sys->render = src.Format;
         IDirect3DSurface9_GetDevice(p_sys->surface, &dx_sys->d3ddev );
+        sys->external_device = true;
     }
 
     err = directx_va_Open(va, &sys->dx_sys, true);
@@ -388,6 +391,12 @@ static int D3dCreateDevice(vlc_va_t *va)
     }
     sys->dx_sys.d3ddev = d3ddev;
 
+    vlc_value_t v;
+    /* only one object is allowed to set the D3D9 context */
+    assert(var_GetChecked(va->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME, VLC_VAR_ADDRESS, &v) == VLC_ENOVAR);
+    var_Create(va->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME, VLC_VAR_ADDRESS);
+    var_SetAddress(va->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME, d3ddev);
+
     return VLC_SUCCESS;
 }
 
@@ -401,6 +410,8 @@ static void D3dDestroyDevice(vlc_va_t *va)
         IDirect3D9_Release(va->sys->d3dobj);
     if (dx_sys->d3ddev)
         IDirect3DDevice9_Release(dx_sys->d3ddev);
+    if (!va->sys->external_device)
+        var_Destroy(va->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME);
 }
 /**
  * It describes our Direct3D object
diff --git a/modules/video_chroma/d3d9_fmt.h b/modules/video_chroma/d3d9_fmt.h
index 840ecb56e8..6868f46dac 100644
--- a/modules/video_chroma/d3d9_fmt.h
+++ b/modules/video_chroma/d3d9_fmt.h
@@ -25,6 +25,9 @@
 
 #include <vlc_picture.h>
 
+/* this global value should go away when we have proper pools handling */
+#define D3D9_GLOBAL_DEVICE_NAME  "_d3d9-device"
+
 /* owned by the vout for VLC_CODEC_D3D9_OPAQUE */
 struct picture_sys_t
 {
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index bada359642..9e288f2733 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -937,7 +937,15 @@ static int Direct3D9CreateDevice(vlc_object_t *o, struct d3dctx *d3dctx, const v
                                      &d3dctx->pp, &d3dctx->dev);
     }
 
-    return FAILED(hr) ? VLC_EGENERIC : VLC_SUCCESS;
+    if (FAILED(hr))
+        return VLC_EGENERIC;
+
+    vlc_value_t v;
+    /* only one object is allowed to set the D3D9 context */
+    assert(var_GetChecked(o->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME, VLC_VAR_ADDRESS, &v) == VLC_ENOVAR);
+    var_Create(o->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME, VLC_VAR_ADDRESS);
+    var_SetAddress(o->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME, d3dctx->dev);
+    return VLC_SUCCESS;
 }
 
 static void Direct3D9DestroyDevice(vlc_object_t *o, struct d3dctx *d3dctx)
@@ -947,6 +955,7 @@ static void Direct3D9DestroyDevice(vlc_object_t *o, struct d3dctx *d3dctx)
     if (d3dctx->dev)
        IDirect3DDevice9_Release(d3dctx->dev);
     d3dctx->dev = NULL;
+    var_Destroy(o->obj.libvlc, D3D9_GLOBAL_DEVICE_NAME);
 }
 
 /**
-- 
2.14.2



More information about the vlc-devel mailing list