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 }