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)
36struct HWD3D11Decoder : GPUVideoDecoder
39 PixelFormatInfo m_fmt;
41 ID3D11Device* m_dev{};
42 ID3D11DeviceContext* m_ctx{};
43 ID3D11Texture2D* m_nv12Tex{};
46 static bool isAvailable(QRhi& rhi)
48 return rhi.backend() == QRhi::D3D11;
51 explicit HWD3D11Decoder(
56 auto* nh =
static_cast<const QRhiD3D11NativeHandles*
>(rhi.nativeHandles());
57 m_dev =
static_cast<ID3D11Device*
>(nh->dev);
58 m_dev->GetImmediateContext(&m_ctx);
61 ~HWD3D11Decoder()
override
71 const int w = decoder.width, h = decoder.height;
72 DXGI_FORMAT nv12Fmt = m_fmt.is10bit() ? DXGI_FORMAT_P010 : DXGI_FORMAT_NV12;
74 D3D11_TEXTURE2D_DESC desc{};
79 desc.Format = nv12Fmt;
80 desc.SampleDesc.Count = 1;
81 desc.Usage = D3D11_USAGE_DEFAULT;
82 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
83 if(FAILED(m_dev->CreateTexture2D(&desc,
nullptr, &m_nv12Tex)))
85 qDebug() <<
"HWD3D11Decoder: failed to create NV12 copy texture"
86 << w <<
"x" << h <<
"fmt:" << nv12Fmt;
94 std::pair<QShader, QShader> init(RenderList& r)
override
96 auto& rhi = *r.state.rhi;
97 const int w = decoder.width, h = decoder.height;
98 auto texFmt = m_fmt.is10bit() ? QRhiTexture::R16 : QRhiTexture::R8;
99 auto uvTexFmt = m_fmt.is10bit() ? QRhiTexture::RG16 : QRhiTexture::RG8;
102 auto tex = rhi.newTexture(texFmt, {w, h}, 1, QRhiTexture::Flag{});
104 auto sampler = rhi.newSampler(
105 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
106 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
108 samplers.push_back({sampler, tex});
111 auto tex = rhi.newTexture(uvTexFmt, {w / 2, h / 2}, 1, QRhiTexture::Flag{});
113 auto sampler = rhi.newSampler(
114 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
115 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
117 samplers.push_back({sampler, tex});
124 r.state, vertexShader(),
125 QString(P010Decoder::frag).arg(
"").arg(colorMatrix(decoder)));
127 QString frag = NV12Decoder::nv12_filter_prologue;
128 frag +=
" vec3 yuv = vec3(y, u, v);\n";
129 frag += NV12Decoder::nv12_filter_epilogue;
131 r.state, vertexShader(), frag.arg(
"").arg(colorMatrix(decoder)));
134 void exec(RenderList& r, QRhiResourceUpdateBatch& res, AVFrame& frame)
override
136 if(!m_ready || !Video::formatIsHardwareDecoded(
137 static_cast<AVPixelFormat
>(frame.format)))
141 auto* srcTex =
reinterpret_cast<ID3D11Texture2D*
>(frame.data[0]);
142 auto srcIdx =
static_cast<UINT
>(
reinterpret_cast<intptr_t
>(frame.data[1]));
146 const int w = decoder.width, h = decoder.height;
151 D3D11_BOX box = {0, 0, 0, (UINT)w, (UINT)h, 1};
152 m_ctx->CopySubresourceRegion(
153 m_nv12Tex, 0, 0, 0, 0,
154 srcTex, srcIdx, &box);
160 samplers[0].texture->createFrom(
161 QRhiTexture::NativeTexture{quint64(m_nv12Tex), 0});
162 samplers[1].texture->createFrom(
163 QRhiTexture::NativeTexture{quint64(m_nv12Tex), 0});
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:12
std::pair< QShader, QShader > makeShaders(const RenderState &v, QString vert, QString frag)
Get a pair of compiled vertex / fragment shaders from GLSL 4.5 sources.
Definition score-plugin-gfx/Gfx/Graph/Utils.cpp:395