Commit dab7df5e authored by Steve Lhomme's avatar Steve Lhomme Committed by Jean-Baptiste Kempf

d3d11va: use the same output format order as the vout for safer compatibility

in debug builds log all the support DXGI output formats
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 49ea9bbc
......@@ -359,6 +359,7 @@ endif
libd3d11va_plugin_la_SOURCES = \
codec/avcodec/d3d11va.c codec/avcodec/directx_va.c codec/avcodec/directx_va.h \
video_chroma/dxgi_fmt.c video_chroma/dxgi_fmt.h \
packetizer/h264_nal.c packetizer/h264_nal.h
libd3d11va_plugin_la_LIBADD = -lole32 -luuid
if HAVE_AVCODEC_D3D11VA
......
......@@ -44,9 +44,11 @@
#include "directx_va.h"
#define COBJMACROS
#define INITGUID
#include <d3d11.h>
#include <libavcodec/d3d11va.h>
#include "../../video_chroma/copy.h"
#include "../../video_chroma/dxgi_fmt.h"
static int Open(vlc_va_t *, AVCodecContext *, enum PixelFormat,
const es_format_t *, picture_sys_t *p_sys);
......@@ -618,38 +620,54 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input)
directx_sys_t *dx_sys = &va->sys->dx_sys;
HRESULT hr;
/* */
BOOL is_supported = false;
hr = ID3D11VideoDevice_CheckVideoDecoderFormat((ID3D11VideoDevice*) dx_sys->d3ddec, input, DXGI_FORMAT_NV12, &is_supported);
if (SUCCEEDED(hr) && is_supported)
msg_Dbg(va, "NV12 is supported for output");
#ifndef NDEBUG
BOOL bSupported = false;
for (int format = 0; format < 188; format++) {
hr = ID3D11VideoDevice_CheckVideoDecoderFormat((ID3D11VideoDevice*) dx_sys->d3ddec, input, format, &bSupported);
if (SUCCEEDED(hr) && bSupported)
msg_Dbg(va, "format %s is supported for output", DxgiFormatToStr(format));
}
#endif
DXGI_FORMAT processorInput[4];
int idx = 0;
if ( va->sys->render != DXGI_FORMAT_UNKNOWN )
processorInput[idx++] = va->sys->render;
processorInput[idx++] = DXGI_FORMAT_NV12;
processorInput[idx++] = DXGI_FORMAT_UNKNOWN;
/* */
for (idx = 0; processorInput[idx] != DXGI_FORMAT_UNKNOWN; ++idx)
{
is_supported = false;
hr = ID3D11VideoDevice_CheckVideoDecoderFormat((ID3D11VideoDevice*) dx_sys->d3ddec, input, va->sys->render, &is_supported);
BOOL is_supported = false;
hr = ID3D11VideoDevice_CheckVideoDecoderFormat((ID3D11VideoDevice*) dx_sys->d3ddec, input, processorInput[idx], &is_supported);
if (SUCCEEDED(hr) && is_supported)
{
/* We have our solution */
msg_Dbg(va, "Using decoder output from picture source.");
return VLC_SUCCESS;
}
msg_Dbg(va, "Output format from picture source not supported.");
return VLC_EGENERIC;
}
msg_Dbg(va, "%s is supported for output", DxgiFormatToStr(processorInput[idx]));
else
{
/* */
is_supported = false;
hr = ID3D11VideoDevice_CheckVideoDecoderFormat((ID3D11VideoDevice*) dx_sys->d3ddec, input, DXGI_FORMAT_NV12, &is_supported);
if (SUCCEEDED(hr) && is_supported)
msg_Dbg(va, "Can't get a decoder for output format %s.", DxgiFormatToStr(processorInput[idx]));
continue;
}
// check if we can create render texture of that format
// check the decoder can output to that format
const UINT i_quadSupportFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_LOAD;
UINT i_formatSupport;
bool b_needsProcessor = true;
if( SUCCEEDED( ID3D11Device_CheckFormatSupport((ID3D11Device*) dx_sys->d3ddev,
processorInput[idx],
&i_formatSupport)) &&
( i_formatSupport & i_quadSupportFlags ) == i_quadSupportFlags )
b_needsProcessor = false;
if ( !b_needsProcessor )
{
/* We have our solution */
msg_Dbg(va, "Using decoder output NV12");
va->sys->render = DXGI_FORMAT_NV12;
va->sys->render = processorInput[idx];
return VLC_SUCCESS;
}
}
msg_Dbg(va, "Output format from picture source not supported.");
return VLC_EGENERIC;
}
......
/*****************************************************************************
* d3d11_surface.c : D3D11 GPU surface conversion module for vlc
*****************************************************************************
* Copyright © 2015 VLC authors, VideoLAN and VideoLabs
*
* Authors: Steve Lhomme <robux4@gmail.com>
*
* 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "dxgi_fmt.h"
typedef struct
{
const char *name;
DXGI_FORMAT format;
} dxgi_format_t;
static const dxgi_format_t dxgi_formats[] = {
{ "NV12", DXGI_FORMAT_NV12 },
{ "I420_OPAQUE", DXGI_FORMAT_420_OPAQUE },
{ "RGBA", DXGI_FORMAT_R8G8B8A8_UNORM },
{ "RGBA_SRGB", DXGI_FORMAT_R8G8B8A8_UNORM_SRGB },
{ "BGRX", DXGI_FORMAT_B8G8R8X8_UNORM },
{ "BGRA", DXGI_FORMAT_B8G8R8A8_UNORM },
{ "BGRA_SRGB", DXGI_FORMAT_B8G8R8A8_UNORM_SRGB },
{ "AYUV", DXGI_FORMAT_AYUV },
{ "YUY2", DXGI_FORMAT_YUY2 },
{ "AI44", DXGI_FORMAT_AI44 },
{ "P8", DXGI_FORMAT_P8 },
{ "A8P8", DXGI_FORMAT_A8P8 },
{ "B5G6R5", DXGI_FORMAT_B5G6R5_UNORM },
{ "Y416", DXGI_FORMAT_Y416 },
{ "P010", DXGI_FORMAT_P010 },
{ "Y210", DXGI_FORMAT_Y210 },
{ "Y410", DXGI_FORMAT_Y410 },
{ "NV11", DXGI_FORMAT_NV11 },
{ "UNKNOWN", DXGI_FORMAT_UNKNOWN },
{ NULL, 0,}
};
static const d3d_format_t d3d_formats[] = {
{ "I420", DXGI_FORMAT_NV12, VLC_CODEC_I420, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
{ "YV12", DXGI_FORMAT_NV12, VLC_CODEC_YV12, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
{ "NV12", DXGI_FORMAT_NV12, VLC_CODEC_NV12, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
{ "VA_NV12", DXGI_FORMAT_NV12, VLC_CODEC_D3D11_OPAQUE, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
#ifdef BROKEN_PIXEL
{ "YUY2", DXGI_FORMAT_YUY2, VLC_CODEC_I422, DXGI_FORMAT_R8G8B8A8_UNORM, 0 },
{ "AYUV", DXGI_FORMAT_AYUV, VLC_CODEC_YUVA, DXGI_FORMAT_R8G8B8A8_UNORM, 0 },
{ "Y416", DXGI_FORMAT_Y416, VLC_CODEC_I444_16L, DXGI_FORMAT_R16G16B16A16_UINT, 0 },
#endif
#ifdef UNTESTED
{ "P010", DXGI_FORMAT_P010, VLC_CODEC_I420_10L, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM },
{ "Y210", DXGI_FORMAT_Y210, VLC_CODEC_I422_10L, DXGI_FORMAT_R16G16B16A16_UNORM, 0 },
{ "Y410", DXGI_FORMAT_Y410, VLC_CODEC_I444_10L, DXGI_FORMAT_R10G10B10A2_UNORM, 0 },
{ "NV11", DXGI_FORMAT_NV11, VLC_CODEC_I411, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
#endif
{ "R8G8B8A8", DXGI_FORMAT_R8G8B8A8_UNORM, VLC_CODEC_RGBA, DXGI_FORMAT_R8G8B8A8_UNORM, 0 },
{ "VA_RGBA", DXGI_FORMAT_R8G8B8A8_UNORM, VLC_CODEC_D3D11_OPAQUE, DXGI_FORMAT_R8G8B8A8_UNORM, 0 },
{ "B8G8R8A8", DXGI_FORMAT_B8G8R8A8_UNORM, VLC_CODEC_BGRA, DXGI_FORMAT_B8G8R8A8_UNORM, 0 },
{ "VA_BGRA", DXGI_FORMAT_B8G8R8A8_UNORM, VLC_CODEC_D3D11_OPAQUE, DXGI_FORMAT_B8G8R8A8_UNORM, 0 },
{ "R8G8B8X8", DXGI_FORMAT_B8G8R8X8_UNORM, VLC_CODEC_RGB32, DXGI_FORMAT_B8G8R8X8_UNORM, 0 },
{ "B5G6R5", DXGI_FORMAT_B5G6R5_UNORM, VLC_CODEC_RGB16, DXGI_FORMAT_B5G6R5_UNORM, 0 },
{ NULL, 0, 0, 0, 0}
};
const char *DxgiFormatToStr(DXGI_FORMAT format)
{
for (const dxgi_format_t *f = dxgi_formats; f->name != NULL; ++f)
{
if (f->format == format)
return f->name;
}
return NULL;
}
const d3d_format_t *GetRenderFormatList(void)
{
return d3d_formats;
}
/*****************************************************************************
* d3d11_surface.c : DXGI helper calls
*****************************************************************************
* Copyright © 2015 VLC authors, VideoLAN and VideoLabs
*
* Authors: Steve Lhomme <robux4@gmail.com>
*
* 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.
*****************************************************************************/
#ifndef _VLC_VIDEOCHROMA_DXGI_H
#define _VLC_VIDEOCHROMA_DXGI_H 1
#include <dxgiformat.h>
#include <vlc_common.h>
#include <vlc_fourcc.h>
typedef struct
{
const char *name;
DXGI_FORMAT formatTexture;
vlc_fourcc_t fourcc;
DXGI_FORMAT formatY;
DXGI_FORMAT formatUV;
} d3d_format_t;
extern const char *DxgiFormatToStr(DXGI_FORMAT format);
extern const d3d_format_t *GetRenderFormatList(void);
#endif /* _VLC_VIDEOCHROMA_DXGI_H */
......@@ -178,6 +178,7 @@ vout_LTLIBRARIES += $(LTLIBdirect3d9)
EXTRA_LTLIBRARIES += libdirect3d9_plugin.la
libdirect3d11_plugin_la_SOURCES = video_output/msw/direct3d11.c \
video_chroma/dxgi_fmt.c video_chroma/dxgi_fmt.h \
video_output/msw/common.c video_output/msw/common.h
libdirect3d11_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) \
-DMODULE_NAME_IS_direct3d11
......
......@@ -38,6 +38,8 @@
#include "common.h"
#include "../../video_chroma/dxgi_fmt.h"
#if !VLC_WINSTORE_APP
# if USE_DXGI
# define D3D11CreateDeviceAndSwapChain(args...) sys->OurD3D11CreateDeviceAndSwapChain(args)
......@@ -78,39 +80,6 @@ vlc_module_begin ()
set_callbacks(Open, Close)
vlc_module_end ()
typedef struct
{
const char *name;
DXGI_FORMAT formatTexture;
vlc_fourcc_t fourcc;
DXGI_FORMAT formatY;
DXGI_FORMAT formatUV;
} d3d_format_t;
static const d3d_format_t d3d_formats[] = {
{ "I420", DXGI_FORMAT_NV12, VLC_CODEC_I420, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
{ "YV12", DXGI_FORMAT_NV12, VLC_CODEC_YV12, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
{ "NV12", DXGI_FORMAT_NV12, VLC_CODEC_NV12, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
{ "VA_NV12", DXGI_FORMAT_NV12, VLC_CODEC_D3D11_OPAQUE, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
#ifdef BROKEN_PIXEL
{ "YUY2", DXGI_FORMAT_YUY2, VLC_CODEC_I422, DXGI_FORMAT_R8G8B8A8_UNORM, 0 },
{ "AYUV", DXGI_FORMAT_AYUV, VLC_CODEC_YUVA, DXGI_FORMAT_R8G8B8A8_UNORM, 0 },
{ "Y416", DXGI_FORMAT_Y416, VLC_CODEC_I444_16L, DXGI_FORMAT_R16G16B16A16_UINT, 0 },
#endif
#ifdef UNTESTED
{ "P010", DXGI_FORMAT_P010, VLC_CODEC_I420_10L, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM },
{ "Y210", DXGI_FORMAT_Y210, VLC_CODEC_I422_10L, DXGI_FORMAT_R16G16B16A16_UNORM, 0 },
{ "Y410", DXGI_FORMAT_Y410, VLC_CODEC_I444_10L, DXGI_FORMAT_R10G10B10A2_UNORM, 0 },
{ "NV11", DXGI_FORMAT_NV11, VLC_CODEC_I411, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
#endif
{ "R8G8B8A8", DXGI_FORMAT_R8G8B8A8_UNORM, VLC_CODEC_RGBA, DXGI_FORMAT_R8G8B8A8_UNORM, 0 },
{ "B8G8R8A8", DXGI_FORMAT_B8G8R8A8_UNORM, VLC_CODEC_BGRA, DXGI_FORMAT_B8G8R8A8_UNORM, 0 },
{ "R8G8B8X8", DXGI_FORMAT_B8G8R8X8_UNORM, VLC_CODEC_RGB32, DXGI_FORMAT_B8G8R8X8_UNORM, 0 },
{ "B5G6R5", DXGI_FORMAT_B5G6R5_UNORM, VLC_CODEC_RGB16, DXGI_FORMAT_B5G6R5_UNORM, 0 },
{ NULL, 0, 0, 0, 0}
};
#ifdef HAVE_ID3D11VIDEODECODER
/* VLC_CODEC_D3D11_OPAQUE */
struct picture_sys_t
......@@ -1031,20 +1000,21 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
// look for the request pixel format first
UINT i_quadSupportFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_LOAD;
UINT i_formatSupport;
for (unsigned i = 0; d3d_formats[i].name != 0; i++)
for (const d3d_format_t *output_format = GetRenderFormatList();
output_format->name != NULL; ++output_format)
{
if( i_src_chroma == d3d_formats[i].fourcc)
if( i_src_chroma == output_format->fourcc)
{
if( SUCCEEDED( ID3D11Device_CheckFormatSupport(sys->d3ddevice,
d3d_formats[i].formatTexture,
output_format->formatTexture,
&i_formatSupport)) &&
( i_formatSupport & i_quadSupportFlags ) == i_quadSupportFlags )
{
msg_Dbg(vd, "Using pixel format %s", d3d_formats[i].name );
fmt->i_chroma = d3d_formats[i].fourcc;
sys->picQuadConfig.textureFormat = d3d_formats[i].formatTexture;
sys->picQuadConfig.resourceFormatYRGB = d3d_formats[i].formatY;
sys->picQuadConfig.resourceFormatUV = d3d_formats[i].formatUV;
msg_Dbg(vd, "Using pixel format %s", output_format->name );
fmt->i_chroma = output_format->fourcc;
sys->picQuadConfig.textureFormat = output_format->formatTexture;
sys->picQuadConfig.resourceFormatYRGB = output_format->formatY;
sys->picQuadConfig.resourceFormatUV = output_format->formatUV;
break;
}
}
......@@ -1053,18 +1023,19 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
// look for any pixel format that we can handle
if ( !fmt->i_chroma )
{
for (unsigned i = 0; d3d_formats[i].name != 0; i++)
for (const d3d_format_t *output_format = GetRenderFormatList();
output_format->name != NULL; ++output_format)
{
if( SUCCEEDED( ID3D11Device_CheckFormatSupport(sys->d3ddevice,
d3d_formats[i].formatTexture,
output_format->formatTexture,
&i_formatSupport)) &&
( i_formatSupport & i_quadSupportFlags ) == i_quadSupportFlags )
{
msg_Dbg(vd, "Using pixel format %s", d3d_formats[i].name );
fmt->i_chroma = d3d_formats[i].fourcc;
sys->picQuadConfig.textureFormat = d3d_formats[i].formatTexture;
sys->picQuadConfig.resourceFormatYRGB = d3d_formats[i].formatY;
sys->picQuadConfig.resourceFormatUV = d3d_formats[i].formatUV;
msg_Dbg(vd, "Using pixel format %s", output_format->name );
fmt->i_chroma = output_format->fourcc;
sys->picQuadConfig.textureFormat = output_format->formatTexture;
sys->picQuadConfig.resourceFormatYRGB = output_format->formatY;
sys->picQuadConfig.resourceFormatUV = output_format->formatUV;
break;
}
}
......
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