vlc | branch: master | Steve Lhomme <[email protected]> | Fri Jun 7 12:58:18 2019 +0200| [b45d5e87944b5d9d7c04f403aa86863c82d4e15c] | committer: Steve Lhomme
direct3d11: add a decoder device It also handles internal/external rendering, the legacy "winrt-d3dcontext" variable. Do not use it if a DXVA2 decoder would be preferred on Win7/8.0. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b45d5e87944b5d9d7c04f403aa86863c82d4e15c --- modules/hw/d3d11/Makefile.am | 1 + modules/hw/d3d11/d3d11_device.c | 146 +++++++++++++++++++++++++++++++++++++++ modules/hw/d3d11/d3d11_filters.c | 10 +++ modules/hw/d3d11/d3d11_filters.h | 3 + 4 files changed, 160 insertions(+) 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..1d543e2087 --- /dev/null +++ b/modules/hw/d3d11/d3d11_device.c @@ -0,0 +1,146 @@ +/***************************************************************************** + * d3d11_device.c : D3D11 decoder device from external ID3D11DeviceContext + ***************************************************************************** + * Copyright © 2019 VLC authors, VideoLAN and VideoLabs + * + * Authors: Steve Lhomme <[email protected]> + * + * 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 { + d3d11_handle_t hd3d; + d3d11_device_t d3d_dev; + + struct { + void *opaque; + libvlc_video_direct3d_device_cleanup_cb cleanupDeviceCb; + } external; + + d3d11_decoder_device_t dec_device; +} d3d11_decoder_device; + +static void D3D11CloseDecoderDevice(vlc_decoder_device *device) +{ + d3d11_decoder_device *sys = device->sys; + + ID3D11DeviceContext_Release(sys->dec_device.device); + + D3D11_Destroy(&sys->hd3d); + + if ( sys->external.cleanupDeviceCb ) + sys->external.cleanupDeviceCb( sys->external.opaque ); + + vlc_obj_free( VLC_OBJECT(device), sys ); +} + +static const struct vlc_decoder_device_operations d3d11_dev_ops = { + .close = D3D11CloseDecoderDevice, +}; + +int D3D11OpenDecoderDevice(vlc_decoder_device *device, vout_window_t *wnd) +{ + VLC_UNUSED(wnd); + d3d11_decoder_device *sys = vlc_obj_malloc(VLC_OBJECT(device), sizeof(*sys)); + if (unlikely(sys==NULL)) + return VLC_ENOMEM; + + int ret = D3D11_Create(device, &sys->hd3d, true); + if (ret != VLC_SUCCESS) + return ret; + + sys->external.cleanupDeviceCb = NULL; +#if VLC_WINSTORE_APP + /* LEGACY, the d3dcontext and swapchain were given by the host app */ + ID3D11DeviceContext *d3dcontext = (ID3D11DeviceContext*)(uintptr_t) var_InheritInteger(device, "winrt-d3dcontext"); + if ( likely(d3dcontext != NULL) ) + { + D3D11_CreateDeviceExternal(device, d3dcontext, true, &sys->d3d_dev); + } + else +#endif + { + libvlc_video_direct3d_device_setup_cb setupDeviceCb = var_InheritAddress( device, "vout-cb-setup" ); + if ( setupDeviceCb ) + { + /* decoder device coming from the external app */ + sys->external.opaque = var_InheritAddress( device, "vout-cb-opaque" ); + sys->external.cleanupDeviceCb = var_InheritAddress( device, "vout-cb-cleanup" ); + libvlc_video_direct3d_device_cfg_t cfg = { + .hardware_decoding = true, /* always favor hardware decoding */ + }; + libvlc_video_direct3d_device_setup_t out = { .device_context = NULL }; + if (!setupDeviceCb( &sys->external.opaque, &cfg, &out )) + { + if (sys->external.cleanupDeviceCb) + sys->external.cleanupDeviceCb( sys->external.opaque ); + goto error; + } + D3D11_CreateDeviceExternal(device, out.device_context, true, &sys->d3d_dev); + } + else + { + /* internal decoder device */ + HRESULT hr = D3D11_CreateDevice( device, &sys->hd3d, NULL, + true /* is_d3d11_opaque(chroma) */, + &sys->d3d_dev ); + if ( FAILED( hr ) ) + { + D3D11_Destroy(&sys->hd3d); + return VLC_EGENERIC; + } + } + } + + if ( !sys->d3d_dev.d3dcontext ) + { + return VLC_EGENERIC; + } + + sys->dec_device.device = sys->d3d_dev.d3dcontext; + ID3D11DeviceContext_AddRef(sys->dec_device.device); + + device->ops = &d3d11_dev_ops; + device->opaque = &sys->dec_device; + device->type = VLC_DECODER_DEVICE_D3D11VA; + device->sys = sys; + + return VLC_SUCCESS; +error: + D3D11_Destroy(&sys->hd3d); + vlc_obj_free( VLC_OBJECT(device), sys ); + return VLC_EGENERIC; +} diff --git a/modules/hw/d3d11/d3d11_filters.c b/modules/hw/d3d11/d3d11_filters.c index ae159a0d08..1feb03fc5f 100644 --- a/modules/hw/d3d11/d3d11_filters.c +++ b/modules/hw/d3d11/d3d11_filters.c @@ -33,6 +33,7 @@ #include <vlc_plugin.h> #include <vlc_filter.h> #include <vlc_picture.h> +#include <vlc_codec.h> #define COBJMACROS #include <d3d11.h> @@ -585,4 +586,13 @@ vlc_module_begin() set_callbacks( D3D11OpenCPUConverter, D3D11CloseCPUConverter ) set_capability( "video converter", 10 ) + add_submodule() + set_description(N_("Direct3D11")) + set_callback_dec_device( D3D11OpenDecoderDevice, 20 ) +#if VLC_WINSTORE_APP + /* LEGACY, the d3dcontext and swapchain were given by the host app */ + add_integer("winrt-d3dcontext", 0x0, NULL, NULL, true) /* ID3D11DeviceContext* */ +#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..0c03523dde 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,8 @@ void D3D11CloseConverter(vlc_object_t *); int D3D11OpenCPUConverter(vlc_object_t *); void D3D11CloseCPUConverter(vlc_object_t *); +int D3D11OpenDecoderDevice(vlc_decoder_device *, vout_window_t *); + void D3D11_FilterHoldInstance(filter_t *, d3d11_device_t *, D3D11_TEXTURE2D_DESC *); void D3D11_FilterReleaseInstance(d3d11_device_t *); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
