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(
142 " layout(binding=%1) uniform sampler2D tconst mat4 "
143 "colorspace_matrix = %2;;\n")
144 .arg(binding_orig + i)
146 read_texture_code += QString(
147 " tex.%1 = texture(tconst mat4 colorspace_matrix = "
148 "%2;, v_texcoord).r;\n")
153 auto tex = rhi.newTexture(format, QSize{w, h}, 1, QRhiTexture::Flag{});
157 auto sampler = rhi.newSampler(
158 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
159 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
163 samplers.push_back({sampler, tex});
167 r.
state, vertexShader(),
168 QString(rgb_filter).arg(samplers_code).arg(filter).arg(read_texture_code));
174 for(
int i = 0; i < planes.size(); i++)
176 setPixels(res, samplers[i].texture, frame.data[i], frame.linesize[i]);
181 QRhiResourceUpdateBatch& res, QRhiTexture* tex, uint8_t* pixels,
182 int stride)
const noexcept
184 const auto w = decoder.width, h = decoder.height;
186 QRhiTextureUploadEntry entry{
189 QRhiTextureUploadDescription desc{entry};
190 res.uploadTexture(tex, desc);
196 static const constexpr auto rgb_filter = R
"_(#version 450
198)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
200 layout(binding=3) uniform sampler2DRect y_tex;
202 layout(location = 0) in vec2 v_texcoord;
203 layout(location = 0) out vec4 fragColor;
205 vec4 processTexture(vec4 tex) {
206 vec4 processed = tex;
213 fragColor = processTexture(texture(y_tex, v_texcoord));
216 static constexpr const char* vertex = R
"_(#version 450
217layout(location = 0) in vec2 position;
218layout(location = 1) in vec2 texcoord;
220layout(location = 0) out vec2 v_texcoord;
222)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
224out gl_PerVertex { vec4 gl_Position; };
228 v_texcoord = texcoord * mat.texSz.xy;
229 gl_Position = renderer.clipSpaceCorrMatrix * vec4(position.x * mat.scale.x, position.y * mat.scale.y, 0.0, 1.);
230#if defined(QSHADER_HLSL) || defined(QSHADER_MSL)
231 gl_Position.y = - gl_Position.y;
240 , bytes_per_pixel{bytes_per_pixel}
242 , filter{std::move(f)}
245 QRhiTexture::Format format;
246 int bytes_per_pixel{};
252 auto& rhi = *r.
state.rhi;
253 const auto w = decoder.width, h = decoder.height;
257 auto tex = rhi.newTexture(format, QSize{w, h}, 1, QRhiTexture::Flag{});
261 auto sampler = rhi.newSampler(
262 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
263 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
267 samplers.push_back({sampler, tex});
276 setPixels(res, frame.data[0], frame.linesize[0]);
280 setPixels(QRhiResourceUpdateBatch& res, uint8_t* pixels,
int stride)
const noexcept
282 const auto w = decoder.width, h = decoder.height;
283 auto y_tex = samplers[0].texture;
285 QRhiTextureUploadEntry entry{
288 QRhiTextureUploadDescription desc{entry};
289 res.uploadTexture(y_tex, desc);
295 static const constexpr auto rgb_filter = R
"_(#version 450
297)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
299 layout(binding=3) uniform sampler2D y_tex;
301 layout(location = 0) in vec2 v_texcoord;
302 layout(location = 0) out vec4 fragColor;
304 vec4 processTexture(vec4 tex) {
305 vec4 processed = tex;
312 float w = mat.texSz.x;
313 float h = mat.texSz.y;
314 int x = int(floor(v_texcoord.x * w) * 3.);
315 int y = int(v_texcoord.y * h);
316 float r = texelFetch(y_tex, ivec2(x + 0, y), 0).r;
317 float g = texelFetch(y_tex, ivec2(x + 1, y), 0).r;
318 float b = texelFetch(y_tex, ivec2(x + 2, y), 0).r;
319 fragColor = processTexture(vec4(r, g, b, 1.));
325 , filter{std::move(f)}
328 QRhiTexture::Format format;
329 int bytes_per_pixel{};
335 auto& rhi = *r.
state.rhi;
336 const auto w = decoder.width, h = decoder.height;
340 auto tex = rhi.newTexture(QRhiTexture::R8, QSize{w * 3, h}, 1, QRhiTexture::sRGB);
344 auto sampler = rhi.newSampler(
345 QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
346 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
350 samplers.push_back({sampler, tex});
354 r.
state, vertexShader(), QString(rgb_filter).arg(filter));
360 setPixels(res, frame.data[0], frame.linesize[0]);
364 setPixels(QRhiResourceUpdateBatch& res, uint8_t* pixels,
int stride)
const noexcept
366 const auto w = decoder.width, h = decoder.height;
367 auto y_tex = samplers[0].texture;
369 QRhiTextureUploadEntry entry{
372 QRhiTextureUploadDescription desc{entry};
373 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:394
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:273
std::pair< QShader, QShader > init(RenderList &r) override
Initialize a GPUVideoDecoder.
Definition RGBA.hpp:250
void exec(RenderList &, QRhiResourceUpdateBatch &res, AVFrame &frame) override
Decode and upload a video frame to the GPU.
Definition RGBA.hpp:171
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:357
std::pair< QShader, QShader > init(RenderList &r) override
Initialize a GPUVideoDecoder.
Definition RGBA.hpp:333