Files
root 95bb7c50ee feat: point the fleet at wss LiveKit room uwh-telhai
Publish and subscribe over wss://livekit.uni-wh.de:7800 and refuse
cleartext ws://. Conference room is uwh-telhai. Includes the uncommitted
encoded H.264 publish path, Rally hairpin, and KMS wall overlay.
2026-10-11 00:48:50 +00:00

77 lines
2.4 KiB
Python

"""16-align I420→NV12 for Intel VA (NV12 only). Pad up, never crop."""
from __future__ import annotations
import numpy as np
def coded_dim(n: int) -> int:
n = int(n)
if n <= 0:
return 0
return (n + 15) // 16 * 16
def nv12_bytes(width: int, height: int) -> int:
return int(width) * int(height) * 3 // 2
def va_visible_height(width: int, height: int) -> int:
"""Drop the 8-row VA pad when the remainder is 16:9 (360/1080)."""
w, h = int(width), int(height)
vis = h - 8
if w > 0 and vis > 0 and vis * 16 == w * 9:
return vis
return h
def drop_va_pad_i420(src, width: int, height: int):
"""Crop coded pad off I420. Returns (payload, w, visible_h)."""
w, h = int(width), int(height)
vis = va_visible_height(w, h)
if vis == h:
return src, w, h
ysz = w * h
uvw, uvh = w // 2, h // 2
uvsz = uvw * uvh
raw = np.frombuffer(src, dtype=np.uint8, count=ysz + 2 * uvsz)
y = raw[:ysz].reshape(h, w)[:vis, :]
u = raw[ysz:ysz + uvsz].reshape(uvh, uvw)[: vis // 2, :]
v = raw[ysz + uvsz:ysz + 2 * uvsz].reshape(uvh, uvw)[: vis // 2, :]
out = np.empty(w * vis * 3 // 2, dtype=np.uint8)
out[: w * vis] = y.reshape(-1)
out[w * vis:w * vis + (w // 2) * (vis // 2)] = u.reshape(-1)
out[w * vis + (w // 2) * (vis // 2):] = v.reshape(-1)
return out.tobytes(), w, vis
def i420_to_nv12_into(src, width: int, height: int, out: bytearray) -> int:
"""Pad to 16-aligned WxH and write NV12 into out. Returns nbytes."""
w, h = int(width), int(height)
cw, ch = coded_dim(w), coded_dim(h)
need = nv12_bytes(cw, ch)
if len(out) < need:
raise ValueError("NV12 dest too small")
ysz = w * h
uvw, uvh = w // 2, h // 2
uvsz = uvw * uvh
raw = np.frombuffer(src, dtype=np.uint8, count=ysz + 2 * uvsz)
y = raw[:ysz].reshape(h, w)
u = raw[ysz:ysz + uvsz].reshape(uvh, uvw)
v = raw[ysz + uvsz:ysz + 2 * uvsz].reshape(uvh, uvw)
nv = np.frombuffer(out, dtype=np.uint8, count=need).reshape(ch + ch // 2, cw)
nv[:h, :w] = y
if ch > h:
nv[h:ch, :w] = y[-1]
if cw > w:
nv[:ch, w:cw] = nv[:ch, w - 1:w]
uv = nv[ch:, :].reshape(ch // 2, cw // 2, 2)
uh, uw = h // 2, w // 2
uv[:uh, :uw, 0] = u
uv[:uh, :uw, 1] = v
if ch // 2 > uh:
uv[uh:, :uw, 0] = u[-1]
uv[uh:, :uw, 1] = v[-1]
if cw // 2 > uw:
uv[:, uw:, :] = uv[:, uw - 1:uw, :]
return need