Loading...
Searching...
No Matches
R210.hpp
1#pragma once
2#include <Gfx/Graph/decoders/GPUVideoDecoder.hpp>
3extern "C" {
4#include <libavformat/avformat.h>
5}
6
7namespace score::gfx
8{
19{
20 // %1 = user filter
21 static const constexpr auto frag = R"_(#version 450
22
23)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
24
25layout(binding=3) uniform sampler2D u_tex;
26
27layout(location = 0) in vec2 v_texcoord;
28layout(location = 0) out vec4 fragColor;
29
30vec4 processTexture(vec4 tex) {
31 vec4 processed = tex;
32 { %1 }
33 return processed;
34}
35
36void main() {
37 int x = int(floor(v_texcoord.x * mat.texSz.x));
38 int y = int(floor(v_texcoord.y * mat.texSz.y));
39 vec4 t = texelFetch(u_tex, ivec2(x, y), 0);
40 uint b0 = uint(t.r * 255.0 + 0.5);
41 uint b1 = uint(t.g * 255.0 + 0.5);
42 uint b2 = uint(t.b * 255.0 + 0.5);
43 uint b3 = uint(t.a * 255.0 + 0.5);
44 uint w = (b0 << 24u) | (b1 << 16u) | (b2 << 8u) | b3; // big-endian word
45 float r = float((w >> 20u) & 0x3FFu);
46 float g = float((w >> 10u) & 0x3FFu);
47 float b = float( w & 0x3FFu);
48 fragColor = processTexture(vec4(r, g, b, 1023.0) / 1023.0);
49}
50)_";
51
53 : decoder{d}
54 {
55 }
56
57 Video::ImageFormat& decoder;
58
59 static constexpr int rowBytesFor(int w) noexcept
60 {
61 return ((w + 63) / 64) * 256;
62 }
63
64 std::pair<QShader, QShader> init(RenderList& r) override
65 {
66 auto& rhi = *r.state.rhi;
67 const auto w = decoder.width, h = decoder.height;
68
69 // One RGBA8 texel per r210 word, on the padded wire stride.
70 const int texW = rowBytesFor(w) / 4;
71 {
72 auto tex
73 = rhi.newTexture(QRhiTexture::RGBA8, {texW, h}, 1, QRhiTexture::Flag{});
74 tex->create();
75
76 auto sampler = rhi.newSampler(
77 QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
78 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
79 sampler->create();
80
81 samplers.push_back({sampler, tex});
82 }
83
85 r.state, vertexShader(), QString(frag).arg(""));
86 }
87
88 void exec(RenderList&, QRhiResourceUpdateBatch& res, AVFrame& frame) override
89 {
90 const int texW = rowBytesFor(decoder.width) / 4;
91 auto tex = samplers[0].texture;
92 QRhiTextureUploadEntry entry{
93 0, 0,
95 frame.data[0], texW, decoder.height, /*bpp=*/4, frame.linesize[0])};
96 QRhiTextureUploadDescription desc{entry};
97 res.uploadTexture(tex, desc);
98 }
99};
100
101} // namespace score::gfx
Processes and renders a video frame on the GPU.
Definition GPUVideoDecoder.hpp:90
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:30
RenderState & state
RenderState corresponding to this RenderList.
Definition RenderList.hpp:169
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
Definition VideoInterface.hpp:26
Decodes 10-bit RGB packed in r210 (DeckLink bmdFormat10BitRGB).
Definition R210.hpp:19
std::pair< QShader, QShader > init(RenderList &r) override
Initialize a GPUVideoDecoder.
Definition R210.hpp:64
void exec(RenderList &, QRhiResourceUpdateBatch &res, AVFrame &frame) override
Decode and upload a video frame to the GPU.
Definition R210.hpp:88