code wiki / (root) / nx_video_codec_wasm.nx

nx_video_codec_wasm.nx source

↩ module page · 690 lines · 43008 B

1// nx_video_codec_wasm.nx -- the SOVEREIGN video codec on the WIRE (task #27): YUV420 color wrapper over 2// the gated nx_vcodec (key + P-frames, motion comp, WHT/DCT, deadzone quant -- realseq gate 42.89dB 3// bit-exact). This replaces the browser's JPEG encoder (the last third-party in the media path and the 4// 2026-07-05 field-call bitrate killer: JPEG ~8-15x the vcodec at the same fps -> phone uplink saturation 5// -> 4fps chop). Pure integer, allocates nothing, flat args -> compiles UNCHANGED to wasm (3rd-party 6// browsers, via nx_compile_wat) AND native (NishiOS client) -- one codec, every target, no host encoder. 7// 8// WIRE STREAM (one frame): [ybytes:u32 LE][ubytes:u32 LE][vbytes:u32 LE][Y stream][U stream][V stream] 9// Planes are independently packed nx_vcodec streams (self-describing key/P per block); U/V are quarter-res 10// (W/2 x H/2). qp rides the room wire header (kind 0x57), NOT this stream. license_tier: ORIGINAL 11import "nx_vcodec.nx" 12import "nx_vcodec_nf.nx" // learned in-loop restoration (neural rung 2): encoder-signaled, never-hurt 13 14// ---- integer BT.601-class RGBA <-> YUV420 (JFIF full-range coefficients, exact-integer, clamp) ---- 15func vv_clamp255(v: i64) -> i64 { if v < 0 { return 0 } if v > 255 { return 255 } return v } 16 17// RGBA (canvas ImageData layout) -> planar YUV420 at yuv: Y[W*H] then U[W/2*H/2] then V[W/2*H/2]. 18// Chroma = one conversion per 2x2 block from the AVERAGED RGB (cheap + correct subsampling order). 19func vv_rgba_to_yuv420(rgba: *u8, W: i64, H: i64, yuv: *u8) -> i64 { 20 let N: i64 = W * H 21 let cw: i64 = W / 2 22 var y: i64 = 0 23 while y < H { 24 var x: i64 = 0 25 while x < W { 26 let o: i64 = (y * W + x) * 4 27 let r: i64 = rgba[o] & 0xff 28 let g: i64 = rgba[o + 1] & 0xff 29 let b: i64 = rgba[o + 2] & 0xff 30 yuv[y * W + x] = vv_clamp255((77 * r + 150 * g + 29 * b) >> 8) as u8 31 x = x + 1 32 } 33 y = y + 1 34 } 35 var cy: i64 = 0 36 while cy < H / 2 { 37 var cx: i64 = 0 38 while cx < cw { 39 let o00: i64 = ((cy * 2) * W + cx * 2) * 4 40 let o01: i64 = o00 + 4 41 let o10: i64 = o00 + W * 4 42 let o11: i64 = o10 + 4 43 let ar: i64 = ((rgba[o00] & 0xff) + (rgba[o01] & 0xff) + (rgba[o10] & 0xff) + (rgba[o11] & 0xff)) / 4 44 let ag: i64 = ((rgba[o00+1] & 0xff) + (rgba[o01+1] & 0xff) + (rgba[o10+1] & 0xff) + (rgba[o11+1] & 0xff)) / 4 45 let ab: i64 = ((rgba[o00+2] & 0xff) + (rgba[o01+2] & 0xff) + (rgba[o10+2] & 0xff) + (rgba[o11+2] & 0xff)) / 4 46 let ci: i64 = cy * cw + cx 47 yuv[N + ci] = vv_clamp255(((0 - 43) * ar - 85 * ag + 128 * ab >> 8) + 128) as u8 48 yuv[N + (cw * (H / 2)) + ci] = vv_clamp255((128 * ar - 107 * ag - 21 * ab >> 8) + 128) as u8 49 cx = cx + 1 50 } 51 cy = cy + 1 52 } 53 return 0 54} 55 56// planar YUV420 -> RGBA (A=255). Integer inverse of the above, clamped. 57func vv_yuv420_to_rgba(yuv: *u8, W: i64, H: i64, rgba: *u8) -> i64 { 58 let N: i64 = W * H 59 let cw: i64 = W / 2 60 let C: i64 = cw * (H / 2) 61 var y: i64 = 0 62 while y < H { 63 var x: i64 = 0 64 while x < W { 65 let yy: i64 = yuv[y * W + x] & 0xff 66 let ci: i64 = (y / 2) * cw + (x / 2) 67 let u: i64 = (yuv[N + ci] & 0xff) - 128 68 let v: i64 = (yuv[N + C + ci] & 0xff) - 128 69 let o: i64 = (y * W + x) * 4 70 rgba[o] = vv_clamp255(yy + ((359 * v) >> 8)) as u8 71 rgba[o + 1] = vv_clamp255(yy - ((88 * u + 183 * v) >> 8)) as u8 72 rgba[o + 2] = vv_clamp255(yy + ((454 * u) >> 8)) as u8 73 rgba[o + 3] = 255 as u8 74 x = x + 1 75 } 76 y = y + 1 77 } 78 return 0 79} 80 81// ---- 3-plane packed encode/decode over the ONE gated codec ---- 82func vv_wr_u32(p: *u8, off: i64, v: i64) -> i64 { 83 p[off] = (v & 0xff) as u8 84 p[off + 1] = ((v >> 8) & 0xff) as u8 85 p[off + 2] = ((v >> 16) & 0xff) as u8 86 p[off + 3] = ((v >> 24) & 0xff) as u8 87 return 0 88} 89func vv_rd_u32b(p: *u8, off: i64) -> i64 { 90 return (p[off] & 0xff) + ((p[off + 1] & 0xff) << 8) + ((p[off + 2] & 0xff) << 16) + ((p[off + 3] & 0xff) << 24) 91} 92 93// encode one YUV420 frame (cur) against prev; recon receives the decoder-exact reconstruction (becomes the 94// next prev -- the CLOSED loop the realseq gate proved). Returns TOTAL wire bytes (12 + planes), or -1 if 95// it would exceed out_cap (honest bound; caller falls back / drops). 96func vv_iabs(x: i64) -> i64 { if x < 0 { return 0 - x } return x } 97// SOVEREIGN RECON-HASH (four-pillar SPOT: cross-instance drift detection). FNV-1a over the reconstructed 98// YUV420 plane. The integer codec is bit-exact BY CONSTRUCTION, so the sender's recon and every receiver's 99// recon MUST hash identically -- any difference is a REAL decode divergence (not rounding). Exported so the 100// last-mile shim AND the native NishiOS video app call the SAME function on both sides: no sample arithmetic 101// is computed in JavaScript (this module's founding charter). Low-32-bit FNV (matches JS Math.imul + >>>0). 102func vc_recon_hash(recon: *u8, W: i64, H: i64) -> i64 { 103 let n: i64 = W * H + (W / 2) * (H / 2) * 2 104 var h: i64 = 2166136261 // FNV-1a offset basis 0x811c9dc5 105 var i: i64 = 0 106 while i < n { 107 h = h ^ ((recon[i] as i64) & 0xff) 108 h = (h * 16777619) & 4294967295 // * 0x01000193, keep low 32 bits 109 i = i + 1 110 } 111 return h 112} 113// SOVEREIGN DRIFT MATCHER (four-pillar SPOT: the decision, not just the hash). The receiver stores each 114// sender's per-frame recon-hash announcement in a ring, then when it decodes a frame it VERIFIES its own 115// recon-hash against the sender's announced truth for the same CONTENT KEY (n,qp,flags,w,h) -- the SFU 116// rewrites the video seq, so we can't match on seq. 2 consecutive mismatches = CONFIRMED drift (a broken 117// chain drifts every frame; a rare content-key collision does not). This whole verdict lives HERE so the 118// browser shim AND a native NishiOS video app share ONE drift brain -- the JS only routes wire bytes and 119// takes the browser action (kreq/toast/badge). Per-peer state region = i64[>=100], zeroed once by reset: 120// [0]=ring head [1]=consecutive miss [2]=confirmed drift count [3]=pad then RING[16] x {hash,n,qp,fl,w,h}. 121const VC_DRIFT_RING: i64 = 16 122func vc_drift_reset(st: *i64) -> i64 { 123 var i: i64 = 0 124 while i < 100 { st[i] = 0; i = i + 1 } 125 return 0 126} 127func vc_drift_push(st: *i64, hash: i64, n: i64, qp: i64, fl: i64, w: i64, h: i64) -> i64 { 128 let head: i64 = st[0] 129 let base: i64 = 4 + head * 6 130 st[base] = hash; st[base + 1] = n; st[base + 2] = qp; st[base + 3] = fl & 15; st[base + 4] = w; st[base + 5] = h 131 st[0] = (head + 1) % VC_DRIFT_RING 132 return 0 133} 134// verify MY just-decoded recon hash vs a matching announcement. 0 = match (or none pending); 1 = unconfirmed 135// mismatch; 2 = CONFIRMED drift (>=2 consecutive). The matched announcement is consumed (n set to sentinel). 136func vc_drift_verify(st: *i64, myhash: i64, n: i64, qp: i64, fl: i64, w: i64, h: i64) -> i64 { 137 let flk: i64 = fl & 15 138 var i: i64 = 0 139 while i < VC_DRIFT_RING { 140 let base: i64 = 4 + i * 6 141 if st[base + 1] == n { if st[base + 2] == qp { if st[base + 3] == flk { if st[base + 4] == w { if st[base + 5] == h { 142 let ah: i64 = st[base] 143 st[base + 1] = 0 - 1 // consume (positive n never matches -1) 144 if ah == myhash { st[1] = 0; return 0 } // match -> reset miss run 145 st[1] = st[1] + 1 146 if st[1] >= 2 { st[2] = st[2] + 1; st[1] = 0; return 2 } 147 return 1 148 } } } } } 149 i = i + 1 150 } 151 return 0 152} 153func vc_drift_count(st: *i64) -> i64 { return st[2] } 154// IN-LOOP DEBLOCKING FILTER (H.264-style weak filter) -- the piece mature codecs (H.264/VP9/AV1) all have 155// and ours lacked, which is exactly why edges looked blocky. For every 4-pixel block boundary: if the step 156// across the edge is small enough to be a quantization artifact (< ~1.5*qp) AND the two neighbours are flat 157// (< ~0.5*qp), smooth the straddling pixels with a 3-tap; a real image edge (big step) is left untouched so 158// detail is preserved. Runs on the RECON on BOTH encode and decode (in-loop) so the P-reference stays 159// bit-exact. qp = the deadzone divisor carried on the wire (kind 0x57), identical both sides. 160func vv_deblock_plane(p: *u8, W: i64, H: i64, qp: i64, gentle: i64) -> i64 { 161 var c1: i64 = qp + (qp >> 1) + 2 // FULL (legacy vcv<8): cross-edge step threshold (alpha-like) 162 var c2: i64 = (qp >> 1) + 1 // FULL: neighbour-flatness threshold (beta-like) 163 if gentle == 1 { c1 = (qp >> 1) + 2; c2 = (qp >> 2) + 1 } // vcv-8: the full thresholds smoothed REAL edges in-loop -> cost 27-53pt BD-rate MEASURED; gentle only removes true block artifacts 164 var y: i64 = 0 // vertical edges (cols 4,8,..) smooth horizontal steps 165 while y < H { 166 let row: i64 = y * W 167 var xe: i64 = 4 168 while xe < W { 169 let i0: i64 = row + xe 170 let p1: i64 = p[i0 - 2] & 0xff; let p0: i64 = p[i0 - 1] & 0xff 171 let q0: i64 = p[i0] & 0xff; let q1: i64 = p[i0 + 1] & 0xff 172 if vv_iabs(p0 - q0) < c1 { if vv_iabs(p1 - p0) < c2 { if vv_iabs(q1 - q0) < c2 { 173 p[i0 - 1] = vv_clamp255((p1 + 2 * p0 + q0 + 2) >> 2) as u8 174 p[i0] = vv_clamp255((p0 + 2 * q0 + q1 + 2) >> 2) as u8 175 } } } 176 xe = xe + 4 177 } 178 y = y + 1 179 } 180 var ye: i64 = 4 // horizontal edges (rows 4,8,..) smooth vertical steps 181 while ye < H { 182 var x: i64 = 0 183 while x < W { 184 let i0: i64 = ye * W + x 185 let p1: i64 = p[i0 - 2 * W] & 0xff; let p0: i64 = p[i0 - W] & 0xff 186 let q0: i64 = p[i0] & 0xff; let q1: i64 = p[i0 + W] & 0xff 187 if vv_iabs(p0 - q0) < c1 { if vv_iabs(p1 - p0) < c2 { if vv_iabs(q1 - q0) < c2 { 188 p[i0 - W] = vv_clamp255((p1 + 2 * p0 + q0 + 2) >> 2) as u8 189 p[i0] = vv_clamp255((p0 + 2 * q0 + q1 + 2) >> 2) as u8 190 } } } 191 x = x + 1 192 } 193 ye = ye + 4 194 } 195 return 0 196} 197func vv_deblock(recon: *u8, W: i64, H: i64, qp: i64, gentle: i64) -> i64 { 198 let N: i64 = W * H 199 let C: i64 = (W / 2) * (H / 2) 200 vv_deblock_plane(recon, W, H, qp, gentle) 201 vv_deblock_plane(((recon as i64) + N) as *u8, W / 2, H / 2, qp, gentle) 202 vv_deblock_plane(((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, gentle) 203 return 0 204} 205 206func vv_enc(cur: *u8, prev: *u8, recon: *u8, W: i64, H: i64, qp: i64, keyframe: i64, sad: i64, 207 out: *u8, out_cap: i64, blk: *i64, mv: *i64) -> i64 { 208 let N: i64 = W * H 209 let C: i64 = (W / 2) * (H / 2) 210 let yb: i64 = (vc_enc_frame_packed_tf(cur, prev, recon, W, H, qp, keyframe, sad, ((out as i64) + 12) as *u8, blk, mv, 1) + 7) / 8 211 if 12 + yb > out_cap { return 0 - 1 } 212 let ub: i64 = (vc_enc_frame_packed_tf(((cur as i64) + N) as *u8, ((prev as i64) + N) as *u8, ((recon as i64) + N) as *u8, 213 W / 2, H / 2, qp, keyframe, sad, ((out as i64) + 12 + yb) as *u8, blk, mv, 1) + 7) / 8 214 if 12 + yb + ub > out_cap { return 0 - 1 } 215 let vb: i64 = (vc_enc_frame_packed_tf(((cur as i64) + N + C) as *u8, ((prev as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, 216 W / 2, H / 2, qp, keyframe, sad, ((out as i64) + 12 + yb + ub) as *u8, blk, mv, 1) + 7) / 8 // tf=1 DCT-II: +2.12dB vs WHT, less blocky (measured) 217 if 12 + yb + ub + vb > out_cap { return 0 - 1 } 218 vv_wr_u32(out, 0, yb) 219 vv_wr_u32(out, 4, ub) 220 vv_wr_u32(out, 8, vb) 221 vv_deblock(recon, W, H, qp, 0) // in-loop: smooth the recon that displays AND becomes next-frame prev 222 return 12 + yb + ub + vb 223} 224 225// decode one wire frame into recon (YUV420); prev = the receiver's previous recon for this SENDER. 226// Defensive at the boundary (rule 12): plane lengths must fit in_len exactly-or-under, else -1 (no read 227// past the wire buffer on a truncated/hostile frame). Returns 0 ok / -1 refused. 228func vv_dec(prev: *u8, recon: *u8, W: i64, H: i64, qp: i64, in_: *u8, in_len: i64, blk: *i64, mv: *i64) -> i64 { 229 if in_len < 12 { return 0 - 1 } 230 let yb: i64 = vv_rd_u32b(in_, 0) 231 let ub: i64 = vv_rd_u32b(in_, 4) 232 let vb: i64 = vv_rd_u32b(in_, 8) 233 if yb < 0 { return 0 - 1 } 234 if ub < 0 { return 0 - 1 } 235 if vb < 0 { return 0 - 1 } 236 if 12 + yb + ub + vb > in_len { return 0 - 1 } 237 let N: i64 = W * H 238 let C: i64 = (W / 2) * (H / 2) 239 vc_dec_frame_packed_tf(prev, recon, W, H, qp, ((in_ as i64) + 12) as *u8, blk, mv, 1) // tf=1 DCT-II -- MUST match vv_enc 240 vc_dec_frame_packed_tf(((prev as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb) as *u8, blk, mv, 1) 241 vc_dec_frame_packed_tf(((prev as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb + ub) as *u8, blk, mv, 1) 242 vv_deblock(recon, W, H, qp, 0) // in-loop: MUST match vv_enc exactly -> bit-exact P-reference 243 return 0 244} 245 246// RANGE-CODED variants (task #31): identical to vv_enc/vv_dec but each plane's frame goes through the range 247// coder (rctx = i64[>=5] providing est/probs/rcbuf). ~36% smaller coeff stream, bit-exact. Version-negotiated 248// (vcv>=3) so a CAVLC-only peer never receives one. The CAVLC vv_enc/vv_dec above are UNTOUCHED. 249func vv_enc_rc(cur: *u8, prev: *u8, recon: *u8, W: i64, H: i64, qp: i64, keyframe: i64, sad: i64, out: *u8, out_cap: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 250 let N: i64 = W * H 251 let C: i64 = (W / 2) * (H / 2) 252 let yb: i64 = (vc_enc_frame_packed_rc(cur, prev, recon, W, H, qp, keyframe, sad, ((out as i64) + 12) as *u8, blk, mv, 1, rctx) + 7) / 8 253 if 12 + yb > out_cap { return 0 - 1 } 254 let ub: i64 = (vc_enc_frame_packed_rc(((cur as i64) + N) as *u8, ((prev as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, keyframe, sad, ((out as i64) + 12 + yb) as *u8, blk, mv, 1, rctx) + 7) / 8 255 if 12 + yb + ub > out_cap { return 0 - 1 } 256 let vb: i64 = (vc_enc_frame_packed_rc(((cur as i64) + N + C) as *u8, ((prev as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, keyframe, sad, ((out as i64) + 12 + yb + ub) as *u8, blk, mv, 1, rctx) + 7) / 8 257 if 12 + yb + ub + vb > out_cap { return 0 - 1 } 258 vv_wr_u32(out, 0, yb) 259 vv_wr_u32(out, 4, ub) 260 vv_wr_u32(out, 8, vb) 261 vv_deblock(recon, W, H, qp, 0) 262 return 12 + yb + ub + vb 263} 264func vv_dec_rc(prev: *u8, recon: *u8, W: i64, H: i64, qp: i64, in_: *u8, in_len: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 265 if in_len < 12 { return 0 - 1 } 266 let yb: i64 = vv_rd_u32b(in_, 0) 267 let ub: i64 = vv_rd_u32b(in_, 4) 268 let vb: i64 = vv_rd_u32b(in_, 8) 269 if yb < 0 { return 0 - 1 } 270 if ub < 0 { return 0 - 1 } 271 if vb < 0 { return 0 - 1 } 272 if 12 + yb + ub + vb > in_len { return 0 - 1 } 273 let N: i64 = W * H 274 let C: i64 = (W / 2) * (H / 2) 275 vc_dec_frame_packed_rc(prev, recon, W, H, qp, ((in_ as i64) + 12) as *u8, blk, mv, 1, rctx) 276 vc_dec_frame_packed_rc(((prev as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb) as *u8, blk, mv, 1, rctx) 277 vc_dec_frame_packed_rc(((prev as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb + ub) as *u8, blk, mv, 1, rctx) 278 vv_deblock(recon, W, H, qp, 0) 279 return 0 280} 281 282// ---- ENCODER-SIGNALED IN-LOOP RESTORATION (neural rung 2, t8-family streams only). The blind static 283// display filter measurably did NOT transfer across scenes (nf_gate v1-v3) -- so the filter is applied 284// ONLY where the encoder MEASURED a win against the source THIS frame (the AV1-loop-restoration 285// principle): after deblock, filter the luma recon into scratch, compare SSE vs the source, and only on 286// a strict win signal the stream's nf bit + adopt the filtered recon IN-LOOP (both sides identical -> 287// bit-exact chain; a win can compound through the P chain). rctx[6]=trained table (vc_nf_load), 288// rctx[7]=scratch >= W*H; either 0 -> feature off (bit stays 0). Decoder refuses an nf frame it cannot 289// honor (no table/scratch) rather than diverging. GUARANTEED-NEVER-HURT by construction. 290// PER-BAND signaling (whole-frame all-or-nothing measured DORMANT -- one bad region vetoed every frame; 291// AV1 signals restoration per unit for exactly this reason). Bands = 16-px luma row groups (H mult of 16 292// by codec-safe geometry). Encoder: filter the whole plane once into scratch, adopt each band ONLY where 293// its OWN SSE strictly improves, set that band's bit in a trailer appended after the 3 plane streams 294// ((H/16+7)/8 bytes), and flag trailer-presence in the Y stream's nf bit. Decoder mirrors: same full-plane 295// filter of the SAME pre-adoption recon -> identical scratch -> copies the flagged bands. Returns the 296// trailer byte count (0 when nothing fired / feature off). 297func vv_nf_enc(cur: *u8, recon: *u8, W: i64, H: i64, qp: i64, ybuf: *u8, nfbit: i64, tr: *u8, rctx: *i64) -> i64 { 298 if rctx[6] == 0 { return 0 } 299 if rctx[7] == 0 { return 0 } 300 let tblp: *i64 = rctx[6] as *i64 301 let scr: *u8 = rctx[7] as *u8 302 vc_nf_apply(recon, W, H, scr, qp, tblp) 303 let bands: i64 = H / 16 304 let tbytes: i64 = (bands + 7) / 8 305 var tb: i64 = 0 306 while tb < tbytes { tr[tb] = 0 as u8; tb = tb + 1 } 307 var fired: i64 = 0 308 var b: i64 = 0 309 while b < bands { 310 var sr: i64 = 0 311 var sf: i64 = 0 312 var y: i64 = b * 16 313 while y < b*16 + 16 { 314 let row: i64 = y * W 315 var x: i64 = 0 316 while x < W { 317 let c: i64 = cur[row + x] & 0xff 318 let dr: i64 = (recon[row + x] & 0xff) - c 319 let df: i64 = (scr[row + x] & 0xff) - c 320 sr = sr + dr*dr 321 sf = sf + df*df 322 x = x + 1 323 } 324 y = y + 1 325 } 326 if sf < sr { 327 tr[b >> 3] = (tr[b >> 3] | (1 << (b & 7))) as u8 328 var y2: i64 = b * 16 329 while y2 < b*16 + 16 { 330 let row2: i64 = y2 * W 331 var x2: i64 = 0 332 while x2 < W { recon[row2 + x2] = scr[row2 + x2]; x2 = x2 + 1 } 333 y2 = y2 + 1 334 } 335 fired = fired + 1 336 } 337 b = b + 1 338 } 339 if fired == 0 { return 0 } 340 nx_bw_put(ybuf, nfbit, 1, 1) 341 return tbytes 342} 343func vv_nf_dec(recon: *u8, W: i64, H: i64, qp: i64, ybuf: *u8, nfbit: i64, tr: *u8, rctx: *i64) -> i64 { 344 if nx_br_get(ybuf, nfbit, 1) == 0 { return 0 } 345 if rctx[6] == 0 { return 0 - 1 } 346 if rctx[7] == 0 { return 0 - 1 } 347 let tblp: *i64 = rctx[6] as *i64 348 let scr: *u8 = rctx[7] as *u8 349 vc_nf_apply(recon, W, H, scr, qp, tblp) 350 let bands: i64 = H / 16 351 var b: i64 = 0 352 while b < bands { 353 if ((tr[b >> 3] >> (b & 7)) & 1) == 1 { 354 var y: i64 = b * 16 355 while y < b*16 + 16 { 356 let row: i64 = y * W 357 var x: i64 = 0 358 while x < W { recon[row + x] = scr[row + x]; x = x + 1 } 359 y = y + 1 360 } 361 } 362 b = b + 1 363 } 364 return 0 365} 366// trailer length for a decoded frame: (H/16 + 7)/8 when the Y stream's nf bit is set, else 0. 367func vv_nf_trlen(H: i64, ybuf: *u8, nfbit: i64) -> i64 { 368 if nx_br_get(ybuf, nfbit, 1) == 0 { return 0 } 369 return (H / 16 + 7) / 8 370} 371 372// VARIABLE-TRANSFORM (t8) variants (task #46 rung 2): per-MB 8x8/4x4 select over the same wire layout. 373// rctx = i64[>=5] = [emode, est, probs, rcbuf, t8c] with t8c = i64[VC_T8_SIZE] slab vc_t8_init'd once by 374// the caller. vv_enc_t8/vv_dec_t8 = CAVLC entropy (rctx[0] MUST be 0); vv_enc_rct8/vv_dec_rct8 = range 375// coder stacked on top (rctx[0]=1, probs sized >= RC_NCTX8). Version-negotiated like rc (vcv + header 376// flag) so an old peer never receives one; vv_enc/vv_dec/vv_enc_rc above are UNTOUCHED. 377func vv_enc_t8(cur: *u8, prev: *u8, recon: *u8, W: i64, H: i64, qp: i64, keyframe: i64, sad: i64, out: *u8, out_cap: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 378 let N: i64 = W * H 379 let C: i64 = (W / 2) * (H / 2) 380 rctx[0] = (rctx[0] | 16) - 16 // luma: t8-select ON 381 let yb: i64 = (vc_enc_frame_packed_t8(cur, prev, recon, W, H, qp, keyframe, sad, ((out as i64) + 12) as *u8, blk, mv, 1, rctx) + 7) / 8 382 if 12 + yb > out_cap { return 0 - 1 } 383 rctx[0] = rctx[0] | 16 // chroma: 4x4 only (field 786: 8x8 color tiles) 384 let ub: i64 = (vc_enc_frame_packed_t8(((cur as i64) + N) as *u8, ((prev as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, keyframe, sad, ((out as i64) + 12 + yb) as *u8, blk, mv, 1, rctx) + 7) / 8 385 if 12 + yb + ub > out_cap { return 0 - 1 } 386 let vb: i64 = (vc_enc_frame_packed_t8(((cur as i64) + N + C) as *u8, ((prev as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, keyframe, sad, ((out as i64) + 12 + yb + ub) as *u8, blk, mv, 1, rctx) + 7) / 8 387 if 12 + yb + ub + vb > out_cap { return 0 - 1 } 388 vv_wr_u32(out, 0, yb) 389 vv_wr_u32(out, 4, ub) 390 vv_wr_u32(out, 8, vb) 391 vv_deblock(recon, W, H, qp, 0) 392 var tb2: i64 = 0 393 if keyframe == 1 { if 12 + yb + ub + vb + (H/16 + 7)/8 <= out_cap { 394 // nf evaluated on KEYFRAMES only (field 788: per-frame filter+SSE cost fps on phones); the bit 395 // rides per frame so P-frame nf can return once the phone fps budget is measured clean. 396 tb2 = vv_nf_enc(cur, recon, W, H, qp, ((out as i64) + 12) as *u8, 1, ((out as i64) + 12 + yb + ub + vb) as *u8, rctx) 397 } } 398 return 12 + yb + ub + vb + tb2 399} 400func vv_dec_t8(prev: *u8, recon: *u8, W: i64, H: i64, qp: i64, in_: *u8, in_len: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 401 if in_len < 12 { return 0 - 1 } 402 let yb: i64 = vv_rd_u32b(in_, 0) 403 let ub: i64 = vv_rd_u32b(in_, 4) 404 let vb: i64 = vv_rd_u32b(in_, 8) 405 if yb < 0 { return 0 - 1 } 406 if ub < 0 { return 0 - 1 } 407 if vb < 0 { return 0 - 1 } 408 if 12 + yb + ub + vb > in_len { return 0 - 1 } 409 let N: i64 = W * H 410 let C: i64 = (W / 2) * (H / 2) 411 rctx[0] = (rctx[0] | 16) - 16 // luma: rich syntax (MUST mirror vv_enc_t8) 412 vc_dec_frame_packed_t8(prev, recon, W, H, qp, ((in_ as i64) + 12) as *u8, blk, mv, 1, rctx) 413 rctx[0] = rctx[0] | 16 // chroma: conservative plane = legacy 4-mode intra 414 vc_dec_frame_packed_t8(((prev as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb) as *u8, blk, mv, 1, rctx) 415 vc_dec_frame_packed_t8(((prev as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb + ub) as *u8, blk, mv, 1, rctx) 416 vv_deblock(recon, W, H, qp, 0) 417 let tl: i64 = vv_nf_trlen(H, ((in_ as i64) + 12) as *u8, 1) 418 if 12 + yb + ub + vb + tl > in_len { return 0 - 1 } 419 if tl > 0 { if vv_nf_dec(recon, W, H, qp, ((in_ as i64) + 12) as *u8, 1, ((in_ as i64) + 12 + yb + ub + vb) as *u8, rctx) != 0 { return 0 - 1 } } 420 return 0 421} 422func vv_enc_rct8(cur: *u8, prev: *u8, recon: *u8, W: i64, H: i64, qp: i64, keyframe: i64, sad: i64, out: *u8, out_cap: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 423 let N: i64 = W * H 424 let C: i64 = (W / 2) * (H / 2) 425 rctx[0] = (rctx[0] | 16) - 16 // luma: t8-select ON 426 let yb: i64 = (vc_enc_frame_packed_rct8(cur, prev, recon, W, H, qp, keyframe, sad, ((out as i64) + 12) as *u8, blk, mv, 1, rctx) + 7) / 8 427 if 12 + yb > out_cap { return 0 - 1 } 428 rctx[0] = rctx[0] | 16 // chroma: 4x4 only (field 786: 8x8 color tiles) 429 let hbit: i64 = rctx[0] & 4096 // P2 heat plane is LUMA-grid-indexed: clear its gate 430 rctx[0] = rctx[0] - hbit // (bit12) for the chroma planes -- index spaces differ 431 let ub: i64 = (vc_enc_frame_packed_rct8(((cur as i64) + N) as *u8, ((prev as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, keyframe, sad, ((out as i64) + 12 + yb) as *u8, blk, mv, 1, rctx) + 7) / 8 432 if 12 + yb + ub > out_cap { rctx[0] = rctx[0] | hbit; return 0 - 1 } 433 let vb: i64 = (vc_enc_frame_packed_rct8(((cur as i64) + N + C) as *u8, ((prev as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, keyframe, sad, ((out as i64) + 12 + yb + ub) as *u8, blk, mv, 1, rctx) + 7) / 8 434 rctx[0] = rctx[0] | hbit 435 if 12 + yb + ub + vb > out_cap { return 0 - 1 } 436 vv_wr_u32(out, 0, yb) 437 vv_wr_u32(out, 4, ub) 438 vv_wr_u32(out, 8, vb) 439 vv_deblock(recon, W, H, qp, (rctx[0] >> 9) & 1) // vcv-8: emode bit9 = gentle deblock (MUST mirror vv_dec_rct8) 440 var tb2: i64 = 0 441 if keyframe == 1 { if 12 + yb + ub + vb + (H/16 + 7)/8 <= out_cap { 442 tb2 = vv_nf_enc(cur, recon, W, H, qp, ((out as i64) + 12) as *u8, 17, ((out as i64) + 12 + yb + ub + vb) as *u8, rctx) 443 } } 444 return 12 + yb + ub + vb + tb2 445} 446func vv_dec_rct8(prev: *u8, recon: *u8, W: i64, H: i64, qp: i64, in_: *u8, in_len: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 447 if in_len < 12 { return 0 - 1 } 448 let yb: i64 = vv_rd_u32b(in_, 0) 449 let ub: i64 = vv_rd_u32b(in_, 4) 450 let vb: i64 = vv_rd_u32b(in_, 8) 451 if yb < 0 { return 0 - 1 } 452 if ub < 0 { return 0 - 1 } 453 if vb < 0 { return 0 - 1 } 454 if 12 + yb + ub + vb > in_len { return 0 - 1 } 455 let N: i64 = W * H 456 let C: i64 = (W / 2) * (H / 2) 457 rctx[0] = (rctx[0] | 16) - 16 // luma: rich syntax (MUST mirror vv_enc_rct8) 458 vc_dec_frame_packed_rct8(prev, recon, W, H, qp, ((in_ as i64) + 12) as *u8, blk, mv, 1, rctx) 459 rctx[0] = rctx[0] | 16 // chroma: conservative plane = legacy 4-mode intra 460 vc_dec_frame_packed_rct8(((prev as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb) as *u8, blk, mv, 1, rctx) 461 vc_dec_frame_packed_rct8(((prev as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb + ub) as *u8, blk, mv, 1, rctx) 462 vv_deblock(recon, W, H, qp, (rctx[0] >> 9) & 1) // vcv-8: emode bit9 = gentle deblock (recovers ~40 BD-rate pts) 463 let tl: i64 = vv_nf_trlen(H, ((in_ as i64) + 12) as *u8, 17) 464 if 12 + yb + ub + vb + tl > in_len { return 0 - 1 } 465 if tl > 0 { if vv_nf_dec(recon, W, H, qp, ((in_ as i64) + 12) as *u8, 17, ((in_ as i64) + 12 + yb + ub + vb) as *u8, rctx) != 0 { return 0 - 1 } } 466 return 0 467} 468// ---- B-FRAME vv pair (vcv-9 VOD; 2026-07-14): full 3-plane bidirectional frame over the rct8 wire layout 469// [ylen:u32][ulen:u32][vlen:u32][Y][U][V]. Each plane runs the _b frame pair with its own per-MB direction 470// bits (chroma decides on its own half-res grid -- self-contained, decoder mirrors). No nf (never key), no 471// heat (bit12 cleared for chroma exactly like rct8). Deblock bit9-gated both sides. B recon is DISPLAY-ONLY 472// (disposable): callers never feed it back as a reference, so anchor drift behaviour is byte-identical to 473// today's P chain. past/fut = the two DECODED anchor recons bracketing this frame in display order. 474func vv_enc_b(cur: *u8, past: *u8, fut: *u8, recon: *u8, W: i64, H: i64, qp: i64, sad: i64, out: *u8, out_cap: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 475 let N: i64 = W * H 476 let C: i64 = (W / 2) * (H / 2) 477 rctx[0] = (rctx[0] | 16) - 16 // luma: t8-select ON (mirror vv_enc_rct8) 478 let yb: i64 = (vc_enc_frame_packed_b(cur, past, fut, recon, W, H, qp, sad, ((out as i64) + 12) as *u8, blk, mv, 1, rctx) + 7) / 8 479 if 12 + yb > out_cap { return 0 - 1 } 480 rctx[0] = rctx[0] | 16 // chroma: 4x4 only 481 let hbit: i64 = rctx[0] & 4096 482 rctx[0] = rctx[0] - hbit 483 let ub: i64 = (vc_enc_frame_packed_b(((cur as i64) + N) as *u8, ((past as i64) + N) as *u8, ((fut as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, sad, ((out as i64) + 12 + yb) as *u8, blk, mv, 1, rctx) + 7) / 8 484 if 12 + yb + ub > out_cap { rctx[0] = rctx[0] | hbit; return 0 - 1 } 485 let vb: i64 = (vc_enc_frame_packed_b(((cur as i64) + N + C) as *u8, ((past as i64) + N + C) as *u8, ((fut as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, sad, ((out as i64) + 12 + yb + ub) as *u8, blk, mv, 1, rctx) + 7) / 8 486 rctx[0] = rctx[0] | hbit 487 if 12 + yb + ub + vb > out_cap { return 0 - 1 } 488 vv_wr_u32(out, 0, yb) 489 vv_wr_u32(out, 4, ub) 490 vv_wr_u32(out, 8, vb) 491 vv_deblock(recon, W, H, qp, (rctx[0] >> 9) & 1) // MUST mirror vv_dec_b 492 return 12 + yb + ub + vb 493} 494func vv_dec_b(past: *u8, fut: *u8, recon: *u8, W: i64, H: i64, qp: i64, in_: *u8, in_len: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 495 if in_len < 12 { return 0 - 1 } 496 let yb: i64 = vv_rd_u32b(in_, 0) 497 let ub: i64 = vv_rd_u32b(in_, 4) 498 let vb: i64 = vv_rd_u32b(in_, 8) 499 if yb < 0 { return 0 - 1 } 500 if ub < 0 { return 0 - 1 } 501 if vb < 0 { return 0 - 1 } 502 if 12 + yb + ub + vb > in_len { return 0 - 1 } 503 let N: i64 = W * H 504 let C: i64 = (W / 2) * (H / 2) 505 rctx[0] = (rctx[0] | 16) - 16 // luma: rich syntax (MUST mirror vv_enc_b) 506 vc_dec_frame_packed_b(past, fut, recon, W, H, qp, ((in_ as i64) + 12) as *u8, blk, mv, 1, rctx) 507 rctx[0] = rctx[0] | 16 // chroma: conservative plane 508 vc_dec_frame_packed_b(((past as i64) + N) as *u8, ((fut as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb) as *u8, blk, mv, 1, rctx) 509 vc_dec_frame_packed_b(((past as i64) + N + C) as *u8, ((fut as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb + ub) as *u8, blk, mv, 1, rctx) 510 vv_deblock(recon, W, H, qp, (rctx[0] >> 9) & 1) 511 return 0 512} 513 514// ---- rct9 LEAN-SKIP vv pair (vcv-10 candidate; 2026-07-14): P-frames only (keyframes ride vv_enc_rct8 -- 515// nothing to lean out on a key). Same [ylen][ulen][vlen] wire; each plane = the rct9 frame pair (rc-context 516// skip flag; lv/t8 only on coded MBs). Deblock bit9-gated both sides; no nf. probs must be sized >= RC_NCTX8+3. 517func vv_enc_rct9(cur: *u8, prev: *u8, recon: *u8, W: i64, H: i64, qp: i64, sad: i64, out: *u8, out_cap: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 518 let N: i64 = W * H 519 let C: i64 = (W / 2) * (H / 2) 520 rctx[0] = (rctx[0] | 16) - 16 521 let yb: i64 = (vc_enc_frame_packed_rct9(cur, prev, recon, W, H, qp, sad, ((out as i64) + 12) as *u8, blk, mv, 1, rctx) + 7) / 8 522 if 12 + yb > out_cap { return 0 - 1 } 523 rctx[0] = rctx[0] | 16 524 let hbit: i64 = rctx[0] & 4096 525 rctx[0] = rctx[0] - hbit 526 let ub: i64 = (vc_enc_frame_packed_rct9(((cur as i64) + N) as *u8, ((prev as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, sad, ((out as i64) + 12 + yb) as *u8, blk, mv, 1, rctx) + 7) / 8 527 if 12 + yb + ub > out_cap { rctx[0] = rctx[0] | hbit; return 0 - 1 } 528 let vb: i64 = (vc_enc_frame_packed_rct9(((cur as i64) + N + C) as *u8, ((prev as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, sad, ((out as i64) + 12 + yb + ub) as *u8, blk, mv, 1, rctx) + 7) / 8 529 rctx[0] = rctx[0] | hbit 530 if 12 + yb + ub + vb > out_cap { return 0 - 1 } 531 vv_wr_u32(out, 0, yb) 532 vv_wr_u32(out, 4, ub) 533 vv_wr_u32(out, 8, vb) 534 vv_deblock(recon, W, H, qp, (rctx[0] >> 9) & 1) // MUST mirror vv_dec_rct9 535 return 12 + yb + ub + vb 536} 537func vv_dec_rct9(prev: *u8, recon: *u8, W: i64, H: i64, qp: i64, in_: *u8, in_len: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 538 if in_len < 12 { return 0 - 1 } 539 let yb: i64 = vv_rd_u32b(in_, 0) 540 let ub: i64 = vv_rd_u32b(in_, 4) 541 let vb: i64 = vv_rd_u32b(in_, 8) 542 if yb < 0 { return 0 - 1 } 543 if ub < 0 { return 0 - 1 } 544 if vb < 0 { return 0 - 1 } 545 if 12 + yb + ub + vb > in_len { return 0 - 1 } 546 let N: i64 = W * H 547 let C: i64 = (W / 2) * (H / 2) 548 rctx[0] = (rctx[0] | 16) - 16 549 vc_dec_frame_packed_rct9(prev, recon, W, H, qp, ((in_ as i64) + 12) as *u8, blk, mv, 1, rctx) 550 rctx[0] = rctx[0] | 16 551 vc_dec_frame_packed_rct9(((prev as i64) + N) as *u8, ((recon as i64) + N) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb) as *u8, blk, mv, 1, rctx) 552 vc_dec_frame_packed_rct9(((prev as i64) + N + C) as *u8, ((recon as i64) + N + C) as *u8, W / 2, H / 2, qp, ((in_ as i64) + 12 + yb + ub) as *u8, blk, mv, 1, rctx) 553 vv_deblock(recon, W, H, qp, (rctx[0] >> 9) & 1) 554 return 0 555} 556 557// ============================================================================================================ 558// TILE-PARALLEL BAND codec (task #47 rung 1b): encode/decode luma-MB-rows [by0,by1) (by0,by1 EVEN for chroma 559// alignment) of ALL 3 planes as a SELF-CONTAINED band. A frame = K bands, each handed to its own Web Worker 560// (its own wasm instance) -> the encode wall-clock drops ~K x -> unlocks higher res/fps and the road to GPU. 561// Deblock is BAND-LOCAL (never crosses the band's top edge) so bands never touch each other's pixels. The 562// only cost vs a whole-frame encode: the K-1 band SEAMS aren't cross-deblocked (a minor, in-loop-consistent 563// artifact; a seam pass can clean it later). Band wire = [ylen:u32][ulen:u32][vlen:u32][Yband][Uband][Vband]. 564// ============================================================================================================ 565func vv_deblock_plane_band(p: *u8, W: i64, H: i64, y0: i64, y1: i64, qp: i64) -> i64 { 566 let c1: i64 = qp + (qp >> 1) + 2 567 let c2: i64 = (qp >> 1) + 1 568 var y: i64 = y0 569 while y < y1 { // vertical edges (all within-band rows) 570 let row: i64 = y * W; var xe: i64 = 4 571 while xe < W { 572 let i0: i64 = row + xe 573 let p1: i64 = p[i0-2]&0xff; let p0: i64 = p[i0-1]&0xff; let q0: i64 = p[i0]&0xff; let q1: i64 = p[i0+1]&0xff 574 if vv_iabs(p0-q0) < c1 { if vv_iabs(p1-p0) < c2 { if vv_iabs(q1-q0) < c2 { 575 p[i0-1] = vv_clamp255((p1+2*p0+q0+2)>>2) as u8; p[i0] = vv_clamp255((p0+2*q0+q1+2)>>2) as u8 } } } 576 xe = xe + 4 } 577 y = y + 1 } 578 var ye: i64 = y0 + 4 // horizontal edges from y0+4 -> the y0 band-top boundary is untouched 579 while ye < y1 { 580 var x: i64 = 0 581 while x < W { 582 let i0: i64 = ye*W + x 583 let p1: i64 = p[i0-2*W]&0xff; let p0: i64 = p[i0-W]&0xff; let q0: i64 = p[i0]&0xff; let q1: i64 = p[i0+W]&0xff 584 if vv_iabs(p0-q0) < c1 { if vv_iabs(p1-p0) < c2 { if vv_iabs(q1-q0) < c2 { 585 p[i0-W] = vv_clamp255((p1+2*p0+q0+2)>>2) as u8; p[i0] = vv_clamp255((p0+2*q0+q1+2)>>2) as u8 } } } 586 x = x + 1 } 587 ye = ye + 4 } 588 return 0 } 589func vv_deblock_band(recon: *u8, W: i64, H: i64, by0: i64, by1: i64, qp: i64) -> i64 { 590 let N: i64 = W*H; let C: i64 = (W/2)*(H/2) 591 vv_deblock_plane_band(recon, W, H, by0*16, by1*16, qp) 592 vv_deblock_plane_band(((recon as i64)+N) as *u8, W/2, H/2, by0*8, by1*8, qp) 593 vv_deblock_plane_band(((recon as i64)+N+C) as *u8, W/2, H/2, by0*8, by1*8, qp) 594 return 0 } 595func vv_enc_band(cur: *u8, prev: *u8, recon: *u8, W: i64, H: i64, by0: i64, by1: i64, qp: i64, keyframe: i64, sad: i64, out: *u8, out_cap: i64, blk: *i64, mv: *i64) -> i64 { 596 let N: i64 = W*H; let C: i64 = (W/2)*(H/2) 597 let yb: i64 = (vc_enc_frame_packed_region(cur, prev, recon, W, H, by0, by1, qp, keyframe, sad, ((out as i64)+12) as *u8, blk, mv, 1) + 7)/8 598 if 12+yb > out_cap { return 0-1 } 599 let ub: i64 = (vc_enc_frame_packed_region(((cur as i64)+N) as *u8, ((prev as i64)+N) as *u8, ((recon as i64)+N) as *u8, W/2, H/2, by0/2, by1/2, qp, keyframe, sad, ((out as i64)+12+yb) as *u8, blk, mv, 1) + 7)/8 600 if 12+yb+ub > out_cap { return 0-1 } 601 let vb: i64 = (vc_enc_frame_packed_region(((cur as i64)+N+C) as *u8, ((prev as i64)+N+C) as *u8, ((recon as i64)+N+C) as *u8, W/2, H/2, by0/2, by1/2, qp, keyframe, sad, ((out as i64)+12+yb+ub) as *u8, blk, mv, 1) + 7)/8 602 if 12+yb+ub+vb > out_cap { return 0-1 } 603 vv_wr_u32(out, 0, yb); vv_wr_u32(out, 4, ub); vv_wr_u32(out, 8, vb) 604 vv_deblock_band(recon, W, H, by0, by1, qp) 605 return 12+yb+ub+vb } 606func vv_dec_band(prev: *u8, recon: *u8, W: i64, H: i64, by0: i64, by1: i64, qp: i64, in_: *u8, in_len: i64, blk: *i64, mv: *i64) -> i64 { 607 if in_len < 12 { return 0-1 } 608 let yb: i64 = vv_rd_u32b(in_, 0); let ub: i64 = vv_rd_u32b(in_, 4); let vb: i64 = vv_rd_u32b(in_, 8) 609 if yb < 0 { return 0-1 } 610 if ub < 0 { return 0-1 } 611 if vb < 0 { return 0-1 } 612 if 12+yb+ub+vb > in_len { return 0-1 } 613 let N: i64 = W*H; let C: i64 = (W/2)*(H/2) 614 vc_dec_frame_packed_region(prev, recon, W, H, by0, by1, qp, ((in_ as i64)+12) as *u8, blk, mv, 1) 615 vc_dec_frame_packed_region(((prev as i64)+N) as *u8, ((recon as i64)+N) as *u8, W/2, H/2, by0/2, by1/2, qp, ((in_ as i64)+12+yb) as *u8, blk, mv, 1) 616 vc_dec_frame_packed_region(((prev as i64)+N+C) as *u8, ((recon as i64)+N+C) as *u8, W/2, H/2, by0/2, by1/2, qp, ((in_ as i64)+12+yb+ub) as *u8, blk, mv, 1) 617 vv_deblock_band(recon, W, H, by0, by1, qp) 618 return 0 } 619// ============================================================================================================ 620// 824 RICH BAND pair (720p rung B): the FULL rct8 stack (rc entropy + t8-RD + sig-map + partition + heat-AQ + 621// GENTLE deblock) over MB rows [by0,by1) -- K independent bands unlock tile-parallel encode at 720p-class 622// (single-thread 1280x704 = 8.8fps MEASURED; ~4 bands = real-time; band geometry must keep by0/by1 EVEN for 623// chroma MB alignment -- 1152x640 gives K=4). Wire per band = [ylen:u32][ulen:u32][vlen:u32][Y][U][V], each 624// plane a self-contained rct8 section. NF is intentionally NOT banded (keyframe-only micro-win, placeholder 625// bit stays 0 -> per-band streams stay stock-decodable). The legacy vv_*_band pair above keeps the OLD 626// aggressive deblock constant (its enc+dec are consistent); this pair honors emode bit9 gentle like the 627// whole-frame rct8 path (the 815 lesson: over-smoothing the in-loop reference cost 24-47 BD-rate pts). 628// ============================================================================================================ 629func vv_deblock_plane_band_g(p: *u8, W: i64, H: i64, y0: i64, y1: i64, qp: i64, gentle: i64) -> i64 { 630 var c1: i64 = qp + (qp >> 1) + 2 631 if gentle == 1 { c1 = (qp >> 1) + 2 } 632 let c2: i64 = (qp >> 1) + 1 633 var y: i64 = y0 634 while y < y1 { 635 let row: i64 = y * W; var xe: i64 = 4 636 while xe < W { 637 let i0: i64 = row + xe 638 let p1: i64 = p[i0-2]&0xff; let p0: i64 = p[i0-1]&0xff; let q0: i64 = p[i0]&0xff; let q1: i64 = p[i0+1]&0xff 639 if vv_iabs(p0-q0) < c1 { if vv_iabs(p1-p0) < c2 { if vv_iabs(q1-q0) < c2 { 640 p[i0-1] = vv_clamp255((p1+2*p0+q0+2)>>2) as u8; p[i0] = vv_clamp255((p0+2*q0+q1+2)>>2) as u8 } } } 641 xe = xe + 4 } 642 y = y + 1 } 643 var ye: i64 = y0 + 4 644 while ye < y1 { 645 var x: i64 = 0 646 while x < W { 647 let i0: i64 = ye*W + x 648 let p1: i64 = p[i0-2*W]&0xff; let p0: i64 = p[i0-W]&0xff; let q0: i64 = p[i0]&0xff; let q1: i64 = p[i0+W]&0xff 649 if vv_iabs(p0-q0) < c1 { if vv_iabs(p1-p0) < c2 { if vv_iabs(q1-q0) < c2 { 650 p[i0-W] = vv_clamp255((p1+2*p0+q0+2)>>2) as u8; p[i0] = vv_clamp255((p0+2*q0+q1+2)>>2) as u8 } } } 651 x = x + 1 } 652 ye = ye + 4 } 653 return 0 } 654func vv_deblock_band2(recon: *u8, W: i64, H: i64, by0: i64, by1: i64, qp: i64, gentle: i64) -> i64 { 655 let N: i64 = W*H; let C: i64 = (W/2)*(H/2) 656 vv_deblock_plane_band_g(recon, W, H, by0*16, by1*16, qp, gentle) 657 vv_deblock_plane_band_g(((recon as i64)+N) as *u8, W/2, H/2, by0*8, by1*8, qp, gentle) 658 vv_deblock_plane_band_g(((recon as i64)+N+C) as *u8, W/2, H/2, by0*8, by1*8, qp, gentle) 659 return 0 } 660func vv_enc_rct8_band(cur: *u8, prev: *u8, recon: *u8, W: i64, H: i64, by0: i64, by1: i64, qp: i64, keyframe: i64, sad: i64, out: *u8, out_cap: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 661 let N: i64 = W*H; let C: i64 = (W/2)*(H/2) 662 rctx[0] = (rctx[0] | 16) - 16 663 let yb: i64 = (vc_enc_frame_packed_rct8_region(cur, prev, recon, W, H, by0, by1, qp, keyframe, sad, ((out as i64)+12) as *u8, blk, mv, 1, rctx) + 7)/8 664 if 12+yb > out_cap { return 0-1 } 665 rctx[0] = rctx[0] | 16 666 let hbit: i64 = rctx[0] & 4096 667 rctx[0] = rctx[0] - hbit 668 let ub: i64 = (vc_enc_frame_packed_rct8_region(((cur as i64)+N) as *u8, ((prev as i64)+N) as *u8, ((recon as i64)+N) as *u8, W/2, H/2, by0/2, by1/2, qp, keyframe, sad, ((out as i64)+12+yb) as *u8, blk, mv, 1, rctx) + 7)/8 669 if 12+yb+ub > out_cap { rctx[0] = rctx[0] | hbit; return 0-1 } 670 let vb: i64 = (vc_enc_frame_packed_rct8_region(((cur as i64)+N+C) as *u8, ((prev as i64)+N+C) as *u8, ((recon as i64)+N+C) as *u8, W/2, H/2, by0/2, by1/2, qp, keyframe, sad, ((out as i64)+12+yb+ub) as *u8, blk, mv, 1, rctx) + 7)/8 671 rctx[0] = rctx[0] | hbit 672 if 12+yb+ub+vb > out_cap { return 0-1 } 673 vv_wr_u32(out, 0, yb); vv_wr_u32(out, 4, ub); vv_wr_u32(out, 8, vb) 674 vv_deblock_band2(recon, W, H, by0, by1, qp, (rctx[0] >> 9) & 1) 675 return 12+yb+ub+vb } 676func vv_dec_rct8_band(prev: *u8, recon: *u8, W: i64, H: i64, by0: i64, by1: i64, qp: i64, in_: *u8, in_len: i64, blk: *i64, mv: *i64, rctx: *i64) -> i64 { 677 if in_len < 12 { return 0-1 } 678 let yb: i64 = vv_rd_u32b(in_, 0); let ub: i64 = vv_rd_u32b(in_, 4); let vb: i64 = vv_rd_u32b(in_, 8) 679 if yb < 0 { return 0-1 } 680 if ub < 0 { return 0-1 } 681 if vb < 0 { return 0-1 } 682 if 12+yb+ub+vb > in_len { return 0-1 } 683 let N: i64 = W*H; let C: i64 = (W/2)*(H/2) 684 rctx[0] = (rctx[0] | 16) - 16 685 vc_dec_frame_packed_rct8_region(prev, recon, W, H, by0, by1, qp, ((in_ as i64)+12) as *u8, blk, mv, 1, rctx) 686 rctx[0] = rctx[0] | 16 687 vc_dec_frame_packed_rct8_region(((prev as i64)+N) as *u8, ((recon as i64)+N) as *u8, W/2, H/2, by0/2, by1/2, qp, ((in_ as i64)+12+yb) as *u8, blk, mv, 1, rctx) 688 vc_dec_frame_packed_rct8_region(((prev as i64)+N+C) as *u8, ((recon as i64)+N+C) as *u8, W/2, H/2, by0/2, by1/2, qp, ((in_ as i64)+12+yb+ub) as *u8, blk, mv, 1, rctx) 689 vv_deblock_band2(recon, W, H, by0, by1, qp, (rctx[0] >> 9) & 1) 690 return 0 }