Commit b45d5e87 authored by Steve Lhomme's avatar 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.
parent 7dd6bc32
......@@ -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
......
/*****************************************************************************
* d3d11_device.c : D3D11 decoder device from external ID3D11DeviceContext
*****************************************************************************
* Copyright © 2019 VLC authors, VideoLAN and VideoLabs
*
* Authors: Steve Lhomme <robux4@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 {
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;
}
......@@ -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()
......@@ -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 *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment