[vlc-devel] [PATCH 6/7] direct3d9: add a decoder device when using external rendering

Steve Lhomme robux4 at ycbcr.xyz
Wed Jun 26 15:49:03 CEST 2019


---
 lib/media_player.c             |   1 +
 modules/hw/d3d9/Makefile.am    |   1 +
 modules/hw/d3d9/d3d9_device.c  | 102 +++++++++++++++++++++++++++++++++
 modules/hw/d3d9/d3d9_filters.c |   5 ++
 modules/hw/d3d9/d3d9_filters.h |   4 ++
 5 files changed, 113 insertions(+)
 create mode 100644 modules/hw/d3d9/d3d9_device.c

diff --git a/lib/media_player.c b/lib/media_player.c
index 682388181e..de31b07e1d 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -1094,6 +1094,7 @@ bool libvlc_video_direct3d_set_callbacks(libvlc_media_player_t *mp,
     {
         var_SetString ( mp, "vout", "direct3d9" );
         var_SetString ( mp, "avcodec-hw", "dxva2");
+        var_SetString ( mp, "dec-dev", "d3d9-device" );
     }
     else
         return false;
diff --git a/modules/hw/d3d9/Makefile.am b/modules/hw/d3d9/Makefile.am
index 1711953e39..68f0084ab1 100644
--- a/modules/hw/d3d9/Makefile.am
+++ b/modules/hw/d3d9/Makefile.am
@@ -4,6 +4,7 @@ libdirect3d9_filters_plugin_la_SOURCES = hw/d3d9/d3d9_filters.h \
     hw/d3d9/d3d9_filters.c \
     hw/d3d9/dxva2_deinterlace.c \
     hw/d3d9/dxa9.c \
+    hw/d3d9/d3d9_device.c \
     hw/d3d9/d3d9_instance.c
 libdirect3d9_filters_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(d3d9dir)'
 libdirect3d9_filters_plugin_la_LIBADD = libchroma_copy.la libdeinterlace_common.la libd3d9_common.la $(LIBCOM)
diff --git a/modules/hw/d3d9/d3d9_device.c b/modules/hw/d3d9/d3d9_device.c
new file mode 100644
index 0000000000..dfb6bd27fd
--- /dev/null
+++ b/modules/hw/d3d9/d3d9_device.c
@@ -0,0 +1,102 @@
+/*****************************************************************************
+ * d3d9_device.c : D3D9 decoder device from external IDirect3DDevice9
+ *****************************************************************************
+ * 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>
+
+#include "d3d9_filters.h"
+
+typedef struct {
+    void                                     *opaque;
+    libvlc_video_direct3d_device_cleanup_cb  cleanupDeviceCb;
+
+    d3d9_device_t                            d3ddev;
+} d3d9_decoder_device;
+
+int D3D9OpenDecoderDevice(vlc_decoder_device *device, vout_window_t *wnd, vlc_fourcc_t chroma)
+{
+    d3d9_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 };
+    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 = is_d3d9_opaque( chroma ),
+        };
+        if (!setupDeviceCb( &sys->opaque, &cfg, &out ))
+        {
+            goto error;
+        }
+    }
+
+    if ( !out.device_context )
+    {
+        goto error;
+    }
+
+    d3d9_handle_t hd3d;
+    D3D9_CloneExternal( &hd3d, out.device_context );
+    HRESULT hr = D3D9_CreateDevice( device, &hd3d, NULL, &sys->d3ddev );
+    if ( FAILED(hr) )
+    {
+        goto error;
+    }
+
+    device->opaque = sys->d3ddev.dev;
+    device->type = VLC_DECODER_DEVICE_DXVA2;
+    device->sys = sys;
+
+    return VLC_SUCCESS;
+error:
+    if ( sys->cleanupDeviceCb )
+        sys->cleanupDeviceCb( sys->opaque );
+    return VLC_EGENERIC;
+}
+
+void D3D9CloseDecoderDevice(vlc_decoder_device *device)
+{
+    d3d9_decoder_device *sys = device->sys;
+
+    D3D9_ReleaseDevice( &sys->d3ddev );
+
+    if ( sys->cleanupDeviceCb )
+        sys->cleanupDeviceCb( sys->opaque );
+}
diff --git a/modules/hw/d3d9/d3d9_filters.c b/modules/hw/d3d9/d3d9_filters.c
index a995c61d14..f1639e0b6e 100644
--- a/modules/hw/d3d9/d3d9_filters.c
+++ b/modules/hw/d3d9/d3d9_filters.c
@@ -496,4 +496,9 @@ vlc_module_begin()
     add_submodule()
     set_callbacks( D3D9OpenCPUConverter, D3D9CloseCPUConverter )
     set_capability( "video converter", 10 )
+
+    add_submodule()
+    set_callbacks( D3D9OpenDecoderDevice, D3D9CloseDecoderDevice )
+    set_capability( "decoder device", 0 )
+    add_shortcut ("d3d9-device")
 vlc_module_end()
diff --git a/modules/hw/d3d9/d3d9_filters.h b/modules/hw/d3d9/d3d9_filters.h
index ee0878bf3e..69b316e6ba 100644
--- a/modules/hw/d3d9/d3d9_filters.h
+++ b/modules/hw/d3d9/d3d9_filters.h
@@ -24,6 +24,7 @@
 #define VLC_D3D9_FILTERS_H
 
 #include <vlc_common.h>
+#include <vlc_vout_display.h>
 
 #include "../../video_chroma/d3d9_fmt.h"
 
@@ -34,6 +35,9 @@ void D3D9CloseConverter(vlc_object_t *);
 int  D3D9OpenCPUConverter(vlc_object_t *);
 void D3D9CloseCPUConverter(vlc_object_t *);
 
+int D3D9OpenDecoderDevice(vlc_decoder_device *, vout_window_t *, vlc_fourcc_t);
+void D3D9CloseDecoderDevice(vlc_decoder_device *);
+
 void D3D9_FilterHoldInstance(filter_t *, d3d9_device_t *, D3DSURFACE_DESC *);
 void D3D9_FilterReleaseInstance(d3d9_device_t *);
 
-- 
2.17.1



More information about the vlc-devel mailing list