[vlc-commits] direct3d9: move the external device handling in the common code

Steve Lhomme git at videolan.org
Wed Feb 12 17:09:14 CET 2020


vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Wed Feb 12 10:12:03 2020 +0100| [c0f1b31f950320dd6ca997d91d67c3a241806329] | committer: Steve Lhomme

direct3d9: move the external device handling in the common code

The D3D9 display module may be used without a decoder device (software decoding)
and we still need to use the device from the host app.

The allocated d3d9_decoder_device_t structure is freed with the object that
created it. But D3D9_ReleaseDevice() still need to be called.

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

 modules/hw/d3d9/d3d9_device.c          | 78 +++-----------------------------
 modules/video_chroma/d3d9_fmt.c        | 83 ++++++++++++++++++++++++++++------
 modules/video_chroma/d3d9_fmt.h        |  7 ++-
 modules/video_output/win32/direct3d9.c | 20 ++------
 4 files changed, 83 insertions(+), 105 deletions(-)

diff --git a/modules/hw/d3d9/d3d9_device.c b/modules/hw/d3d9/d3d9_device.c
index 06c78873b6..90cf50f362 100644
--- a/modules/hw/d3d9/d3d9_device.c
+++ b/modules/hw/d3d9/d3d9_device.c
@@ -31,31 +31,12 @@
 #include <vlc_common.h>
 #include <vlc_codec.h>
 
-#include <vlc/libvlc.h>
-#include <vlc/libvlc_picture.h>
-#include <vlc/libvlc_media.h>
-#include <vlc/libvlc_renderer_discoverer.h>
-#include <vlc/libvlc_media_player.h>
-
 #include "d3d9_filters.h"
 
