[vlc-devel] [PATCH 07/31] direct3d11: add a decoder device when using external rendering
Steve Lhomme
robux4 at ycbcr.xyz
Fri Jul 5 16:19:46 CEST 2019
It also handles the legacy "winrt-d3dcontext" variable.
---
lib/media_player.c | 1 +
modules/hw/d3d11/Makefile.am | 1 +
modules/hw/d3d11/d3d11_device.c | 104 ++++++++++++++++++++++++
modules/hw/d3d11/d3d11_filters.c | 11 +++
modules/hw/d3d11/d3d11_filters.h | 4 +
modules/video_output/win32/direct3d11.c | 1 -
6 files changed, 121 insertions(+), 1 deletion(-)
create mode 100644 modules/hw/d3d11/d3d11_device.c
diff --git a/lib/media_player.c b/lib/media_player.c
index f3cf1a417c..de31b07e1d 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -1088,6 +1088,7 @@ bool libvlc_video_direct3d_set_callbacks(libvlc_media_player_t *mp,
{
var_SetString ( mp, "vout", "direct3d11" );
var_SetString ( mp, "avcodec-hw", "d3d11va");
+ var_SetString ( mp, "dec-dev", "d3d11-device" );
}
else if ( engine == libvlc_video_direct3d_engine_d3d9 )
{
diff --git a/modules/hw/d3d11/Makefile.am b/modules/hw/d3d11/Makefile.am
index e5c5afa3b8..3c9ae52e15 100644
--- a/modules/hw/d3d11/Makefile.am
+++ b/modules/hw/d3d11/Makefile.am
@@ -3,6 +3,7 @@ d3d11dir = $(pluginsdir)/d3d11
libdirect3d11_filters_plugin_la_SOURCES = hw/d3d11/d3d11_filters.h \
hw/d3d11/d3d11_filters.c \
hw/d3d11/d3d11_deinterlace.c \
+ hw/d3d11/d3d11_device.c \
hw/d3d11/d3d11_surface.c \
hw/d3d11/d3d11_instance.c \
hw/d3d11/d3d11_processor.c hw/d3d11/d3d11_processor.h
diff --git a/modules/hw/d3d11/d3d11_device.c b/modules/hw/d3d11/d3d11_device.c
new file mode 100644
index 0000000000..086ae8a5c3
--- /dev/null
+++ b/modules/hw/d3d11/d3d11_device.c
@@ -0,0 +1,104 @@
+/*****************************************************************************
+ * d3d11_device.c : D3D11 decoder device from external ID3D11DeviceContext
+ *****************************************************************************
+ * Copyright © 2019 VLC authors, VideoLAN and VideoLabs
+ *
+ * Authors: Steve Lhomme <robux4 at ycbcr.xyz>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#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>
+
+#define COBJMACROS
+#include <d3d11.h>
+#include "d3d11_filters.h"
+
+typedef struct {
+ void *opaque;
+ libvlc_video_direct3d_device_cleanup_cb cleanupDeviceCb;
+
+ d3d11_decoder_device_t dec_device;
+} d3d11_decoder_device;
+
+int D3D11OpenDecoderDevice(vlc_decoder_device *device, bool forced, vout_window_t *wnd)
+{
+ VLC_UNUSED(forced);
+ d3d11_decoder_device *sys = vlc_obj_malloc(VLC_OBJECT(device), sizeof(*sys));
+ if (unlikely(sys==NULL))
+ return VLC_ENOMEM;
+
+ libvlc_video_direct3d_device_setup_t out = { NULL };
+#if VLC_WINSTORE_APP
+ /* LEGACY, the d3dcontext and swapchain were given by the host app */
+ out.device_context = (ID3D11DeviceContext*)(uintptr_t) var_InheritInteger(wnd, "winrt-d3dcontext");
+ if ( likely(out.device_context == NULL) )
+#endif
+ {
+ libvlc_video_direct3d_device_setup_cb setupDeviceCb = var_InheritAddress( wnd, "vout-cb-setup" );
+ if ( setupDeviceCb )
+ {
+ sys->opaque = var_InheritAddress( wnd, "vout-cb-opaque" );
+ sys->cleanupDeviceCb = var_InheritAddress( wnd, "vout-cb-cleanup" );
+ libvlc_video_direct3d_device_cfg_t cfg = {
+ .hardware_decoding = true, /* always favor hardware decoding */
+ };
+ if (!setupDeviceCb( &sys->opaque, &cfg, &out ))
+ {
+ sys->cleanupDeviceCb( sys->opaque );
+ out.device_context = NULL;
+ }
+ }
+ }
+
+ if ( !out.device_context )
+ {
+ return VLC_EGENERIC;
+ }
+
+ sys->dec_device.device = (ID3D11DeviceContext*) out.device_context;
+ ID3D11DeviceContext_AddRef(sys->dec_device.device);
+
+ device->opaque = &sys->dec_device;
+ device->type = VLC_DECODER_DEVICE_D3D11VA;
+ device->sys = sys;
+
+ return VLC_SUCCESS;
+}
+
+void D3D11CloseDecoderDevice(vlc_decoder_device *device)
+{
+ d3d11_decoder_device *sys = device->sys;
+
+ ID3D11DeviceContext_Release(sys->dec_device.device);
+
+ if ( sys->cleanupDeviceCb )
+ sys->cleanupDeviceCb( sys->opaque );
+}
diff --git a/modules/hw/d3d11/d3d11_filters.c b/modules/hw/d3d11/d3d11_filters.c
index ae159a0d08..714a8490dd 100644
--- a/modules/hw/d3d11/d3d11_filters.c
+++ b/modules/hw/d3d11/d3d11_filters.c
@@ -585,4 +585,15 @@ vlc_module_begin()
set_callbacks( D3D11OpenCPUConverter, D3D11CloseCPUConverter )
set_capability( "video converter", 10 )
+ add_submodule()
+ set_callbacks( D3D11OpenDecoderDevice, D3D11CloseDecoderDevice )
+#if !VLC_WINSTORE_APP
+ set_capability( "decoder device", 0 )
+#else /* VLC_WINSTORE_APP */
+ /* LEGACY, the d3dcontext and swapchain were given by the host app */
+ add_integer("winrt-d3dcontext", 0x0, NULL, NULL, true) /* ID3D11DeviceContext* */
+ set_capability( "decoder device", 1 ) /* loaded automatically */
+#endif /* VLC_WINSTORE_APP */
+ add_shortcut ("d3d11-device")
+
vlc_module_end()
diff --git a/modules/hw/d3d11/d3d11_filters.h b/modules/hw/d3d11/d3d11_filters.h
index c4433937f9..bf27308407 100644
--- a/modules/hw/d3d11/d3d11_filters.h
+++ b/modules/hw/d3d11/d3d11_filters.h
@@ -24,6 +24,7 @@
#define VLC_D3D11_FILTERS_H
#include <vlc_common.h>
+#include <vlc_vout_display.h>
#include "../../video_chroma/d3d11_fmt.h"
@@ -34,6 +35,9 @@ void D3D11CloseConverter(vlc_object_t *);
int D3D11OpenCPUConverter(vlc_object_t *);
void D3D11CloseCPUConverter(vlc_object_t *);
+int D3D11OpenDecoderDevice(vlc_decoder_device *, bool, vout_window_t *);
+void D3D11CloseDecoderDevice(vlc_decoder_device *);
+
void D3D11_FilterHoldInstance(filter_t *, d3d11_device_t *, D3D11_TEXTURE2D_DESC *);
void D3D11_FilterReleaseInstance(d3d11_device_t *);
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index f23cd04810..c05e305e80 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -80,7 +80,6 @@ vlc_module_begin ()
add_bool("direct3d11-hw-blending", true, HW_BLENDING_TEXT, HW_BLENDING_LONGTEXT, true)
#if VLC_WINSTORE_APP
- add_integer("winrt-d3dcontext", 0x0, NULL, NULL, true) /* ID3D11DeviceContext* */
add_integer("winrt-swapchain", 0x0, NULL, NULL, true) /* IDXGISwapChain1* */
#endif
--
2.17.1
More information about the vlc-devel
mailing list