You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

103 lines
3.5 KiB

// 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@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;
}