[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