[vlc-commits] [Git][videolan/vlc][master] 12 commits: dxgi_fmt: keep information about how many alpha bits has a DXGI format
Steve Lhomme (@robUx4)
gitlab at videolan.org
Fri Feb 16 14:38:46 UTC 2024
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
d6c19a63 by Steve Lhomme at 2024-02-16T13:21:45+00:00
dxgi_fmt: keep information about how many alpha bits has a DXGI format
- - - - -
8e8cb9da by Steve Lhomme at 2024-02-16T13:21:45+00:00
d3d11: allow picking a DXGI format that requires alpha channels
- - - - -
3f0b063c by Steve Lhomme at 2024-02-16T13:21:45+00:00
d3d11: add VLC_CODEC_YUV420A rendering support
- - - - -
d8f0d4df by Steve Lhomme at 2024-02-16T13:21:45+00:00
d3d: don't bleed alpha values in the colors
Since we use a 4x3 Colorspace matrix, the alpha values are can end up in the
colors.
- - - - -
8f5e889d by Steve Lhomme at 2024-02-16T13:21:45+00:00
dxgi_fmt: add secondary DXGI_FORMAT for a texture with alpha data
- - - - -
dc7f5a2e by Steve Lhomme at 2024-02-16T13:21:45+00:00
d3d11: lookup d3d_format_t with or without an alpha texture
- - - - -
3a85b272 by Steve Lhomme at 2024-02-16T13:21:45+00:00
d3d11_fmt: add an alpha texture type in d3d11_video_context_t
- - - - -
1429659a by Steve Lhomme at 2024-02-16T13:21:45+00:00
fourcc: add a D3D11 opaque that combines an opaque texture and an alpha one
- - - - -
81efa92f by Steve Lhomme at 2024-02-16T13:21:45+00:00
dxgi_fmt: add a d3d_format_t for GPU NV12 combined with NV12 alpha
- - - - -
678f8603 by Steve Lhomme at 2024-02-16T13:21:45+00:00
d3d11: add support for NV12 with alpha channel in NV12
- - - - -
c95e45ae by Steve Lhomme at 2024-02-16T13:21:45+00:00
d3d11_fmt: init GUIDs from d3d11/dxgi as well
- - - - -
f95c9c6a by Steve Lhomme at 2024-02-16T13:21:45+00:00
vpx_alpha: support D3D11 combined planes
- - - - -
24 changed files:
- include/vlc_fourcc.h
- modules/access/screen/dxgi.cpp
- modules/codec/Makefile.am
- + modules/codec/alpha_combine.h
- + modules/codec/alpha_d3d11.cpp
- modules/codec/avcodec/d3d11va.c
- modules/codec/meson.build
- modules/codec/mft_d3d11.cpp
- modules/codec/vpx_alpha.c
- modules/hw/d3d11/d3d11_decoder.cpp
- modules/hw/d3d11/d3d11_deinterlace.c
- modules/hw/d3d11/d3d11_filters.c
- modules/hw/d3d11/d3d11_surface.c
- modules/video_chroma/d3d11_fmt.c
- modules/video_chroma/d3d11_fmt.h
- modules/video_chroma/dxgi_fmt.c
- modules/video_chroma/dxgi_fmt.h
- modules/video_output/win32/d3d11_quad.cpp
- modules/video_output/win32/d3d11_scaler.cpp
- modules/video_output/win32/d3d11_swapchain.cpp
- modules/video_output/win32/d3d_dynamic_shader.c
- modules/video_output/win32/direct3d11.cpp
- src/misc/fourcc.c
- src/misc/fourcc_list.h
Changes:
=====================================
include/vlc_fourcc.h
=====================================
@@ -469,6 +469,7 @@
#define VLC_CODEC_D3D11_OPAQUE_10B VLC_FOURCC('D','X','1','0') /* 4:2:0 10 bpc */
#define VLC_CODEC_D3D11_OPAQUE_RGBA VLC_FOURCC('D','X','R','G')
#define VLC_CODEC_D3D11_OPAQUE_BGRA VLC_FOURCC('D','A','G','R')
+#define VLC_CODEC_D3D11_OPAQUE_ALPHA VLC_FOURCC('D','A','1','1') /* 4:2:0 8 bpc with extra alpha plane */
/* NVDEC opaque video format for use the NVDec API */
#define VLC_CODEC_NVDEC_OPAQUE VLC_FOURCC('N','V','D','8') /* 4:2:0 8 bpc */
=====================================
modules/access/screen/dxgi.cpp
=====================================
@@ -248,14 +248,14 @@ int screen_InitCaptureDXGI(demux_t *p_demux)
DXGI_OUTDUPL_DESC outDesc;
p_data->duplication->GetDesc(&outDesc);
- p_data->output_format = D3D11_RenderFormat(outDesc.ModeDesc.Format ,true);
+ p_data->output_format = D3D11_RenderFormat(outDesc.ModeDesc.Format, DXGI_FORMAT_UNKNOWN ,true);
if (unlikely(!p_data->output_format))
{
msg_Err(p_demux, "Unknown texture format %d", outDesc.ModeDesc.Format);
goto error;
}
- p_data->vctx = D3D11CreateVideoContext(dec_dev, p_data->output_format->formatTexture);
+ p_data->vctx = D3D11CreateVideoContext(dec_dev, p_data->output_format->formatTexture, p_data->output_format->alphaTexture);
vlc_decoder_device_Release(dec_dev);
dec_dev = nullptr;
if (unlikely(p_data->vctx == nullptr))
=====================================
modules/codec/Makefile.am
=====================================
@@ -568,7 +568,14 @@ libvpx_plugin_la_LIBADD = $(VPX_LIBS)
EXTRA_LTLIBRARIES += libvpx_plugin.la
codec_LTLIBRARIES += $(LTLIBvpx)
-libvpx_alpha_plugin_la_SOURCES = codec/vpx_alpha.c
+libvpx_alpha_plugin_la_SOURCES = codec/vpx_alpha.c codec/alpha_combine.h
+if HAVE_WIN32
+libvpx_alpha_plugin_la_SOURCES += codec/alpha_d3d11.cpp
+libvpx_alpha_plugin_la_LIBADD = $(LIBCOM) libd3d11_common.la
+if HAVE_WINSTORE
+libvpx_alpha_plugin_la_LIBADD += -ld3d11
+endif
+endif
codec_LTLIBRARIES += libvpx_alpha_plugin.la
libaom_plugin_la_SOURCES = codec/aom.c \
=====================================
modules/codec/alpha_combine.h
=====================================
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+// alpha_combine.h : helper to combine D3D11 planes to generate pictures with alpha
+// Copyright © 2023 VideoLabs, VLC authors and VideoLAN
+
+// Authors: Steve Lhomme <robux4 at videolabs.io>
+
+#ifndef VLC_ALPHA_COMBINE_H
+#define VLC_ALPHA_COMBINE_H 1
+
+#include <vlc_common.h>
+#include <vlc_codec.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN32
+picture_t *CombineD3D11(decoder_t *bdec, picture_t *opaque, picture_t *alpha, vlc_video_context*);
+int SetupD3D11(decoder_t *bdec, vlc_video_context *vctx, vlc_video_context **vctx_out);
+#endif // _WIN32
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // VLC_ALPHA_COMBINE_H
=====================================
modules/codec/alpha_d3d11.cpp
=====================================
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+// alpha_d3d11.cpp : helper to combine D3D11 planes to generate pictures with alpha
+// Copyright © 2023 VideoLabs, VLC authors and VideoLAN
+
+// Authors: Steve Lhomme <robux4 at videolabs.io>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "alpha_combine.h"
+#include "../video_chroma/d3d11_fmt.h"
+
+struct d3d11_alpha_context
+{
+ d3d11_pic_context ctx;
+ picture_t *opaque;
+ picture_t *alpha;
+};
+
+static void d3d11_alpha_pic_context_destroy(picture_context_t *ctx)
+{
+ d3d11_alpha_context *pic_ctx = container_of(ctx, d3d11_alpha_context, ctx);
+ picture_Release(pic_ctx->opaque);
+ picture_Release(pic_ctx->alpha);
+
+ auto *picsys_out = &pic_ctx->ctx.picsys;
+ // texture objects have been be released by their parents
+ picsys_out->renderSrc[0] = nullptr;
+ picsys_out->renderSrc[1] = nullptr;
+ picsys_out->renderSrc[2] = nullptr;
+ picsys_out->renderSrc[3] = nullptr;
+
+ picsys_out->texture[0] = nullptr;
+ picsys_out->texture[1] = nullptr;
+ picsys_out->texture[2] = nullptr;
+ picsys_out->texture[3] = nullptr;
+
+ d3d11_pic_context_destroy(ctx);
+}
+
+static picture_context_t *d3d11_alpha_pic_context_copy(picture_context_t *)
+{
+ assert(!"unsupported yet!");
+ return nullptr;
+}
+
+picture_t *CombineD3D11(decoder_t *dec, picture_t *opaque, picture_t *alpha, vlc_video_context *vctx)
+{
+ auto *out = decoder_NewPicture(dec);
+ if (out == nullptr)
+ return nullptr;
+
+ d3d11_alpha_context *pic_ctx = static_cast<d3d11_alpha_context *>(calloc(1, sizeof(*pic_ctx)));
+ if (unlikely(pic_ctx == NULL))
+ {
+ picture_Release(out);
+ return nullptr;
+ }
+ pic_ctx->ctx.picsys.sharedHandle = INVALID_HANDLE_VALUE;
+ pic_ctx->ctx.s.copy = d3d11_alpha_pic_context_copy;
+ pic_ctx->ctx.s.destroy = d3d11_alpha_pic_context_destroy;
+ pic_ctx->ctx.s.vctx = vlc_video_context_Hold(vctx);
+ pic_ctx->opaque = picture_Hold(opaque);
+ pic_ctx->alpha = picture_Hold(alpha);
+ out->context = &pic_ctx->ctx.s;
+
+ auto *picsys_out = &pic_ctx->ctx.picsys;
+ auto *picsys_opaque = ActiveD3D11PictureSys(opaque);
+ auto *picsys_alpha = ActiveD3D11PictureSys(alpha);
+
+ picsys_out->renderSrc[0] = picsys_opaque->renderSrc[0]; // opaque Y
+ picsys_out->renderSrc[1] = picsys_opaque->renderSrc[1]; // opaque UV
+ picsys_out->renderSrc[2] = picsys_alpha->renderSrc[0]; // alpha Y
+ picsys_out->renderSrc[3] = picsys_alpha->renderSrc[1]; // alpha UV
+
+ picsys_out->texture[0] = picsys_opaque->texture[0];
+ picsys_out->texture[1] = picsys_opaque->texture[1];
+ picsys_out->texture[2] = picsys_alpha->texture[0];
+ picsys_out->texture[3] = picsys_alpha->texture[1];
+
+ return out;
+}
+
+int SetupD3D11(decoder_t *dec, vlc_video_context *vctx, vlc_video_context **vctx_out)
+{
+ auto *vctx_sys = GetD3D11ContextPrivate(vctx);
+ assert(vctx_sys->secondary == DXGI_FORMAT_UNKNOWN);
+ assert(*vctx_out == nullptr); // TODO handle multiple format updates
+
+ auto *dec_dev = vlc_video_context_HoldDevice(vctx);
+ *vctx_out = D3D11CreateVideoContext(dec_dev, vctx_sys->format, DXGI_FORMAT_NV12);
+ vlc_decoder_device_Release(dec_dev);
+ if (unlikely(*vctx_out == nullptr))
+ {
+ msg_Dbg(dec,"Failed to create output vctx.");
+ return VLC_EGENERIC;
+ }
+ dec->fmt_out.video.i_chroma = dec->fmt_out.i_codec = VLC_CODEC_D3D11_OPAQUE_ALPHA;
+
+ return VLC_SUCCESS;
+}
=====================================
modules/codec/avcodec/d3d11va.c
=====================================
@@ -292,7 +292,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum AVPixelFormat hwfmt, con
sys->d3d_dev->adapterDesc.VendorId, DxgiVendorStr(sys->d3d_dev->adapterDesc.VendorId),
sys->d3d_dev->adapterDesc.DeviceId, sys->d3d_dev->adapterDesc.Revision);
- sys->vctx = D3D11CreateVideoContext(dec_device, sys->render_fmt->formatTexture);
+ sys->vctx = D3D11CreateVideoContext(dec_device, sys->render_fmt->formatTexture, sys->render_fmt->alphaTexture);
if (sys->vctx == NULL)
{
msg_Dbg(va, "no video context");
@@ -397,17 +397,20 @@ static int DxSetupOutput(vlc_va_t *va, const directx_va_mode_t *mode, const vide
const d3d_format_t *decoder_format;
UINT supportFlags = D3D11_FORMAT_SUPPORT_DECODER_OUTPUT | D3D11_FORMAT_SUPPORT_SHADER_LOAD;
decoder_format = FindD3D11Format( va, sys->d3d_dev, 0, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT,
- mode->bit_depth, mode->log2_chroma_h+1, mode->log2_chroma_w+1,
+ mode->bit_depth, mode->log2_chroma_h+1, mode->log2_chroma_w+1, 0,
DXGI_CHROMA_GPU, supportFlags );
if (decoder_format == NULL)
+ // other chroma sub-sampling
decoder_format = FindD3D11Format( va, sys->d3d_dev, 0, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT,
- mode->bit_depth, 0, 0, DXGI_CHROMA_GPU, supportFlags );
+ mode->bit_depth, 0, 0, 0, DXGI_CHROMA_GPU, supportFlags );
if (decoder_format == NULL && mode->bit_depth > 10)
+ // 10 bits instead of 8/12/14/16
decoder_format = FindD3D11Format( va, sys->d3d_dev, 0, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT,
- 10, 0, 0, DXGI_CHROMA_GPU, supportFlags );
+ 10, 0, 0, 0, DXGI_CHROMA_GPU, supportFlags );
if (decoder_format == NULL)
+ // any bit depth
decoder_format = FindD3D11Format( va, sys->d3d_dev, 0, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT,
- 0, 0, 0, DXGI_CHROMA_GPU, supportFlags );
+ 0, 0, 0, 0, DXGI_CHROMA_GPU, supportFlags );
if (decoder_format != NULL)
{
msg_Dbg(va, "favor decoder format %s", decoder_format->name);
@@ -415,8 +418,8 @@ static int DxSetupOutput(vlc_va_t *va, const directx_va_mode_t *mode, const vide
}
if (decoder_format == NULL || decoder_format->formatTexture != DXGI_FORMAT_NV12)
- processorInput[idx++] = D3D11_RenderFormat(DXGI_FORMAT_NV12 ,true);
- processorInput[idx++] = D3D11_RenderFormat(DXGI_FORMAT_420_OPAQUE ,true);
+ processorInput[idx++] = D3D11_RenderFormat(DXGI_FORMAT_NV12, DXGI_FORMAT_UNKNOWN ,true);
+ processorInput[idx++] = D3D11_RenderFormat(DXGI_FORMAT_420_OPAQUE, DXGI_FORMAT_UNKNOWN ,true);
processorInput[idx++] = NULL;
/* */
=====================================
modules/codec/meson.build
=====================================
@@ -811,9 +811,16 @@ if vpx_dep.found()
endif
# VP8/VP9 with alpha pseudo-decoder
+vpx_alpha_sources = files('vpx_alpha.c')
+vpx_alpha_with = [ ]
+if host_system == 'windows'
+ vpx_alpha_sources += files('alpha_d3d11.cpp')
+ vpx_alpha_with += [ d3d11_common_lib ]
+endif
vlc_modules += {
'name' : 'vpx_alpha',
- 'sources' : files('vpx_alpha.c')
+ 'sources' : vpx_alpha_sources,
+ 'link_with' : vpx_alpha_with
}
=====================================
modules/codec/mft_d3d11.cpp
=====================================
@@ -120,7 +120,7 @@ HRESULT MFHW_d3d11::SetupVideoContext(vlc_logger *logger, ComPtr<IMFDXGIBuffer>
D3D11_TEXTURE2D_DESC desc;
d3d11Res->GetDesc(&desc);
- vctx_out = D3D11CreateVideoContext( dec_dev, desc.Format );
+ vctx_out = D3D11CreateVideoContext( dec_dev, desc.Format, DXGI_FORMAT_UNKNOWN );
if (unlikely(vctx_out == NULL))
{
vlc_error(logger, "failed to create a video context");
@@ -129,7 +129,7 @@ HRESULT MFHW_d3d11::SetupVideoContext(vlc_logger *logger, ComPtr<IMFDXGIBuffer>
fmt_out.video.i_width = desc.Width;
fmt_out.video.i_height = desc.Height;
- cfg = D3D11_RenderFormat(desc.Format ,true);
+ cfg = D3D11_RenderFormat(desc.Format, DXGI_FORMAT_UNKNOWN, true);
fmt_out.i_codec = cfg->fourcc;
fmt_out.video.i_chroma = cfg->fourcc;
=====================================
modules/codec/vpx_alpha.c
=====================================
@@ -17,6 +17,8 @@
#include <vlc_atomic.h>
#include <vlc_picture_pool.h>
+#include "alpha_combine.h"
+
static int OpenDecoder(vlc_object_t *);
static void CloseDecoder(vlc_object_t *);
@@ -202,6 +204,44 @@ static int FormatUpdate( decoder_t *dec, vlc_video_context *vctx )
p_sys->pf_combine = CombinePicturesCPU;
}
break;
+#ifdef _WIN32
+ case VLC_CODEC_D3D11_OPAQUE:
+ if (dec == &p_sys->alpha->dec)
+ {
+ switch (p_sys->opaque->dec.fmt_out.video.i_chroma)
+ {
+ case VLC_CODEC_D3D11_OPAQUE:
+ res = SetupD3D11(bdec, vctx, &p_sys->vctx);
+ if (res == VLC_SUCCESS)
+ {
+ p_sys->pf_combine = CombineD3D11;
+ vctx = p_sys->vctx;
+ }
+ break;
+ default:
+ msg_Err(dec, "unsupported opaque D3D11 combination %4.4s", (char*)&p_sys->opaque->dec.fmt_out.video.i_chroma);
+ res = VLC_EGENERIC;
+ }
+ }
+ else
+ {
+ switch (p_sys->alpha->dec.fmt_out.video.i_chroma)
+ {
+ case VLC_CODEC_D3D11_OPAQUE:
+ res = SetupD3D11(bdec, vctx, &p_sys->vctx);
+ if (res == VLC_SUCCESS)
+ {
+ p_sys->pf_combine = CombineD3D11;
+ vctx = p_sys->vctx;
+ }
+ break;
+ default:
+ msg_Err(dec, "unsupported opaque D3D11 combination %4.4s", (char*)&p_sys->alpha->dec.fmt_out.video.i_chroma);
+ res = VLC_EGENERIC;
+ }
+ }
+ break;
+#endif // _WIN32
default:
msg_Err(dec, "unsupported decoder output %4.4s", (char*)&dec->fmt_out.video.i_chroma);
res = VLC_EGENERIC;
=====================================
modules/hw/d3d11/d3d11_decoder.cpp
=====================================
@@ -112,7 +112,7 @@ static int DecodeFrame( decoder_t *p_dec, block_t *p_block )
D3D11_TEXTURE2D_DESC outDesc;
src_sys->texture[0]->GetDesc(&outDesc);
- p_sys->output_format = D3D11_RenderFormat(outDesc.Format ,true);
+ p_sys->output_format = D3D11_RenderFormat(outDesc.Format, DXGI_FORMAT_UNKNOWN ,true);
if (unlikely(!p_sys->output_format->name))
{
msg_Err(p_dec, "Unknown texture format %d", outDesc.Format);
@@ -124,7 +124,7 @@ static int DecodeFrame( decoder_t *p_dec, block_t *p_block )
if (unlikely(p_sys->vctx == nullptr))
{
p_sys->vctx =
- D3D11CreateVideoContext(p_sys->dec_dev, p_sys->output_format->formatTexture);
+ D3D11CreateVideoContext(p_sys->dec_dev, p_sys->output_format->formatTexture, p_sys->output_format->alphaTexture);
if (!p_sys->vctx)
{
block_Release( p_block );
@@ -277,7 +277,7 @@ int D3D11OpenBlockDecoder( vlc_object_t *obj )
}
p_sys->vctx =
- D3D11CreateVideoContext(p_sys->dec_dev, p_sys->output_format->formatTexture);
+ D3D11CreateVideoContext(p_sys->dec_dev, p_sys->output_format->formatTexture, p_sys->output_format->alphaTexture);
if (!p_sys->vctx)
{
vlc_decoder_device_Release(dec_dev);
=====================================
modules/hw/d3d11/d3d11_deinterlace.c
=====================================
@@ -254,7 +254,7 @@ int D3D11OpenDeinterlace(filter_t *filter)
d3d11_decoder_device_t *dev_sys = GetD3D11OpaqueContext( filter->vctx_in );
sys->d3d_dev = &dev_sys->d3d_dev;
- sys->output_format = D3D11_RenderFormat(vctx_sys->format ,true);
+ sys->output_format = D3D11_RenderFormat(vctx_sys->format, vctx_sys->secondary ,true);
if (unlikely(sys->output_format == NULL))
goto error;
=====================================
modules/hw/d3d11/d3d11_filters.c
=====================================
@@ -188,7 +188,7 @@ static picture_t *AllocPicture( filter_t *p_filter )
{
d3d11_video_context_t *vctx_sys = GetD3D11ContextPrivate( p_filter->vctx_out );
- const d3d_format_t *cfg = D3D11_RenderFormat(vctx_sys->format ,true);
+ const d3d_format_t *cfg = D3D11_RenderFormat(vctx_sys->format, vctx_sys->secondary ,true);
if (unlikely(cfg == NULL))
return NULL;
=====================================
modules/hw/d3d11/d3d11_surface.c
=====================================
@@ -183,7 +183,7 @@ static int assert_staging(filter_t *p_filter, filter_sys_t *sys, DXGI_FORMAT for
/* failed with the this format, try a different one */
UINT supportFlags = D3D11_FORMAT_SUPPORT_SHADER_LOAD | D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT;
const d3d_format_t *new_fmt =
- FindD3D11Format( p_filter, d3d_dev, 0, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0, DXGI_CHROMA_CPU, supportFlags );
+ FindD3D11Format( p_filter, d3d_dev, 0, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0, 0, DXGI_CHROMA_CPU, supportFlags );
if (new_fmt && texDesc.Format != new_fmt->formatTexture)
{
DXGI_FORMAT srcFormat = texDesc.Format;
@@ -623,7 +623,7 @@ static picture_t *AllocateCPUtoGPUTexture(filter_t *p_filter, filter_sys_t *p_sy
d3d11_video_context_t *vctx_sys = GetD3D11ContextPrivate( p_filter->vctx_out );
- const d3d_format_t *cfg = D3D11_RenderFormat(vctx_sys->format ,false);
+ const d3d_format_t *cfg = D3D11_RenderFormat(vctx_sys->format, vctx_sys->secondary ,false);
if (unlikely(cfg == NULL))
return NULL;
@@ -822,7 +822,7 @@ int D3D11OpenCPUConverter( filter_t *p_filter )
default:
vlc_assert_unreachable();
}
- p_filter->vctx_out = D3D11CreateVideoContext(dec_device, vctx_fmt);
+ p_filter->vctx_out = D3D11CreateVideoContext(dec_device, vctx_fmt, DXGI_FORMAT_UNKNOWN);
if ( p_filter->vctx_out == NULL )
{
msg_Dbg(p_filter, "no video context");
=====================================
modules/video_chroma/d3d11_fmt.c
=====================================
@@ -46,13 +46,13 @@
#include <vlc/libvlc_media_player.h>
#define COBJMACROS
-#include <d3d11.h>
-#include <assert.h>
#include <initguid.h>
+#include <d3d11.h>
#include <dxgi1_2.h>
#if !defined(NDEBUG) && defined(HAVE_DXGIDEBUG_H)
# include <dxgidebug.h>
#endif
+#include <assert.h>
#include "d3d11_fmt.h"
@@ -747,6 +747,7 @@ const d3d_format_t *(FindD3D11Format)(vlc_object_t *o,
uint8_t bits_per_channel,
uint8_t widthDenominator,
uint8_t heightDenominator,
+ uint8_t alpha_bits,
int cpu_gpu,
UINT supportFlags)
{
@@ -768,6 +769,10 @@ const d3d_format_t *(FindD3D11Format)(vlc_object_t *o,
continue;
if (heightDenominator && heightDenominator < output_format->heightDenominator)
continue;
+ if (alpha_bits && output_format->bitsForAlpha < alpha_bits)
+ continue;
+ if (alpha_bits == 0 && output_format->bitsForAlpha != 0)
+ continue;
DXGI_FORMAT textureFormat;
if (output_format->formatTexture == DXGI_FORMAT_UNKNOWN)
@@ -952,7 +957,7 @@ const struct vlc_video_context_operations d3d11_vctx_ops = {
NULL,
};
-vlc_video_context *D3D11CreateVideoContext(vlc_decoder_device *dec_dev, DXGI_FORMAT vctx_fmt)
+vlc_video_context *D3D11CreateVideoContext(vlc_decoder_device *dec_dev, DXGI_FORMAT vctx_fmt, DXGI_FORMAT alpha)
{
vlc_video_context *vctx = vlc_video_context_Create( dec_dev, VLC_VIDEO_CONTEXT_D3D11VA,
sizeof(d3d11_video_context_t), &d3d11_vctx_ops );
@@ -961,6 +966,7 @@ vlc_video_context *D3D11CreateVideoContext(vlc_decoder_device *dec_dev, DXGI_FOR
d3d11_video_context_t *priv = GetD3D11ContextPrivate(vctx);
priv->format = vctx_fmt;
+ priv->secondary = alpha;
return vctx;
}
=====================================
modules/video_chroma/d3d11_fmt.h
=====================================
@@ -100,6 +100,7 @@ typedef struct
typedef struct
{
DXGI_FORMAT format;
+ DXGI_FORMAT secondary; // alpha source in combined formats
} d3d11_video_context_t;
/* index to use for texture/resource that use a known DXGI format
@@ -111,7 +112,8 @@ static inline bool is_d3d11_opaque(vlc_fourcc_t chroma)
return chroma == VLC_CODEC_D3D11_OPAQUE ||
chroma == VLC_CODEC_D3D11_OPAQUE_10B ||
chroma == VLC_CODEC_D3D11_OPAQUE_RGBA ||
- chroma == VLC_CODEC_D3D11_OPAQUE_BGRA;
+ chroma == VLC_CODEC_D3D11_OPAQUE_BGRA ||
+ chroma == VLC_CODEC_D3D11_OPAQUE_ALPHA;
}
extern const struct vlc_video_context_operations d3d11_vctx_ops;
@@ -145,18 +147,19 @@ static inline d3d11_video_context_t *GetD3D11ContextPrivate(vlc_video_context *v
return (d3d11_video_context_t *) vlc_video_context_GetPrivate( vctx, VLC_VIDEO_CONTEXT_D3D11VA );
}
-vlc_video_context *D3D11CreateVideoContext(vlc_decoder_device *, DXGI_FORMAT);
+vlc_video_context *D3D11CreateVideoContext(vlc_decoder_device *, DXGI_FORMAT, DXGI_FORMAT);
void AcquireD3D11PictureSys(picture_sys_d3d11_t *p_sys);
void ReleaseD3D11PictureSys(picture_sys_d3d11_t *p_sys);
-static inline const d3d_format_t *D3D11_RenderFormat(DXGI_FORMAT opaque, bool gpu_based)
+static inline const d3d_format_t *D3D11_RenderFormat(DXGI_FORMAT opaque, DXGI_FORMAT alpha, bool gpu_based)
{
for (const d3d_format_t *output_format = DxgiGetRenderFormatList();
output_format->name != NULL; ++output_format)
{
if (output_format->formatTexture == opaque &&
+ output_format->alphaTexture == alpha &&
is_d3d11_opaque(output_format->fourcc) == gpu_based)
{
return output_format;
@@ -194,10 +197,11 @@ const d3d_format_t *FindD3D11Format(vlc_object_t *,
uint8_t bits_per_channel,
uint8_t widthDenominator,
uint8_t heightDenominator,
+ uint8_t alpha_bits,
int cpu_gpu,
UINT supportFlags);
-#define FindD3D11Format(a,b,c,d,e,f,g,h,i) \
- FindD3D11Format(VLC_OBJECT(a),b,c,d,e,f,g,h,i)
+#define FindD3D11Format(a,b,c,d,e,f,g,h,i,j) \
+ FindD3D11Format(VLC_OBJECT(a),b,c,d,e,f,g,h,i,j)
int AllocateTextures(vlc_object_t *, d3d11_device_t *, const d3d_format_t *,
const video_format_t *, bool, ID3D11Texture2D *textures[],
=====================================
modules/video_chroma/dxgi_fmt.c
=====================================
@@ -66,43 +66,45 @@ static const dxgi_format_t dxgi_formats[] = {
};
static const d3d_format_t d3d_formats[] = {
- { "NV12", DXGI_FORMAT_NV12, VLC_CODEC_NV12, 8, 2, 2, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM } },
- { "VA_NV12", DXGI_FORMAT_NV12, VLC_CODEC_D3D11_OPAQUE, 8, 2, 2, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM } },
- { "P010", DXGI_FORMAT_P010, VLC_CODEC_P010, 10, 2, 2, 1, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16G16_UNORM } },
- { "VA_P010", DXGI_FORMAT_P010, VLC_CODEC_D3D11_OPAQUE_10B, 10, 2, 2, 1, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16G16_UNORM } },
- { "VA_AYUV", DXGI_FORMAT_AYUV, VLC_CODEC_D3D11_OPAQUE, 8, 1, 1, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
- { "YUY2", DXGI_FORMAT_YUY2, VLC_CODEC_YUYV, 8, 1, 2, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
- { "VA_YUY2", DXGI_FORMAT_YUY2, VLC_CODEC_D3D11_OPAQUE, 8, 1, 2, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
+ { "NV12", DXGI_FORMAT_NV12, DXGI_FORMAT_UNKNOWN, VLC_CODEC_NV12, 8, 2, 2, 0, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM } },
+ { "VA_NV12", DXGI_FORMAT_NV12, DXGI_FORMAT_UNKNOWN, VLC_CODEC_D3D11_OPAQUE, 8, 2, 2, 0, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM } },
+ { "VA_NV12A", DXGI_FORMAT_NV12, DXGI_FORMAT_NV12, VLC_CODEC_D3D11_OPAQUE_ALPHA,8, 2, 2, 8, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8_UNORM } },
+ { "P010", DXGI_FORMAT_P010, DXGI_FORMAT_UNKNOWN, VLC_CODEC_P010, 10, 2, 2, 0, 1, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16G16_UNORM } },
+ { "VA_P010", DXGI_FORMAT_P010, DXGI_FORMAT_UNKNOWN, VLC_CODEC_D3D11_OPAQUE_10B, 10, 2, 2, 0, 1, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16G16_UNORM } },
+ { "VA_AYUV", DXGI_FORMAT_AYUV, DXGI_FORMAT_UNKNOWN, VLC_CODEC_D3D11_OPAQUE, 8, 1, 1, 8, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
+ { "YUY2", DXGI_FORMAT_YUY2, DXGI_FORMAT_UNKNOWN, VLC_CODEC_YUYV, 8, 1, 2, 0, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
+ { "VA_YUY2", DXGI_FORMAT_YUY2, DXGI_FORMAT_UNKNOWN, VLC_CODEC_D3D11_OPAQUE, 8, 1, 2, 0, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
#ifdef BROKEN_PIXEL
- { "Y416", DXGI_FORMAT_Y416, VLC_CODEC_I444_16L, 16, 1, 1, 1, { DXGI_FORMAT_R16G16B16A16_UINT } },
+ { "Y416", DXGI_FORMAT_Y416, DXGI_FORMAT_UNKNOWN, VLC_CODEC_I444_16L, 16, 1, 1, 16, 1, { DXGI_FORMAT_R16G16B16A16_UNORM } },
#endif
- { "VA_Y210", DXGI_FORMAT_Y210, VLC_CODEC_D3D11_OPAQUE_10B, 10, 1, 2, 1, { DXGI_FORMAT_R16G16B16A16_UNORM } },
- { "VA_Y410", DXGI_FORMAT_Y410, VLC_CODEC_D3D11_OPAQUE_10B, 10, 1, 1, 1, { DXGI_FORMAT_R10G10B10A2_UNORM } },
+ { "VA_Y210", DXGI_FORMAT_Y210, DXGI_FORMAT_UNKNOWN, VLC_CODEC_D3D11_OPAQUE_10B, 10, 1, 2, 0, 1, { DXGI_FORMAT_R16G16B16A16_UNORM } },
+ { "VA_Y410", DXGI_FORMAT_Y410, DXGI_FORMAT_UNKNOWN, VLC_CODEC_D3D11_OPAQUE_10B, 10, 1, 1, 0, 1, { DXGI_FORMAT_R10G10B10A2_UNORM } },
#ifdef UNTESTED
- { "Y210", DXGI_FORMAT_Y210, VLC_CODEC_I422_10L, 10, 1, 2, 1, { DXGI_FORMAT_R16G16B16A16_UNORM } },
- { "Y410", DXGI_FORMAT_Y410, VLC_CODEC_I444, 10, 1, 1, 1, { DXGI_FORMAT_R10G10B10A2_UNORM } },
- { "NV11", DXGI_FORMAT_NV11, VLC_CODEC_I411, 8, 4, 1, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM} },
+ { "Y210", DXGI_FORMAT_Y210, DXGI_FORMAT_UNKNOWN, VLC_CODEC_I422_10L, 10, 1, 2, 0, 1, { DXGI_FORMAT_R16G16B16A16_UNORM } },
+ { "Y410", DXGI_FORMAT_Y410, DXGI_FORMAT_UNKNOWN, VLC_CODEC_I444, 10, 1, 1, 0, 1, { DXGI_FORMAT_R10G10B10A2_UNORM } },
+ { "NV11", DXGI_FORMAT_NV11, DXGI_FORMAT_UNKNOWN, VLC_CODEC_I411, 8, 4, 1, 0, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM} },
#endif
- { "I420", DXGI_FORMAT_UNKNOWN, VLC_CODEC_I420, 8, 2, 2, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM } },
- { "I420_10", DXGI_FORMAT_UNKNOWN, VLC_CODEC_I420_10L, 10, 2, 2, 1, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM } },
- { "YUVA", DXGI_FORMAT_UNKNOWN, VLC_CODEC_YUVA, 8, 1, 1, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM } },
- { "I444", DXGI_FORMAT_UNKNOWN, VLC_CODEC_I444, 8, 1, 1, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM } },
- { "I444_10", DXGI_FORMAT_UNKNOWN, VLC_CODEC_I444_10L, 10, 1, 1, 1 << 6, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM } },
- { "I444_12", DXGI_FORMAT_UNKNOWN, VLC_CODEC_I444_12L, 10, 1, 1, 1 << 4, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM } },
- { "I444_16", DXGI_FORMAT_UNKNOWN, VLC_CODEC_I444_16L, 16, 1, 1, 1, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM } },
- { "B8G8R8A8", DXGI_FORMAT_B8G8R8A8_UNORM, VLC_CODEC_BGRA, 8, 1, 1, 1, { DXGI_FORMAT_B8G8R8A8_UNORM } },
- { "VA_BGRA", DXGI_FORMAT_B8G8R8A8_UNORM, VLC_CODEC_D3D11_OPAQUE_BGRA, 8, 1, 1, 1, { DXGI_FORMAT_B8G8R8A8_UNORM } },
- { "R8G8B8A8", DXGI_FORMAT_R8G8B8A8_UNORM, VLC_CODEC_RGBA, 8, 1, 1, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
- { "VA_RGBA", DXGI_FORMAT_R8G8B8A8_UNORM, VLC_CODEC_D3D11_OPAQUE_RGBA, 8, 1, 1, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
- { "R8G8B8X8", DXGI_FORMAT_B8G8R8X8_UNORM, VLC_CODEC_BGRX , 8, 1, 1, 1, { DXGI_FORMAT_B8G8R8X8_UNORM } },
- { "RGBA64", DXGI_FORMAT_R16G16B16A16_UNORM, VLC_CODEC_RGBA64, 16, 1, 1, 1, { DXGI_FORMAT_R16G16B16A16_UNORM } },
- { "RGB10A2", DXGI_FORMAT_R10G10B10A2_UNORM, VLC_CODEC_RGBA10LE, 10, 1, 1, 1, { DXGI_FORMAT_R10G10B10A2_UNORM } },
- { "VA_RGB10", DXGI_FORMAT_R10G10B10A2_UNORM, VLC_CODEC_D3D11_OPAQUE_RGBA, 10, 1, 1, 1, { DXGI_FORMAT_R10G10B10A2_UNORM } },
- { "AYUV", DXGI_FORMAT_AYUV, VLC_CODEC_VUYA, 8, 1, 1, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
- { "B5G6R5", DXGI_FORMAT_B5G6R5_UNORM, VLC_CODEC_RGB565LE, 5, 1, 1, 1, { DXGI_FORMAT_B5G6R5_UNORM } },
- { "I420_OPAQUE", DXGI_FORMAT_420_OPAQUE, VLC_CODEC_D3D11_OPAQUE, 8, 2, 2, 1, { DXGI_FORMAT_UNKNOWN } },
-
- { NULL, 0, 0, 0, 0, 0, 0, { DXGI_FORMAT_UNKNOWN } }
+ { "I420", DXGI_FORMAT_UNKNOWN,DXGI_FORMAT_UNKNOWN, VLC_CODEC_I420, 8, 2, 2, 0, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM } },
+ { "I420_10", DXGI_FORMAT_UNKNOWN,DXGI_FORMAT_UNKNOWN, VLC_CODEC_I420_10L, 10, 2, 2, 0, 1, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM } },
+ { "I40A", DXGI_FORMAT_UNKNOWN,DXGI_FORMAT_UNKNOWN, VLC_CODEC_YUV420A, 8, 2, 2, 8, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM } },
+ { "YUVA", DXGI_FORMAT_UNKNOWN,DXGI_FORMAT_UNKNOWN, VLC_CODEC_YUVA, 8, 1, 1, 8, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM } },
+ { "I444", DXGI_FORMAT_UNKNOWN,DXGI_FORMAT_UNKNOWN, VLC_CODEC_I444, 8, 1, 1, 0, 1, { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM } },
+ { "I444_10", DXGI_FORMAT_UNKNOWN,DXGI_FORMAT_UNKNOWN, VLC_CODEC_I444_10L, 10, 1, 1, 0, 1 << 6, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM } },
+ { "I444_12", DXGI_FORMAT_UNKNOWN,DXGI_FORMAT_UNKNOWN, VLC_CODEC_I444_12L, 10, 1, 1, 0, 1 << 4, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM } },
+ { "I444_16", DXGI_FORMAT_UNKNOWN,DXGI_FORMAT_UNKNOWN, VLC_CODEC_I444_16L, 16, 1, 1, 0, 1, { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM } },
+ { "B8G8R8A8", DXGI_FORMAT_B8G8R8A8_UNORM,DXGI_FORMAT_UNKNOWN, VLC_CODEC_BGRA, 8, 1, 1, 8, 1, { DXGI_FORMAT_B8G8R8A8_UNORM } },
+ { "VA_BGRA", DXGI_FORMAT_B8G8R8A8_UNORM,DXGI_FORMAT_UNKNOWN, VLC_CODEC_D3D11_OPAQUE_BGRA, 8, 1, 1, 8, 1, { DXGI_FORMAT_B8G8R8A8_UNORM } },
+ { "R8G8B8A8", DXGI_FORMAT_R8G8B8A8_UNORM,DXGI_FORMAT_UNKNOWN, VLC_CODEC_RGBA, 8, 1, 1, 8, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
+ { "VA_RGBA", DXGI_FORMAT_R8G8B8A8_UNORM,DXGI_FORMAT_UNKNOWN, VLC_CODEC_D3D11_OPAQUE_RGBA, 8, 1, 1, 8, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
+ { "R8G8B8X8", DXGI_FORMAT_B8G8R8X8_UNORM,DXGI_FORMAT_UNKNOWN, VLC_CODEC_BGRX , 8, 1, 1, 0, 1, { DXGI_FORMAT_B8G8R8X8_UNORM } },
+ { "RGBA64", DXGI_FORMAT_R16G16B16A16_UNORM,DXGI_FORMAT_UNKNOWN, VLC_CODEC_RGBA64, 16, 1, 1, 16, 1, { DXGI_FORMAT_R16G16B16A16_UNORM } },
+ { "RGB10A2", DXGI_FORMAT_R10G10B10A2_UNORM,DXGI_FORMAT_UNKNOWN, VLC_CODEC_RGBA10LE, 10, 1, 1, 2, 1, { DXGI_FORMAT_R10G10B10A2_UNORM } },
+ { "VA_RGB10", DXGI_FORMAT_R10G10B10A2_UNORM,DXGI_FORMAT_UNKNOWN, VLC_CODEC_D3D11_OPAQUE_RGBA, 10, 1, 1, 2, 1, { DXGI_FORMAT_R10G10B10A2_UNORM } },
+ { "AYUV", DXGI_FORMAT_AYUV, DXGI_FORMAT_UNKNOWN, VLC_CODEC_VUYA, 8, 1, 1, 8, 1, { DXGI_FORMAT_R8G8B8A8_UNORM } },
+ { "B5G6R5", DXGI_FORMAT_B5G6R5_UNORM,DXGI_FORMAT_UNKNOWN, VLC_CODEC_RGB565LE, 5, 1, 1, 0, 1, { DXGI_FORMAT_B5G6R5_UNORM } },
+ { "I420_OPAQUE", DXGI_FORMAT_420_OPAQUE,DXGI_FORMAT_UNKNOWN, VLC_CODEC_D3D11_OPAQUE, 8, 2, 2, 0, 1, { DXGI_FORMAT_UNKNOWN } },
+
+ { NULL, 0, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, 0, 0, 0, 0, 0, { DXGI_FORMAT_UNKNOWN } }
};
const char *DxgiFormatToStr(DXGI_FORMAT format)
=====================================
modules/video_chroma/dxgi_fmt.h
=====================================
@@ -46,10 +46,12 @@ typedef struct
{
const char *name;
DXGI_FORMAT formatTexture;
+ DXGI_FORMAT alphaTexture;
vlc_fourcc_t fourcc;
uint8_t bitsPerChannel;
uint8_t widthDenominator;
uint8_t heightDenominator;
+ uint8_t bitsForAlpha;
uint8_t resourceFactor; // the plane depth doesn't match the resource depth
DXGI_FORMAT resourceFormat[DXGI_MAX_SHADER_VIEW];
} d3d_format_t;
@@ -63,8 +65,8 @@ UINT DxgiResourceCount(const d3d_format_t *);
bool DxgiIsRGBFormat(const d3d_format_t *);
-#define DXGI_RGB_FORMAT 1
-#define DXGI_YUV_FORMAT 2
+#define DXGI_RGB_FORMAT (1 << 0)
+#define DXGI_YUV_FORMAT (1 << 1)
#define DXGI_CHROMA_CPU 1
#define DXGI_CHROMA_GPU 2
=====================================
modules/video_output/win32/d3d11_quad.cpp
=====================================
@@ -362,6 +362,7 @@ void d3d11_quad_t::UpdateViewport(const RECT *rect, const d3d_format_t *display)
/* fallthrough */
case VLC_CODEC_I420_10L:
case VLC_CODEC_I420:
+ case VLC_CODEC_YUV420A:
cropViewport[1].TopLeftX = cropViewport[0].TopLeftX / 2;
cropViewport[1].TopLeftY = cropViewport[0].TopLeftY / 2;
cropViewport[1].Width = cropViewport[0].Width / 2;
=====================================
modules/video_output/win32/d3d11_scaler.cpp
=====================================
@@ -40,7 +40,7 @@ struct d3d11_scaler
static const d3d_format_t *GetDirectRenderingFormat(vlc_object_t *vd, d3d11_device_t *d3d_dev, vlc_fourcc_t i_src_chroma)
{
UINT supportFlags = D3D11_FORMAT_SUPPORT_SHADER_LOAD | D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_INPUT;
- return FindD3D11Format( vd, d3d_dev, i_src_chroma, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0,
+ return (FindD3D11Format)( vd, d3d_dev, i_src_chroma, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0, 0,
DXGI_CHROMA_CPU|DXGI_CHROMA_GPU, supportFlags );
}
=====================================
modules/video_output/win32/d3d11_swapchain.cpp
=====================================
@@ -84,12 +84,19 @@ static bool UpdateSwapchain( d3d11_local_swapchain *display, const libvlc_video_
/* favor RGB formats first */
newPixelFormat = FindD3D11Format( display->obj, display->d3d_dev, 0, DXGI_RGB_FORMAT,
cfg->bitdepth > 8 ? 10 : 8,
- 0, 0,
+ 0, 0, 0,
DXGI_CHROMA_CPU, D3D11_FORMAT_SUPPORT_DISPLAY );
if (unlikely(newPixelFormat == NULL))
+ // try with alpha
+ newPixelFormat = FindD3D11Format( display->obj, display->d3d_dev, 0, DXGI_RGB_FORMAT,
+ cfg->bitdepth > 8 ? 10 : 8,
+ 0, 0, 8,
+ DXGI_CHROMA_CPU, D3D11_FORMAT_SUPPORT_DISPLAY );
+ if (unlikely(newPixelFormat == NULL))
+ // try YUV without alpha
newPixelFormat = FindD3D11Format( display->obj, display->d3d_dev, 0, DXGI_YUV_FORMAT,
cfg->bitdepth > 8 ? 10 : 8,
- 0, 0,
+ 0, 0, 0,
DXGI_CHROMA_CPU, D3D11_FORMAT_SUPPORT_DISPLAY );
if (unlikely(newPixelFormat == NULL)) {
msg_Err(display->obj, "Could not get the SwapChain format.");
=====================================
modules/video_output/win32/d3d_dynamic_shader.c
=====================================
@@ -90,6 +90,7 @@ struct PS_INPUT\n\
#define SAMPLE_RGBA_TO_NV_GB 13\n\
#define SAMPLE_PLANAR_YUVA_TO_NV_Y 14\n\
#define SAMPLE_PLANAR_YUVA_TO_NV_UV 15\n\
+#define SAMPLE_NV12A_TO_YUVA 16\n\
\n\
#if (TONE_MAPPING==TONE_MAP_HABLE)\n\
/* see http://filmicworlds.com/blog/filmic-tonemapping-operators/ */\n\
@@ -177,6 +178,10 @@ inline float4 sampleTexture(SamplerState samplerState, float2 coords) {\n\
sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n\
sample.yz = shaderTexture[1].Sample(samplerState, coords).xy;\n\
sample.a = 1;\n\
+#elif (SAMPLE_TEXTURES==SAMPLE_NV12A_TO_YUVA)\n\
+ sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n\
+ sample.yz = shaderTexture[1].Sample(samplerState, coords).xy;\n\
+ sample.a = shaderTexture[2].Sample(samplerState, coords).x;\n\
#elif (SAMPLE_TEXTURES==SAMPLE_YUY2_TO_YUVA)\n\
sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n\
sample.y = shaderTexture[0].Sample(samplerState, coords).y;\n\
@@ -254,11 +259,13 @@ float4 main( PS_INPUT In ) : SV_TARGET\n\
sample = sampleTexture( borderSampler, In.uv );\n\
else\n\
sample = sampleTexture( normalSampler, In.uv );\n\
+ float srcAlpha = saturate(sample.a * Opacity);\n\
+ sample.a = 1.0;\n\
float3 rgb = max(mul(sample, Colorspace),0);\n\
rgb = sourceToLinear(rgb);\n\
rgb = toneMapping(rgb);\n\
rgb = linearToDisplay(rgb);\n\
- return float4(rgb, saturate(sample.a * Opacity));\n\
+ return float4(rgb, srcAlpha);\n\
}\n\
";
@@ -479,8 +486,19 @@ HRESULT (D3D_CompilePixelShader)(vlc_object_t *o, const d3d_shader_compiler_t *c
{
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_P010:
- psz_sampler[0] = "SAMPLE_NV12_TO_YUVA";
- psz_shader_resource_views[0] = "2"; shader_views[0] = 2;
+ switch(dxgi_fmt->alphaTexture)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ psz_sampler[0] = "SAMPLE_NV12_TO_YUVA";
+ psz_shader_resource_views[0] = "2"; shader_views[0] = 2;
+ break;
+ case DXGI_FORMAT_NV12:
+ psz_sampler[0] = "SAMPLE_NV12A_TO_YUVA";
+ psz_shader_resource_views[0] = "4"; shader_views[0] = 4;
+ break;
+ default:
+ vlc_assert_unreachable();
+ }
break;
case DXGI_FORMAT_YUY2:
psz_sampler[0] = "SAMPLE_YUY2_TO_YUVA";
@@ -523,6 +541,7 @@ HRESULT (D3D_CompilePixelShader)(vlc_object_t *o, const d3d_shader_compiler_t *c
psz_shader_resource_views[0] = "3"; shader_views[0] = 3;
break;
case VLC_CODEC_YUVA:
+ case VLC_CODEC_YUV420A:
psz_sampler[0] = "SAMPLE_PLANAR_YUVA_TO_YUVA";
psz_shader_resource_views[0] = "4"; shader_views[0] = 4;
break;
=====================================
modules/video_output/win32/direct3d11.cpp
=====================================
@@ -168,6 +168,7 @@ static int UpdateDisplayFormat(vout_display_t *vd, const video_format_t *fmt)
switch (fmt->i_chroma)
{
case VLC_CODEC_D3D11_OPAQUE:
+ case VLC_CODEC_D3D11_OPAQUE_ALPHA:
cfg.bitdepth = 8;
break;
case VLC_CODEC_D3D11_OPAQUE_RGBA:
@@ -215,7 +216,7 @@ static int UpdateDisplayFormat(vout_display_t *vd, const video_format_t *fmt)
display_info_t new_display = { };
- new_display.pixelFormat = D3D11_RenderFormat((DXGI_FORMAT)out.dxgi_format, false);
+ new_display.pixelFormat = D3D11_RenderFormat((DXGI_FORMAT)out.dxgi_format, DXGI_FORMAT_UNKNOWN, false);
if (unlikely(new_display.pixelFormat == NULL))
{
msg_Err(vd, "Could not find the output format.");
@@ -741,7 +742,7 @@ static const d3d_format_t *GetDirectRenderingFormat(vout_display_t *vd, vlc_four
UINT supportFlags = D3D11_FORMAT_SUPPORT_SHADER_LOAD;
if (is_d3d11_opaque(i_src_chroma))
supportFlags |= D3D11_FORMAT_SUPPORT_DECODER_OUTPUT;
- return FindD3D11Format( vd, sys->d3d_dev, i_src_chroma, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0,
+ return FindD3D11Format( vd, sys->d3d_dev, i_src_chroma, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0, 0,
is_d3d11_opaque(i_src_chroma) ? DXGI_CHROMA_GPU : DXGI_CHROMA_CPU, supportFlags );
}
@@ -750,13 +751,14 @@ static const d3d_format_t *GetDirectDecoderFormat(vout_display_t *vd, vlc_fourcc
vout_display_sys_t *sys = static_cast<vout_display_sys_t *>(vd->sys);
UINT supportFlags = D3D11_FORMAT_SUPPORT_DECODER_OUTPUT;
- return FindD3D11Format( vd, sys->d3d_dev, i_src_chroma, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0,
+ return FindD3D11Format( vd, sys->d3d_dev, i_src_chroma, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0, 0,
DXGI_CHROMA_GPU, supportFlags );
}
static const d3d_format_t *GetDisplayFormatByDepth(vout_display_t *vd, uint8_t bit_depth,
uint8_t widthDenominator,
uint8_t heightDenominator,
+ uint8_t alpha_bits,
bool from_processor,
int rgb_yuv)
{
@@ -766,7 +768,7 @@ static const d3d_format_t *GetDisplayFormatByDepth(vout_display_t *vd, uint8_t b
if (from_processor)
supportFlags |= D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT;
return FindD3D11Format( vd, sys->d3d_dev, 0, rgb_yuv,
- bit_depth, widthDenominator+1, heightDenominator+1,
+ bit_depth, widthDenominator+1, heightDenominator+1, alpha_bits,
DXGI_CHROMA_CPU, supportFlags );
}
@@ -775,7 +777,7 @@ static const d3d_format_t *GetBlendableFormat(vout_display_t *vd, vlc_fourcc_t i
vout_display_sys_t *sys = static_cast<vout_display_sys_t *>(vd->sys);
UINT supportFlags = D3D11_FORMAT_SUPPORT_SHADER_LOAD | D3D11_FORMAT_SUPPORT_BLENDABLE;
- return FindD3D11Format( vd, sys->d3d_dev, i_src_chroma, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0, DXGI_CHROMA_CPU, supportFlags );
+ return FindD3D11Format( vd, sys->d3d_dev, i_src_chroma, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0, 8, DXGI_CHROMA_CPU, supportFlags );
}
static void InitScaleProcessor(vout_display_t *vd)
@@ -896,7 +898,7 @@ static int SetupOutputFormat(vout_display_t *vd, video_format_t *fmt, vlc_video_
if (vtcx_sys != NULL &&
D3D11_DeviceSupportsFormat( sys->d3d_dev, vtcx_sys->format, D3D11_FORMAT_SUPPORT_SHADER_LOAD ))
{
- sys->picQuad.generic.textureFormat = D3D11_RenderFormat(vtcx_sys->format ,true);
+ sys->picQuad.generic.textureFormat = D3D11_RenderFormat(vtcx_sys->format, vtcx_sys->secondary ,true);
}
// look for the requested pixel format first
@@ -909,6 +911,7 @@ static int SetupOutputFormat(vout_display_t *vd, video_format_t *fmt, vlc_video_
{
uint8_t bits_per_channel;
uint8_t widthDenominator, heightDenominator;
+ uint8_t alpha_bits = 0;
vlc_fourcc_t cpu_chroma;
if (is_d3d11_opaque(fmt->i_chroma))
cpu_chroma = DxgiFormatFourcc(vtcx_sys->format);
@@ -935,6 +938,37 @@ static int SetupOutputFormat(vout_display_t *vd, video_format_t *fmt, vlc_video_
if (heightDenominator < p_format->p[i].h.den)
heightDenominator = p_format->p[1].h.den;
}
+
+ switch (cpu_chroma) // FIXME get this info from the core
+ {
+ case VLC_CODEC_YUVA:
+ case VLC_CODEC_YUV422A:
+ case VLC_CODEC_YUV420A:
+ case VLC_CODEC_VUYA:
+ case VLC_CODEC_RGBA:
+ case VLC_CODEC_ARGB:
+ case VLC_CODEC_BGRA:
+ case VLC_CODEC_ABGR:
+ case VLC_CODEC_D3D11_OPAQUE_RGBA:
+ case VLC_CODEC_D3D11_OPAQUE_BGRA:
+ case VLC_CODEC_D3D11_OPAQUE_ALPHA:
+ alpha_bits = 8;
+ break;
+ case VLC_CODEC_YUVA_444_10L:
+ case VLC_CODEC_YUVA_444_10B:
+ alpha_bits = 10;
+ break;
+ case VLC_CODEC_RGBA10LE:
+ alpha_bits = 2;
+ break;
+ case VLC_CODEC_YUVA_444_12L:
+ case VLC_CODEC_YUVA_444_12B:
+ alpha_bits = 12;
+ break;
+ case VLC_CODEC_RGBA64:
+ alpha_bits = 16;
+ break;
+ }
}
/* look for a decoder format that can be decoded but not used in shaders */
@@ -943,19 +977,19 @@ static int SetupOutputFormat(vout_display_t *vd, video_format_t *fmt, vlc_video_
bool is_rgb = !vlc_fourcc_IsYUV(fmt->i_chroma);
sys->picQuad.generic.textureFormat = GetDisplayFormatByDepth(vd, bits_per_channel,
- widthDenominator, heightDenominator,
+ widthDenominator, heightDenominator, alpha_bits,
decoder_format!=nullptr,
is_rgb ? DXGI_RGB_FORMAT : DXGI_YUV_FORMAT);
if (!sys->picQuad.generic.textureFormat)
sys->picQuad.generic.textureFormat = GetDisplayFormatByDepth(vd, bits_per_channel,
- widthDenominator, heightDenominator,
+ widthDenominator, heightDenominator, alpha_bits,
decoder_format!=nullptr,
is_rgb ? DXGI_YUV_FORMAT : DXGI_RGB_FORMAT);
}
// look for any pixel format that we can handle
if ( !sys->picQuad.generic.textureFormat )
- sys->picQuad.generic.textureFormat = GetDisplayFormatByDepth(vd, 0, 0, 0, false, DXGI_YUV_FORMAT|DXGI_RGB_FORMAT);
+ sys->picQuad.generic.textureFormat = GetDisplayFormatByDepth(vd, 0, 0, 0, 0, true, DXGI_YUV_FORMAT|DXGI_RGB_FORMAT);
if ( !sys->picQuad.generic.textureFormat )
{
=====================================
src/misc/fourcc.c
=====================================
@@ -818,6 +818,9 @@ static const vlc_chroma_description_t p_list_chroma_description[] = {
{ VLC_CODEC_D3D11_OPAQUE_RGBA, FAKE_FMT() },
{ VLC_CODEC_D3D11_OPAQUE_BGRA, FAKE_FMT() },
+ { { VLC_CODEC_D3D11_OPAQUE_ALPHA },
+ FAKE_FMT() },
+
{ VLC_CODEC_NVDEC_OPAQUE_16B, FAKE_FMT() },
{ VLC_CODEC_NVDEC_OPAQUE_10B, FAKE_FMT() },
{ VLC_CODEC_NVDEC_OPAQUE, FAKE_FMT() },
=====================================
src/misc/fourcc_list.h
=====================================
@@ -1262,6 +1262,9 @@ static const staticentry_t p_list_video[] = {
B(VLC_CODEC_D3D11_OPAQUE_BGRA, "BGRA D3D11 opaque"),
A("DAGR"),
+ B(VLC_CODEC_D3D11_OPAQUE_ALPHA, "4:2:0 D3D11 opaque with alpha"),
+ A("DA11"),
+
B(VLC_CODEC_NVDEC_OPAQUE, "4:2:0 NVDEC opaque"),
A("NVD8"),
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/81ce022fae048e4d5a17a08f7d15cea68d68adeb...f95c9c6aa692f8cb9ec56a637795d0cd65dc5ee4
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/81ce022fae048e4d5a17a08f7d15cea68d68adeb...f95c9c6aa692f8cb9ec56a637795d0cd65dc5ee4
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list