4#include <Gfx/Graph/decoders/ColorSpace.hpp>
5#include <Gfx/Graph/decoders/GPUVideoDecoder.hpp>
6#include <Gfx/Graph/decoders/NV12.hpp>
7#include <Gfx/Graph/decoders/P010.hpp>
8#include <Video/GpuFormats.hpp>
10#include <QtGui/private/qrhid3d11_p.h>
13#include <libavformat/avformat.h>
14#if __has_include(<libavutil/hwcontext_d3d11va.h>)
15#include <libavutil/hwcontext_d3d11va.h>
16#define SCORE_HAS_D3D11_HWCONTEXT 1
20#if defined(SCORE_HAS_D3D11_HWCONTEXT)
39struct HWD3D11Decoder : GPUVideoDecoder
42 PixelFormatInfo m_fmt;
44 ID3D11Device* m_dev{};
45 ID3D11DeviceContext* m_ctx{};
46 ID3D11Texture2D* m_nv12Tex{};
49 static bool isAvailable(QRhi& rhi)
51 return rhi.backend() == QRhi::D3D11;
54 explicit HWD3D11Decoder(
59 auto* nh =
static_cast<const QRhiD3D11NativeHandles*
>(rhi.nativeHandles());
60 m_dev =
static_cast<ID3D11Device*
>(nh->dev);
61 m_dev->GetImmediateContext(&m_ctx);
64 ~HWD3D11Decoder()
override
74 const int w = decoder.width, h = decoder.height;
75 DXGI_FORMAT nv12Fmt = m_fmt.is10bit() ? DXGI_FORMAT_P010 : DXGI_FORMAT_NV12;
77 D3D11_TEXTURE2D_DESC desc{};
82 desc.Format = nv12Fmt;
83 desc.SampleDesc.Count = 1;
84 desc.Usage = D3D11_USAGE_DEFAULT;
85 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
86 if(FAILED(m_dev->CreateTexture2D(&desc,
nullptr, &m_nv12Tex)))
88 qDebug() <<
"HWD3D11Decoder: failed to create NV12 copy texture"
89 << w <<
"x" << h <<
"fmt:" << nv12Fmt;
97 std::pair<QShader, QShader> init(RenderList& r)
override
99 auto& rhi = *r.state.rhi;
100 const int w = decoder.width, h = decoder.height;
101 auto texFmt = m_fmt.is10bit() ? QRhiTexture::R16 : QRhiTexture::R8;
102 auto uvTexFmt = m_fmt.is10bit() ? QRhiTexture::RG16 : QRhiTexture::RG8;
105 auto tex = rhi.newTexture(texFmt, {w, h}, 1, QRhiTexture::Flag{});
107 auto sampler = rhi.newSampler(
108 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
109 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
111 samplers.push_back({sampler, tex});
114 auto tex = rhi.newTexture(uvTexFmt, {w / 2, h / 2}, 1, QRhiTexture::Flag{});
116 auto sampler = rhi.newSampler(
117 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
118 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
120 samplers.push_back({sampler, tex});
127 r.state, vertexShader(),
128 QString(P010Decoder::frag).arg(
"").arg(colorMatrix(decoder)));
130 QString frag = NV12Decoder::nv12_filter_prologue;
131 frag +=
" vec3 yuv = vec3(y, u, v);\n";
132 frag += NV12Decoder::nv12_filter_epilogue;
134 r.state, vertexShader(), frag.arg(
"").arg(colorMatrix(decoder)));
137 void exec(RenderList& r, QRhiResourceUpdateBatch& res, AVFrame& frame)
override
139 if(!m_ready || !Video::formatIsHardwareDecoded(
140 static_cast<AVPixelFormat
>(frame.format)))
144 auto* srcTex =
reinterpret_cast<ID3D11Texture2D*
>(frame.data[0]);
145 auto srcIdx =
static_cast<UINT
>(
reinterpret_cast<intptr_t
>(frame.data[1]));
149 const int w = decoder.width, h = decoder.height;
154 D3D11_BOX box = {0, 0, 0, (UINT)w, (UINT)h, 1};
155 m_ctx->CopySubresourceRegion(
156 m_nv12Tex, 0, 0, 0, 0,
157 srcTex, srcIdx, &box);
163 samplers[0].texture->createFrom(
164 QRhiTexture::NativeTexture{quint64(m_nv12Tex), 0});
165 samplers[1].texture->createFrom(
166 QRhiTexture::NativeTexture{quint64(m_nv12Tex), 0});
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11
std::pair< QShader, QShader > makeShaders(const RenderState &v, QString vert, QString frag, int multiViewCount)
Get a pair of compiled vertex / fragment shaders from GLSL 4.5 sources.
Definition score-plugin-gfx/Gfx/Graph/Utils.cpp:1238