[vlc-devel] [PATCH 5/7] direct3d9: create a decoder device when the local swapchain is used
Steve Lhomme
robux4 at ycbcr.xyz
Wed Jun 26 15:49:02 CEST 2019
The display module always use the device from the vlc_video_context.
Use it in the OpenGL converter if possible.
---
modules/video_output/win32/direct3d9.c | 124 +++++++++++++++----------
1 file changed, 76 insertions(+), 48 deletions(-)
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index b0fe0343dd..bbbfcefad0 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -41,6 +41,7 @@
#include <vlc_common.h>
#include <vlc_plugin.h>
+#include <vlc_codec.h>
#include <vlc_vout_display.h>
#include <vlc/libvlc.h>
@@ -72,6 +73,9 @@ static int Open(vout_display_t *, const vout_display_cfg_t *,
video_format_t *, vlc_video_context *);
static void Close(vout_display_t *);
+static int OpenD3D9DecoderDevice(vlc_decoder_device *, vout_window_t *, vlc_fourcc_t);
+static void CloseD3D9DecoderDevice(vlc_decoder_device *);
+
static int GLConvOpen(vlc_object_t *);
static void GLConvClose(vlc_object_t *);
@@ -117,6 +121,10 @@ vlc_module_begin ()
add_shortcut("direct3d9", "direct3d")
set_callbacks(Open, Close)
+ add_submodule()
+ set_capability( "decoder device", 10 )
+ set_callbacks( OpenD3D9DecoderDevice, CloseD3D9DecoderDevice )
+
#ifdef HAVE_GL
add_submodule()
set_description("DX OpenGL surface converter for D3D9")
@@ -174,8 +182,6 @@ struct vout_display_sys_t
/* outside rendering */
void *outside_opaque;
- libvlc_video_direct3d_device_setup_cb setupDeviceCb;
- libvlc_video_direct3d_device_cleanup_cb cleanupDeviceCb;
libvlc_video_direct3d_update_output_cb updateOutputCb;
libvlc_video_swap_cb swapCb;
libvlc_video_direct3d_start_end_rendering_cb startEndRenderingCb;
@@ -1388,9 +1394,6 @@ static void Direct3D9Destroy(vout_display_sys_t *sys)
FreeLibrary(sys->hxdll);
sys->hxdll = NULL;
}
-
- if ( sys->cleanupDeviceCb )
- sys->cleanupDeviceCb( sys->outside_opaque );
}
/**
@@ -1599,27 +1602,6 @@ static int FindShadersCallback(const char *name, char ***values, char ***descs)
}
-static bool LocalSwapchainSetupDevice( void **opaque, const libvlc_video_direct3d_device_cfg_t *cfg, libvlc_video_direct3d_device_setup_t *out )
-{
- vout_display_t *vd = *opaque;
- vout_display_sys_t *sys = vd->sys;
- if (D3D9_Create(vd, &sys->hd3d) != VLC_SUCCESS)
- {
- msg_Err( vd, "Direct3D9 could not be initialized" );
- return false;
- }
-
- out->device_context = sys->hd3d.obj;
- return true;
-}
-
-static void LocalSwapchainCleanupDevice( void *opaque )
-{
- vout_display_t *vd = opaque;
- vout_display_sys_t *sys = vd->sys;
- D3D9_Destroy(&sys->hd3d);
-}
-
static bool LocalSwapchainUpdateOutput( void *opaque, const libvlc_video_direct3d_cfg_t *cfg, libvlc_video_output_cfg_t *out )
{
vout_display_t *vd = opaque;
@@ -1666,45 +1648,40 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
CommonInit(vd, &sys->area, cfg);
sys->outside_opaque = var_InheritAddress( vd, "vout-cb-opaque" );
- sys->setupDeviceCb = var_InheritAddress( vd, "vout-cb-setup" );
- sys->cleanupDeviceCb = var_InheritAddress( vd, "vout-cb-cleanup" );
sys->updateOutputCb = var_InheritAddress( vd, "vout-cb-update-output" );
sys->swapCb = var_InheritAddress( vd, "vout-cb-swap" );
sys->startEndRenderingCb = var_InheritAddress( vd, "vout-cb-make-current" );
- if ( sys->setupDeviceCb == NULL || sys->swapCb == NULL || sys->startEndRenderingCb == NULL || sys->updateOutputCb == NULL )
+ if ( sys->swapCb == NULL || sys->startEndRenderingCb == NULL || sys->updateOutputCb == NULL )
{
/* use our own callbacks, since there isn't any external ones */
if (CommonWindowInit(VLC_OBJECT(vd), &sys->area, &sys->sys, false))
goto error;
sys->outside_opaque = vd;
- sys->setupDeviceCb = LocalSwapchainSetupDevice;
- sys->cleanupDeviceCb = LocalSwapchainCleanupDevice;
sys->updateOutputCb = LocalSwapchainUpdateOutput;
sys->swapCb = LocalSwapchainSwap;
sys->startEndRenderingCb = NULL;
}
- libvlc_video_direct3d_device_cfg_t surface_cfg = {
- .hardware_decoding = is_d3d9_opaque( vd->source.i_chroma ),
- };
- libvlc_video_direct3d_device_setup_t device_setup;
- IDirect3D9 *d3d9_device = NULL;
- if ( sys->setupDeviceCb( &sys->outside_opaque, &surface_cfg, &device_setup ) )
- d3d9_device = device_setup.device_context;
+ IDirect3DDevice9 *d3d9_device = NULL;
+ if ( context && context->device->type == VLC_DECODER_DEVICE_DXVA2 )
+ d3d9_device = context->device->opaque;
if ( d3d9_device == NULL )
{
- msg_Err(vd, "Missing external IDirect3D9");
- return VLC_EGENERIC;
+ msg_Err(vd, "Missing D3D device");
+ goto error;
}
- D3D9_CloneExternal( &sys->hd3d, d3d9_device );
- HRESULT hr = D3D9_CreateDevice(vd, &sys->hd3d, sys->sys.hvideownd, &sys->d3d_dev);
+ if ( unlikely(D3D9_CreateExternal(vd, &sys->hd3d, d3d9_device) != VLC_SUCCESS) )
+ {
+ goto error;
+ }
+ HRESULT hr = D3D9_CreateDeviceExternal(d3d9_device, &sys->hd3d,
+ sys->sys.hvideownd,
+ &sys->d3d_dev);
if (FAILED(hr)) {
msg_Err( vd, "D3D9 Creation failed! (hr=0x%lX)", hr);
D3D9_Destroy(&sys->hd3d);
- if ( sys->cleanupDeviceCb )
- sys->cleanupDeviceCb( sys->outside_opaque );
free(sys);
return VLC_EGENERIC;
}
@@ -1719,7 +1696,7 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
goto error;
}
- if (sys->setupDeviceCb != LocalSwapchainSetupDevice)
+ if (sys->swapCb == LocalSwapchainSwap)
CommonPlacePicture(VLC_OBJECT(vd), &sys->area, &sys->sys);
sys->hxdll = Direct3D9LoadShaderLibrary();
@@ -1961,11 +1938,16 @@ GLConvOpen(vlc_object_t *obj)
goto error;
}
- if (FAILED(D3D9_CreateDevice(obj, &priv->hd3d, tc->gl->surface->handle.hwnd,
- &priv->d3d_dev)))
+ HRESULT hr;
+ if (tc->dec_device->type == VLC_DECODER_DEVICE_DXVA2)
+ hr = D3D9_CreateDeviceExternal( (IDirect3DDevice9*)tc->dec_device->opaque,
+ &priv->hd3d, tc->gl->surface->handle.hwnd, &priv->d3d_dev );
+ else
+ hr = D3D9_CreateDevice(obj, &priv->hd3d, tc->gl->surface->handle.hwnd,
+ &priv->d3d_dev);
+ if (FAILED(hr))
goto error;
- HRESULT hr;
HANDLE shared_handle = NULL;
hr = IDirect3DDevice9Ex_CreateRenderTarget(priv->d3d_dev.devex,
tc->fmt.i_visible_width,
@@ -2005,3 +1987,49 @@ error:
return VLC_EGENERIC;
}
#endif
+
+/* decoder device */
+struct local_render_device
+{
+ d3d9_handle_t hd3d;
+ d3d9_device_t d3d_dev;
+};
+
+static int OpenD3D9DecoderDevice(vlc_decoder_device *device, vout_window_t *wnd, vlc_fourcc_t chroma)
+{
+ VLC_UNUSED(wnd);
+ VLC_UNUSED(chroma);
+ struct local_render_device *display = vlc_obj_calloc(VLC_OBJECT(device), 1, sizeof(*display));
+ if (unlikely(display == NULL))
+ return VLC_ENOMEM;
+
+ if (D3D9_Create(device, &display->hd3d) != VLC_SUCCESS)
+ {
+ msg_Err( device, "Direct3D9 could not be initialized" );
+ goto error;
+ }
+
+ HRESULT hr = D3D9_CreateDevice( device, &display->hd3d, NULL, &display->d3d_dev );
+ if ( FAILED(hr) )
+ {
+ goto error;
+ }
+
+ device->opaque = display->d3d_dev.dev;
+ device->type = VLC_DECODER_DEVICE_DXVA2;
+ device->sys = display;
+
+ return VLC_SUCCESS;
+
+error:
+ D3D9_Destroy(&display->hd3d);
+ return VLC_EGENERIC;
+}
+
+static void CloseD3D9DecoderDevice(vlc_decoder_device *device)
+{
+ struct local_render_device *display = device->sys;
+ D3D9_ReleaseDevice( &display->d3d_dev );
+ D3D9_Destroy(&display->hd3d);
+}
+
--
2.17.1
More information about the vlc-devel
mailing list