and the video comes into chat

This commit is contained in:
Dmitry Sergeev
2026-08-22 14:59:54 +03:00
parent 32f7dea31c
commit 84572fb88c
11 changed files with 554 additions and 13 deletions
+76
View File
@@ -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);
}