-typedef struct {
-    void                            *opaque;
-    libvlc_video_output_cleanup_cb  cleanupDeviceCb;
-
-    d3d9_decoder_device_t                    dec_device;
-} d3d9_decoder_device;
-
 static void D3D9CloseDecoderDevice(vlc_decoder_device *device)
 {
-    d3d9_decoder_device *sys = device->sys;
-
-    D3D9_ReleaseDevice( &sys->dec_device.d3ddev );
-    D3D9_Destroy( &sys->dec_device.hd3d );
-
-    if ( sys->cleanupDeviceCb )
-        sys->cleanupDeviceCb( sys->opaque );
-    vlc_obj_free( VLC_OBJECT(device), sys );
+    d3d9_decoder_device_t *dec_device = device->opaque;
+    D3D9_ReleaseDevice( dec_device );
 }
 static const struct vlc_decoder_device_operations d3d9_dev_ops = {
     .close = D3D9CloseDecoderDevice,
@@ -64,60 +45,15 @@ static const struct vlc_decoder_device_operations d3d9_dev_ops = {
 int D3D9OpenDecoderDevice(vlc_decoder_device *device, vout_window_t *wnd)
 {
     VLC_UNUSED(wnd);
-    d3d9_decoder_device *sys = vlc_obj_malloc(VLC_OBJECT(device), sizeof(*sys));
-    if (unlikely(sys==NULL))
-        return VLC_ENOMEM;
-
-    int adapter;
-    sys->cleanupDeviceCb = NULL;
-    libvlc_video_output_setup_cb setupDeviceCb = var_InheritAddress( device, "vout-cb-setup" );
-    if ( setupDeviceCb )
-    {
-        /* external rendering */
-        libvlc_video_setup_device_info_t out = { .d3d9.adapter = 0 };
-        sys->opaque          = var_InheritAddress( device, "vout-cb-opaque" );
-        sys->cleanupDeviceCb = var_InheritAddress( device, "vout-cb-cleanup" );
-        libvlc_video_setup_device_cfg_t cfg = {
-            .hardware_decoding = true, /* ignored anyway */
-        };
-        if (!setupDeviceCb( &sys->opaque, &cfg, &out ))
-        {
-            if ( sys->cleanupDeviceCb )
-                sys->cleanupDeviceCb( sys->opaque );
-            goto error;
-        }
-
-        D3D9_CloneExternal( &sys->dec_device.hd3d, (IDirect3D9*) out.d3d9.device );
-        adapter = out.d3d9.adapter;
-    }
-    else
-    {
-        /* internal rendering */
-        if (D3D9_Create(device, &sys->dec_device.hd3d) != VLC_SUCCESS)
-        {
-            msg_Err( device, "Direct3D9 could not be initialized" );
-            goto error;
-        }
-        /* find the best adapter to use, not based on the HWND used */
-        adapter = -1;
-    }
 
-    HRESULT hr = D3D9_CreateDevice( device, &sys->dec_device.hd3d, adapter, &sys->dec_device.d3ddev );
-    if ( FAILED(hr) )
-    {
-        if ( sys->cleanupDeviceCb )
-            sys->cleanupDeviceCb( sys->opaque );
-        D3D9_Destroy( &sys->dec_device.hd3d );
-        goto error;
-    }
+    d3d9_decoder_device_t *dec_device = D3D9_CreateDevice( device );
+    if ( dec_device == NULL )
+        return VLC_EGENERIC;
 
     device->ops = &d3d9_dev_ops;
-    device->opaque = &sys->dec_device;
+    device->opaque = dec_device;
     device->type = VLC_DECODER_DEVICE_DXVA2;
-    device->sys = sys;
+    device->sys = NULL;
 
     return VLC_SUCCESS;
-error:
-    vlc_obj_free( VLC_OBJECT(device), sys );
-    return VLC_EGENERIC;
 }
diff --git a/modules/video_chroma/d3d9_fmt.c b/modules/video_chroma/d3d9_fmt.c
index 421d1a75f6..66c753e308 100644
--- a/modules/video_chroma/d3d9_fmt.c
+++ b/modules/video_chroma/d3d9_fmt.c
@@ -25,6 +25,12 @@
 
 #include <assert.h>
 
+#include <vlc/libvlc.h>
+#include <vlc/libvlc_picture.h>
+#include <vlc/libvlc_media.h>
+#include <vlc/libvlc_renderer_discoverer.h>
+#include <vlc/libvlc_media_player.h>
+
 #include <initguid.h>
 #include "d3d9_fmt.h"
 
@@ -39,13 +45,56 @@ picture_sys_d3d9_t *ActiveD3D9PictureSys(picture_t *pic)
     return &pic_ctx->picsys;
 }
 
-#undef D3D9_CreateDevice
-HRESULT D3D9_CreateDevice(vlc_object_t *o, d3d9_handle_t *hd3d, int AdapterToUse,
-                          d3d9_device_t *out)
+typedef struct {
+    void                            *opaque;
+    libvlc_video_output_cleanup_cb  cleanupDeviceCb;
+
+    d3d9_decoder_device_t           dec_device;
+} d3d9_decoder_device;
+
+d3d9_decoder_device_t *(D3D9_CreateDevice)(vlc_object_t *o)
 {
     HRESULT hr;
     D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL;
 
+    d3d9_decoder_device *sys = vlc_obj_malloc(o, sizeof(*sys));
+    if (unlikely(sys==NULL))
+        return NULL;
+
+d3d9_device_t *out = &sys->dec_device.d3ddev;
+d3d9_handle_t *hd3d = &sys->dec_device.hd3d;
+
+    int AdapterToUse;
+
+    sys->cleanupDeviceCb = NULL;
+    libvlc_video_output_setup_cb setupDeviceCb = var_InheritAddress( o, "vout-cb-setup" );
+    if ( setupDeviceCb )
+    {
+        /* external rendering */
+        libvlc_video_setup_device_info_t extern_out = { .d3d9.adapter = -1 };
+        sys->opaque          = var_InheritAddress( o, "vout-cb-opaque" );
+        sys->cleanupDeviceCb = var_InheritAddress( o, "vout-cb-cleanup" );
+        libvlc_video_setup_device_cfg_t cfg = {
+            .hardware_decoding = true, /* ignored anyway */
+        };
+        if (!setupDeviceCb( &sys->opaque, &cfg, &extern_out ))
+            goto error;
+
+        D3D9_CloneExternal( hd3d, (IDirect3D9 *) extern_out.d3d9.device );
+        AdapterToUse = extern_out.d3d9.adapter;
+    }
+    else
+    {
+        /* internal rendering */
+        if (D3D9_Create(o, hd3d) != VLC_SUCCESS)
+        {
+            msg_Err( o, "Direct3D9 could not be initialized" );
+            goto error;
+        }
+        /* find the best adapter to use, not based on the HWND used */
+        AdapterToUse = -1;
+    }
+
     if (AdapterToUse == -1)
     {
         AdapterToUse = D3DADAPTER_DEFAULT;
@@ -72,14 +121,14 @@ HRESULT D3D9_CreateDevice(vlc_object_t *o, d3d9_handle_t *hd3d, int AdapterToUse
     hr = IDirect3D9_GetDeviceCaps(hd3d->obj, AdapterToUse, DeviceType, &out->caps);
     if (FAILED(hr)) {
        msg_Err(o, "Could not read adapter capabilities. (hr=0x%lX)", hr);
-       return hr;
+       goto error;
     }
     msg_Dbg(o, "D3D9 device caps 0x%lX / 0x%lX", out->caps.DevCaps, out->caps.DevCaps2);
 
     /* TODO: need to test device capabilities and select the right render function */
     if (!(out->caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES)) {
         msg_Err(o, "Device does not support stretching from textures.");
-        return E_INVALIDARG;
+        goto error;
     }
 
     out->adapterId = AdapterToUse;
@@ -88,7 +137,7 @@ HRESULT D3D9_CreateDevice(vlc_object_t *o, d3d9_handle_t *hd3d, int AdapterToUse
     if (D3D9_FillPresentationParameters(hd3d, out, &d3dpp))
     {
         msg_Err(o, "Could not get presentation parameters");
-        return E_INVALIDARG;
+        goto error;
     }
 
     /* */
@@ -125,23 +174,29 @@ HRESULT D3D9_CreateDevice(vlc_object_t *o, d3d9_handle_t *hd3d, int AdapterToUse
             {
                 out->BufferFormat = d3dpp.BackBufferFormat;
                 out->owner = true;
-                return hr;
+                return &sys->dec_device;
             }
         }
     }
 
     msg_Err(o, "failed to create the D3D9%s device %d/%d. (hr=0x%lX)",
                hd3d->use_ex?"Ex":"", AdapterToUse, DeviceType, hr);
-    return hr;
+
+error:
+    if ( sys->cleanupDeviceCb )
+        sys->cleanupDeviceCb( sys->opaque );
+    vlc_obj_free( o, sys );
+    return NULL;
 }
 
-void D3D9_ReleaseDevice(d3d9_device_t *d3d_dev)
+void D3D9_ReleaseDevice(d3d9_decoder_device_t *dec_dev)
 {
-    if (d3d_dev->dev)
-    {
-       IDirect3DDevice9_Release(d3d_dev->dev);
-       d3d_dev->dev = NULL;
-    }
+    d3d9_decoder_device *sys = container_of(dec_dev, d3d9_decoder_device, dec_device);
+    if (dec_dev->d3ddev.dev)
+       IDirect3DDevice9_Release(dec_dev->d3ddev.dev);
+    D3D9_Destroy( &dec_dev->hd3d );
+    if ( sys->cleanupDeviceCb )
+        sys->cleanupDeviceCb( sys->opaque );
 }
 
 /**
diff --git a/modules/video_chroma/d3d9_fmt.h b/modules/video_chroma/d3d9_fmt.h
index 9647c9b623..cb87d0cde4 100644
--- a/modules/video_chroma/d3d9_fmt.h
+++ b/modules/video_chroma/d3d9_fmt.h
@@ -133,11 +133,10 @@ static inline void ReleaseD3D9PictureSys(picture_sys_d3d9_t *p_sys)
     IDirect3DSurface9_Release(p_sys->surface);
 }
 
-HRESULT D3D9_CreateDevice(vlc_object_t *, d3d9_handle_t *, int,
-                          d3d9_device_t *out);
-#define D3D9_CreateDevice(a,b,c,d) D3D9_CreateDevice( VLC_OBJECT(a), b, c, d )
+d3d9_decoder_device_t *D3D9_CreateDevice(vlc_object_t *);
+#define D3D9_CreateDevice(a) D3D9_CreateDevice( VLC_OBJECT(a) )
 
-void D3D9_ReleaseDevice(d3d9_device_t *);
+void D3D9_ReleaseDevice(d3d9_decoder_device_t *);
 int D3D9_Create(vlc_object_t *, d3d9_handle_t *);
 #define D3D9_Create(a,b) D3D9_Create( VLC_OBJECT(a), b )
 void D3D9_CloneExternal(d3d9_handle_t *, IDirect3D9 *);
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index db64693eb7..41295fea78 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -1289,8 +1289,7 @@ static void Direct3D9Destroy(vout_display_sys_t *sys)
         vlc_decoder_device_Release(sys->dec_device);
     else if (sys->d3d9_device)
     {
-        D3D9_ReleaseDevice(&sys->d3d9_device->d3ddev);
-        free(sys->d3d9_device);
+        D3D9_ReleaseDevice(sys->d3d9_device);
     }
     if (sys->hxdll)
     {
@@ -1575,21 +1574,10 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
             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;
-        }
 
-        HRESULT hr;
-        hr = D3D9_CreateDevice(vd, &sys->d3d9_device->hd3d, -1, &sys->d3d9_device->d3ddev);
-        if (FAILED(hr)) {
-            msg_Err( vd, "D3D9 Creation failed! (hr=0x%lX)", hr);
+        sys->d3d9_device = D3D9_CreateDevice( vd );
+        if (sys->d3d9_device == NULL) {
+            msg_Err( vd, "D3D9 Creation failed!" );
             goto error;
         }
     }



More information about the vlc-commits mailing list