and the video comes into chat
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0, std430) readonly buffer V210 {
|
||||
uint words[];
|
||||
};
|
||||
|
||||
layout(push_constant) uniform PC {
|
||||
uint width;
|
||||
uint height;
|
||||
uint strideBytes;
|
||||
uint winW;
|
||||
uint winH;
|
||||
} pc;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
// Letterbox: fit video into the window, preserving aspect ratio.
|
||||
float sx = float(pc.winW) / float(pc.width);
|
||||
float sy = float(pc.winH) / float(pc.height);
|
||||
float scale = min(sx, sy);
|
||||
float dispW = float(pc.width) * scale;
|
||||
float dispH = float(pc.height) * scale;
|
||||
float offX = (float(pc.winW) - dispW) * 0.5;
|
||||
float offY = (float(pc.winH) - dispH) * 0.5;
|
||||
float fbx = gl_FragCoord.x - offX;
|
||||
float fby = gl_FragCoord.y - offY;
|
||||
if (fbx < 0.0 || fbx >= dispW || fby < 0.0 || fby >= dispH) {
|
||||
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
return;
|
||||
}
|
||||
// Framebuffer y is bottom-origin; flip to video top-origin.
|
||||
uint x = uint(fbx / scale);
|
||||
uint y = uint(fby / scale);
|
||||
|
||||
// V210: 6 pixels per group of 4 words; 3 ten-bit components per word
|
||||
// (bits 0-9 / 10-19 / 20-29). Stream order: Cb Y Cr Y Cb Y Cr Y ...
|
||||
uint group = x / 6u;
|
||||
uint sub = x % 6u;
|
||||
uint wordsPerLine = pc.strideBytes / 4u;
|
||||
uint base = y * wordsPerLine + group * 4u;
|
||||
|
||||
uint w0 = words[base + 0u];
|
||||
uint w1 = words[base + 1u];
|
||||
uint w2 = words[base + 2u];
|
||||
uint w3 = words[base + 3u];
|
||||
|
||||
uint cb0 = (w0 ) & 0x3FFu;
|
||||
uint y0 = (w0 >> 10u) & 0x3FFu;
|
||||
uint cr0 = (w0 >> 20u) & 0x3FFu;
|
||||
uint y1 = (w1 ) & 0x3FFu;
|
||||
uint cb1 = (w1 >> 10u) & 0x3FFu;
|
||||
uint y2 = (w1 >> 20u) & 0x3FFu;
|
||||
uint cr1 = (w2 ) & 0x3FFu;
|
||||
uint y3 = (w2 >> 10u) & 0x3FFu;
|
||||
uint cb2 = (w2 >> 20u) & 0x3FFu;
|
||||
uint y4 = (w3 ) & 0x3FFu;
|
||||
uint cr2 = (w3 >> 10u) & 0x3FFu;
|
||||
uint y5 = (w3 >> 20u) & 0x3FFu;
|
||||
|
||||
float Y, Cb, Cr;
|
||||
if (sub == 0u) { Y = float(y0); Cb = float(cb0); Cr = float(cr0); }
|
||||
else if (sub == 1u) { Y = float(y1); Cb = float(cb0); Cr = float(cr0); }
|
||||
else if (sub == 2u) { Y = float(y2); Cb = float(cb1); Cr = float(cr1); }
|
||||
else if (sub == 3u) { Y = float(y3); Cb = float(cb1); Cr = float(cr1); }
|
||||
else if (sub == 4u) { Y = float(y4); Cb = float(cb2); Cr = float(cr2); }
|
||||
else { Y = float(y5); Cb = float(cb2); Cr = float(cr2); }
|
||||
|
||||
float yf = (Y - 64.0) / 876.0;
|
||||
float uf = (Cb - 512.0) / 896.0;
|
||||
float vf = (Cr - 512.0) / 896.0;
|
||||
float r = yf + 1.5748 * vf;
|
||||
float g = yf - 0.1873 * uf - 0.4681 * vf;
|
||||
float b = yf + 1.8556 * uf;
|
||||
fragColor = vec4(clamp(r, 0.0, 1.0), clamp(g, 0.0, 1.0), clamp(b, 0.0, 1.0), 1.0);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
|
||||
// Fullscreen triangle, no vertex buffer. One triangle covers the viewport.
|
||||
vec2 positions[3] = vec2[](
|
||||
vec2(-1.0, -1.0),
|
||||
vec2( 3.0, -1.0),
|
||||
vec2(-1.0, 3.0)
|
||||
);
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user