[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