Loading...
Searching...
No Matches
YUYV422.hpp
1#pragma once
2#include <Gfx/Graph/decoders/ColorSpace.hpp>
3#include <Gfx/Graph/decoders/GPUVideoDecoder.hpp>
4extern "C" {
5#include <libavformat/avformat.h>
6}
7
8namespace score::gfx
9{
16{
17 static const constexpr auto frag = R"_(#version 450
18
19)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
20
21layout(binding=3) uniform sampler2D u_tex;
22
23layout(location = 0) in vec2 v_texcoord;
24layout(location = 0) out vec4 fragColor;
25
26%2
27
28vec4 processTexture(vec4 tex) {
29 vec4 processed = convert_to_rgb(tex);
30 { %1 }
31 return processed;
32}
33
34void main() {
35 vec4 tex = texture(u_tex, v_texcoord);
36 float y = tex.r;
37 float u = tex.g;
38 float v = tex.a;
39
40 fragColor = processTexture(vec4(y,u,v, 1.));
41}
42)_";
43
45 : decoder{d}
46 {
47 }
48
49 Video::ImageFormat& decoder;
50 std::pair<QShader, QShader> init(RenderList& r) override
51 {
52 auto& rhi = *r.state.rhi;
53
54 const auto w = decoder.width, h = decoder.height;
55 // Y
56 {
57 auto tex = rhi.newTexture(QRhiTexture::RGBA8, {w / 2, h}, 1, QRhiTexture::Flag{});
58 tex->create();
59
60 auto sampler = rhi.newSampler(
61 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
62 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
63 sampler->create();
64 samplers.push_back({sampler, tex});
65 }
66
68 r.state, vertexShader(), QString(frag).arg("").arg(colorMatrix(decoder)));
69 }
70
71 void exec(RenderList&, QRhiResourceUpdateBatch& res, AVFrame& frame) override
72 {
73 setYPixels(res, frame.data[0], frame.linesize[0]);
74 }
75
76 void
77 setYPixels(QRhiResourceUpdateBatch& res, uint8_t* pixels, int stride) const noexcept
78 {
79 const auto w = decoder.width, h = decoder.height;
80 auto y_tex = samplers[0].texture;
81
82 QRhiTextureUploadEntry entry{0, 0, createTextureUpload(pixels, w, h, 2, stride)};
83
84 QRhiTextureUploadDescription desc{entry};
85 res.uploadTexture(y_tex, desc);
86 }
87};
88
95{
96 static const constexpr auto frag = R"_(#version 450
97
98)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
99
100layout(binding=3) uniform sampler2D u_tex;
101
102layout(location = 0) in vec2 v_texcoord;
103layout(location = 0) out vec4 fragColor;
104
105%2
106
107vec4 processTexture(vec4 tex) {
108 vec4 processed = convert_to_rgb(tex);
109 { %1 }
110 return processed;
111}
112
113void main() {
114 // For U0 Y0 V0 Y1 macropixel, lookup Y0 or Y1 based on whether
115 // the original texture x coord is even or odd.
116 vec4 uyvy = texture(u_tex, v_texcoord);
117 float y;
118 if (fract(floor(v_texcoord.x * renderer.renderSize.x + 0.5) / 2.0) > 0.0)
119 y = uyvy.a; // odd so choose Y1
120 else
121 y = uyvy.g; // even so choose Y0
122 float u = uyvy.r;
123 float v = uyvy.b;
124
125 fragColor = processTexture(vec4(y,u,v, 1.));
126}
127)_";
128
130 : decoder{d}
131 {
132 }
133
134 Video::ImageFormat& decoder;
135 std::pair<QShader, QShader> init(RenderList& r) override
136 {
137 auto& rhi = *r.state.rhi;
138
139 const auto w = decoder.width, h = decoder.height;
140 // Y
141 {
142 auto tex = rhi.newTexture(QRhiTexture::RGBA8, {w / 2, h}, 1, QRhiTexture::Flag{});
143 tex->create();
144
145 auto sampler = rhi.newSampler(
146 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
147 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
148 sampler->create();
149 samplers.push_back({sampler, tex});
150 }
151
153 r.state, vertexShader(), QString(frag).arg("").arg(colorMatrix(decoder)));
154 }
155
156 void exec(RenderList&, QRhiResourceUpdateBatch& res, AVFrame& frame) override
157 {
158 auto y_tex = samplers[0].texture;
159
160 auto pixels = frame.data[0];
161 auto stride = frame.linesize[0];
162 QRhiTextureUploadEntry entry{
163 0, 0, createTextureUpload(pixels, frame.width, frame.height, 2, stride)};
164
165 QRhiTextureUploadDescription desc{entry};
166 res.uploadTexture(y_tex, desc);
167 }
168};
169
170}
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:89
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:342
Definition VideoInterface.hpp:16
Decodes UYVY422 video, mostly used for NDI.
Definition YUYV422.hpp:95
void exec(RenderList &, QRhiResourceUpdateBatch &res, AVFrame &frame) override
Decode and upload a video frame to the GPU.
Definition YUYV422.hpp:156
std::pair< QShader, QShader > init(RenderList &r) override
Initialize a GPUVideoDecoder.
Definition YUYV422.hpp:135
Decodes YUYV422 video.
Definition YUYV422.hpp:16
std::pair< QShader, QShader > init(RenderList &r) override
Initialize a GPUVideoDecoder.
Definition YUYV422.hpp:50
void exec(RenderList &, QRhiResourceUpdateBatch &res, AVFrame &frame) override
Decode and upload a video frame to the GPU.
Definition YUYV422.hpp:71