2#include <Gfx/Graph/decoders/GPUVideoDecoder.hpp>
4#include <libavformat/avformat.h>
11 static const constexpr auto rgb_filter = R
"_(#version 450
13)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
15 layout(binding=3) uniform sampler2D y_tex;
17 layout(location = 0) in vec2 v_texcoord;
18 layout(location = 0) out vec4 fragColor;
20 vec4 processTexture(vec4 tex) {
28 fragColor = processTexture(texture(y_tex, v_texcoord));
33 QString f =
"",
bool invertY =
false)
35 , bytes_per_pixel{bytes_per_pixel}
37 , filter{std::move(f)}
41 QRhiTexture::Format format;
42 int bytes_per_pixel{};
49 auto& rhi = *r.
state.rhi;
50 const auto w = decoder.width, h = decoder.height;
54 auto tex = rhi.newTexture(format, QSize{w, h}, 1, QRhiTexture::Flag{});
58 auto sampler = rhi.newSampler(
59 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
60 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
64 samplers.push_back({sampler, tex});
68 r.
state, vertexShader(invertY), QString(rgb_filter).arg(filter));
71 void exec(
RenderList&, QRhiResourceUpdateBatch& res, AVFrame& frame)
override
74 setPixels(res, frame.data[0], frame.linesize[0]);
78 setPixels(QRhiResourceUpdateBatch& res, uint8_t* pixels,
int stride)
const noexcept
80 const auto w = decoder.width, h = decoder.height;
81 auto y_tex = samplers[0].texture;
83 QRhiTextureUploadEntry entry{
86 QRhiTextureUploadDescription desc{entry};
87 res.uploadTexture(y_tex, desc);
93 static const constexpr auto rgb_filter = R
"_(#version 450
95)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
98 layout(location = 0) in vec2 v_texcoord;
99 layout(location = 0) out vec4 fragColor;
101 vec4 processTexture(vec4 tex) {
102 vec4 processed = tex;
111 fragColor = processTexture(tex);
115 QRhiTexture::Format fmt, int bytes_per_pixel, QString planes,
118 , bytes_per_pixel{bytes_per_pixel}
121 , filter{std::move(f)}
124 QRhiTexture::Format format;
125 int bytes_per_pixel{};
132 auto& rhi = *r.
state.rhi;
133 const auto w = decoder.width, h = decoder.height;
135 QString samplers_code;
136 QString read_texture_code;
138 const int binding_orig = 3;
139 for(
int i = 0; i < planes.size(); i++)
141 samplers_code += QString(
" layout(binding=%1) uniform sampler2D t%2;\n")
142 .arg(binding_orig + i)
145 += QString(
" tex.%1 = texture(t%2, v_texcoord).r;\n")
150 auto tex = rhi.newTexture(format, QSize{w, h}, 1, QRhiTexture::Flag{});
154 auto sampler = rhi.newSampler(
155 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
156 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
160 samplers.push_back({sampler, tex});
164 r.
state, vertexShader(),
165 QString(rgb_filter).arg(samplers_code).arg(filter).arg(read_texture_code));
171 for(
int i = 0; i < planes.size(); i++)
173 setPixels(res, samplers[i].texture, frame.data[i], frame.linesize[i]);
178 QRhiResourceUpdateBatch& res, QRhiTexture* tex, uint8_t* pixels,
179 int stride)
const noexcept
181 const auto w = decoder.width, h = decoder.height;
183 QRhiTextureUploadEntry entry{
186 QRhiTextureUploadDescription desc{entry};
187 res.uploadTexture(tex, desc);
193 static const constexpr auto rgb_filter = R
"_(#version 450
195)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
197 layout(binding=3) uniform sampler2DRect y_tex;
199 layout(location = 0) in vec2 v_texcoord;
200 layout(location = 0) out vec4 fragColor;
202 vec4 processTexture(vec4 tex) {
203 vec4 processed = tex;
210 fragColor = processTexture(texture(y_tex, v_texcoord));
213 static constexpr const char* vertex = R
"_(#version 450
214layout(location = 0) in vec2 position;
215layout(location = 1) in vec2 texcoord;
217layout(location = 0) out vec2 v_texcoord;
219)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
221out gl_PerVertex { vec4 gl_Position; };
225 v_texcoord = texcoord * mat.texSz.xy;
226 gl_Position = renderer.clipSpaceCorrMatrix * vec4(position.x * mat.scale.x, position.y * mat.scale.y, 0.0, 1.);
227#if defined(QSHADER_HLSL) || defined(QSHADER_MSL)
228 gl_Position.y = - gl_Position.y;
237 , bytes_per_pixel{bytes_per_pixel}
239 , filter{std::move(f)}
242 QRhiTexture::Format format;
243 int bytes_per_pixel{};
249 auto& rhi = *r.
state.rhi;
250 const auto w = decoder.width, h = decoder.height;
254 auto tex = rhi.newTexture(format, QSize{w, h}, 1, QRhiTexture::Flag{});
258 auto sampler = rhi.newSampler(
259 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
260 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
264 samplers.push_back({sampler, tex});
273 setPixels(res, frame.data[0], frame.linesize[0]);
277 setPixels(QRhiResourceUpdateBatch& res, uint8_t* pixels,
int stride)
const noexcept
279 const auto w = decoder.width, h = decoder.height;
280 auto y_tex = samplers[0].texture;
282 QRhiTextureUploadEntry entry{
285 QRhiTextureUploadDescription desc{entry};
286 res.uploadTexture(y_tex, desc);
292 static const constexpr auto rgb_filter = R
"_(#version 450
294)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
296 layout(binding=3) uniform sampler2D y_tex;
298 layout(location = 0) in vec2 v_texcoord;
299 layout(location = 0) out vec4 fragColor;
301 vec4 processTexture(vec4 tex) {
302 vec4 processed = tex;
309 float w = mat.texSz.x;
310 float h = mat.texSz.y;
311 int x = int(floor(v_texcoord.x * w) * 3.);
312 int y = int(v_texcoord.y * h);
313 float r = texelFetch(y_tex, ivec2(x + 0, y), 0).r;
314 float g = texelFetch(y_tex, ivec2(x + 1, y), 0).r;
315 float b = texelFetch(y_tex, ivec2(x + 2, y), 0).r;
316 fragColor = processTexture(vec4(r, g, b, 1.));
322 , filter{std::move(f)}
325 int bytes_per_pixel{};
331 auto& rhi = *r.
state.rhi;
332 const auto w = decoder.width, h = decoder.height;
336 auto tex = rhi.newTexture(QRhiTexture::R8, QSize{w * 3, h}, 1, QRhiTexture::sRGB);
340 auto sampler = rhi.newSampler(
341 QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
342 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
346 samplers.push_back({sampler, tex});
350 r.
state, vertexShader(), QString(rgb_filter).arg(filter));
356 setPixels(res, frame.data[0], frame.linesize[0]);
360 setPixels(QRhiResourceUpdateBatch& res, uint8_t* pixels,
int stride)
const noexcept
362 const auto w = decoder.width, h = decoder.height;
363 auto y_tex = samplers[0].texture;
365 QRhiTextureUploadEntry entry{
368 QRhiTextureUploadDescription desc{entry};
369 res.uploadTexture(y_tex, desc);
375 static const constexpr auto rgb_filter = R
"_(#version 450
377)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
379 layout(binding=3) uniform sampler2D y_tex;
381 layout(location = 0) in vec2 v_texcoord;
382 layout(location = 0) out vec4 fragColor;
384 vec4 processTexture(vec4 tex) {
385 vec4 processed = tex;
392 float w = mat.texSz.x;
393 float h = mat.texSz.y;
394 int x = int(floor(v_texcoord.x * w) * 3.);
395 int y = int(v_texcoord.y * h);
396 float r = texelFetch(y_tex, ivec2(x + 0, y), 0).r;
397 float g = texelFetch(y_tex, ivec2(x + 1, y), 0).r;
398 float b = texelFetch(y_tex, ivec2(x + 2, y), 0).r;
399 fragColor = processTexture(vec4(r, g, b, 1.));
404 , filter{std::move(f)}
412 auto& rhi = *r.
state.rhi;
413 const auto w = decoder.width, h = decoder.height;
416 auto tex = rhi.newTexture(QRhiTexture::R16, QSize{w * 3, h}, 1, QRhiTexture::Flag{});
419 auto sampler = rhi.newSampler(
420 QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
421 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
424 samplers.push_back({sampler, tex});
428 r.
state, vertexShader(), QString(rgb_filter).arg(filter));
433 const auto w = decoder.width, h = decoder.height;
434 auto y_tex = samplers[0].texture;
437 QRhiTextureUploadEntry entry{
440 QRhiTextureUploadDescription desc{entry};
441 res.uploadTexture(y_tex, desc);
Processes and renders a video frame on the GPU.
Definition GPUVideoDecoder.hpp:43
static QRhiTextureSubresourceUploadDescription createTextureUpload(uint8_t *pixels, int w, int h, int bytesPerPixel, int stride)
Utility method to create a QRhiTextureSubresourceUploadDescription.
Definition GPUVideoDecoder.cpp:22
List of nodes to be rendered to an output.
Definition RenderList.hpp:19
RenderState & state
RenderState corresponding to this RenderList.
Definition RenderList.hpp:94
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
std::pair< QShader, QShader > init(RenderList &r) override
Initialize a GPUVideoDecoder.
Definition RGBA.hpp:47
void exec(RenderList &, QRhiResourceUpdateBatch &res, AVFrame &frame) override
Decode and upload a video frame to the GPU.
Definition RGBA.hpp:71
void exec(RenderList &, QRhiResourceUpdateBatch &res, AVFrame &frame) override
Decode and upload a video frame to the GPU.
Definition RGBA.hpp:270
std::pair< QShader, QShader > init(RenderList &r) override
Initialize a GPUVideoDecoder.
Definition RGBA.hpp:247
void exec(RenderList &, QRhiResourceUpdateBatch &res, AVFrame &frame) override
Decode and upload a video frame to the GPU.
Definition RGBA.hpp:168
std::pair< QShader, QShader > init(RenderList &r) override
Initialize a GPUVideoDecoder.
Definition RGBA.hpp:130
void exec(RenderList &, QRhiResourceUpdateBatch &res, AVFrame &frame) override
Decode and upload a video frame to the GPU.
Definition RGBA.hpp:353
std::pair< QShader, QShader > init(RenderList &r) override
Initialize a GPUVideoDecoder.
Definition RGBA.hpp:329
std::pair< QShader, QShader > init(RenderList &r) override
Initialize a GPUVideoDecoder.
Definition RGBA.hpp:410
void exec(RenderList &, QRhiResourceUpdateBatch &res, AVFrame &frame) override
Decode and upload a video frame to the GPU.
Definition RGBA.hpp:431