code wiki / _hdl_build / nx_ts_lumadiff.nx

nx_ts_lumadiff.nx source

↩ module page · 231 lines · 10633 B

1// nx_ts_lumadiff.nx -- VISUAL dead-air measurement. 2// Byte-rate analysis CANNOT see dead air in this corpus (measured 2026-07-31: audio is CBR AAC, 3// video is rate-controlled, p25/p50 = 79-94%). But "nothing is happening" IS visible in the 4// PIXELS. This seeks to NXVI keyframe byte offsets, decodes luma with the gate-proven CAVLC 5// I-frame decoder, reduces each frame to a 16x9 luma signature, and reports the mean absolute 6// difference between consecutive sampled frames. Low MAD run = static = dead air. 7// Reuses nx_ts_es (lifted verbatim from nx_cam_poster, byte-identical proven) + nx_h264_iframe. 8// nx_ts_lumadiff <in.ts> <in.idx> [max_samples] 9// license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_itoa_lib.nx" // shared MSB-first emitter -- _hdl_build MAY import runtime/ (not the reverse) 12import "nx_ts_es.nx" 13import "nx_h264_sps.nx" 14import "nx_h264_pps.nx" 15import "nx_h264_iframe.nx" 16const LD_MAGIC_8388608: i64 = 8388608 17const LD_MAGIC_1048576: i64 = 1048576 18const LD_MAGIC_1024: i64 = 1024 19 20const LD_WIN: i64 = 3145728 // bytes read at each keyframe offset; one IDR access unit fits 21const LD_SIGW: i64 = 16 // signature grid width (cells) 22const LD_SIGH: i64 = 9 // signature grid height (cells) 23const LD_NALCAP: i64 = 4194304 24const LD_HEAD: i64 = 262144 // head read for SPS/PPS 25const LD_DEFSAMP: i64 = 40 // default number of keyframes sampled across the file 26 27func ld_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 28// MIGRATED to the shared emitter (debt 1785557603). THIS FUNCTION TOOK 28.5GB OF A 36GB HOST. 29// Measured 2026-08-01: this organ held 29166124 kB RSS on a 2,383,652-byte (2MB) input -- ~12,000x 30// the input size -- froze every seat, OOM-killed sibling builds, and made the build admitter DENY. 31// Cause: TWO sys_mmap(28) per call, neither freed; each rounds to a 4096B page, so 8192B leaked per 32// call, and 28.5GB / 8192B is ~3.66 MILLION calls from 9 call sites inside per-sample loops. 33// nxi_out is MSB-first, allocates NOTHING, and emits identical bytes including the sign (gate T9/T10). 34func ld_num(v: i64) -> i64 { nxi_out(v); return 0 } 35func ld_atoi(s: *u8) -> i64 { 36 var v: i64 = 0 37 var i: i64 = 0 38 while s[i] != (0 as u8) { if s[i] >= (48 as u8) { if s[i] <= (57 as u8) { v = v*10 + ((s[i]-(48 as u8)) as i64) } } i = i + 1 } 39 return v 40} 41func ld_r32(b: *u8, o: i64) -> i64 { 42 return ((b[o] as i64)<<24) | ((b[o+1] as i64)<<16) | ((b[o+2] as i64)<<8) | (b[o+3] as i64) 43} 44func ld_r64(b: *u8, o: i64) -> i64 { 45 var v: i64 = 0 46 var i: i64 = 0 47 while i < 8 { v = (v<<8) | (b[o+i] as i64); i = i + 1 } 48 return v 49} 50// reduce a decoded luma plane to a LD_SIGW x LD_SIGH mean-luma signature 51func ld_signature(yf: *u8, W: i64, cropW: i64, cropH: i64, sig: *i64) -> i64 { 52 var cy: i64 = 0 53 while cy < LD_SIGH { 54 var cx: i64 = 0 55 while cx < LD_SIGW { 56 let x0: i64 = cx * cropW / LD_SIGW 57 var x1: i64 = (cx+1) * cropW / LD_SIGW 58 let y0: i64 = cy * cropH / LD_SIGH 59 var y1: i64 = (cy+1) * cropH / LD_SIGH 60 if x1 <= x0 { x1 = x0 + 1 } 61 if y1 <= y0 { y1 = y0 + 1 } 62 var acc: i64 = 0 63 var n: i64 = 0 64 var yy: i64 = y0 65 while yy < y1 { 66 var xx: i64 = x0 67 while xx < x1 { acc = acc + (yf[yy*W + xx] as i64); n = n + 1; xx = xx + 1 } 68 yy = yy + 1 69 } 70 if n < 1 { n = 1 } 71 sig[cy*LD_SIGW + cx] = acc / n 72 cx = cx + 1 73 } 74 cy = cy + 1 75 } 76 return 0 77} 78 79func main(argc: i64, argv: *i64) -> i64 { 80 if argc < 3 { ld_puts("usage: nx_ts_lumadiff <in.ts> <in.idx> [max_samples]\n\x00" as *u8); return 2 } 81 let tspath: *u8 = argv[1] as *u8 82 let ixpath: *u8 = argv[2] as *u8 83 var maxs: i64 = LD_DEFSAMP 84 if argc >= 4 { maxs = ld_atoi(argv[3] as *u8) } 85 if maxs < 0 { maxs = 0 } // arg is WHICH keyframe now; never silently rewrite it 86 87 // ---- read the NXVI index 88 let ixfd: i64 = sys_openat_rd(ixpath) 89 if ixfd < 0 { ld_puts("ERR: cannot open index\n\x00" as *u8); return 1 } 90 let ib: *u8 = sys_mmap(LD_MAGIC_8388608) 91 var ilen: i64 = 0 92 var g: i64 = 1 93 while g == 1 { 94 let r: i64 = sys_read(ixfd, ((ib as i64)+ilen) as *u8, LD_MAGIC_1048576) 95 if r <= 0 { g = 0 } 96 if r > 0 { ilen = ilen + r } 97 } 98 sys_close(ixfd) 99 if ilen < 40 { ld_puts("ERR: index too short\n\x00" as *u8); return 3 } 100 if ib[0] != (78 as u8) { ld_puts("ERR: not NXVI\n\x00" as *u8); return 3 } 101 let ver: i64 = ld_r32(ib, 4) 102 var o: i64 = 8 103 o = o + 8 + 4 + 4 + 4 + 4 // dur_ms, arate, achan, vidpid, audpid 104 // v3 inserted srcsize(8) here. A FORMAT BUMP MUST UPDATE EVERY READER: parsing 105 // v3 at v2 offsets reads srcsize AS spslen and seeks out of bounds (core dump). 106 if ver >= 3 { o = o + 8 } 107 let spl: i64 = ld_r32(ib, o); o = o + 4 + spl 108 let ppl: i64 = ld_r32(ib, o); o = o + 4 + ppl 109 let nkf: i64 = ld_r64(ib, o); o = o + 8 110 if nkf < 2 { ld_puts("REFUSED: index has fewer than 2 keyframes\n\x00" as *u8); return 4 } 111 let ktab: i64 = o 112 113 // ---- SPS/PPS from the head of the TS 114 let tsfd: i64 = sys_openat_rd(tspath) 115 if tsfd < 0 { ld_puts("ERR: cannot open ts\n\x00" as *u8); return 1 } 116 let hb: *u8 = sys_mmap(LD_HEAD + 512) 117 var hl: i64 = 0 118 var g2: i64 = 1 119 while g2 == 1 { 120 let r: i64 = sys_read(tsfd, ((hb as i64)+hl) as *u8, LD_HEAD - hl) 121 if r <= 0 { g2 = 0 } 122 if r > 0 { hl = hl + r; if hl >= LD_HEAD { g2 = 0 } } 123 } 124 let es: *u8 = sys_mmap(LD_WIN + 512) 125 let pidout: *i64 = sys_mmap(64) as *i64 126 var eslen: i64 = demux_video_es(hb, hl, es, pidout) 127 let spsn: *u8 = sys_mmap(LD_MAGIC_1024) 128 let ppsn: *u8 = sys_mmap(LD_MAGIC_1024) 129 let sl: i64 = find_first_nal(es, eslen, 7, spsn, LD_MAGIC_1024) 130 let pl: i64 = find_first_nal(es, eslen, 8, ppsn, LD_MAGIC_1024) 131 if sl <= 0 { ld_puts("REFUSED: no SPS in head\n\x00" as *u8); return 5 } 132 if pl <= 0 { ld_puts("REFUSED: no PPS in head\n\x00" as *u8); return 5 } 133 let srb: *u8 = sys_mmap(LD_MAGIC_1024) 134 let prb: *u8 = sys_mmap(LD_MAGIC_1024) 135 let srl: i64 = nal_to_rbsp(spsn, sl, srb) 136 let prl: i64 = nal_to_rbsp(ppsn, pl, prb) 137 let sps: *i64 = sys_mmap(8*128) as *i64 138 let pps: *i64 = sys_mmap(8*128) as *i64 139 nx_h264_parse_sps(srb, srl, sps) 140 nx_h264_parse_pps(prb, prl, pps) 141 if pps[2] == 1 { ld_puts("SKIP: CABAC stream (CAVLC decoder only)\n\x00" as *u8); return 10 } 142 let mbW: i64 = sps[4] + 1 143 let mbH: i64 = sps[5] + 1 144 let W: i64 = mbW * 16 145 let H: i64 = mbH * 16 146 let cpW: i64 = mbW * 8 147 var cropW: i64 = sps[2] 148 var cropH: i64 = sps[3] 149 if cropW <= 0 { cropW = W } 150 if cropH <= 0 { cropH = H } 151 if cropW > W { cropW = W } 152 if cropH > H { cropH = H } 153 let yf: *u8 = sys_mmap(W*H + 64) 154 let uf: *u8 = sys_mmap(cpW*(H/2) + 64) 155 let vf: *u8 = sys_mmap(cpW*(H/2) + 64) 156 let win: *u8 = sys_mmap(LD_WIN + 512) 157 let idrn: *u8 = sys_mmap(LD_NALCAP) 158 let irb: *u8 = sys_mmap(LD_NALCAP) 159 let sig: *i64 = sys_mmap(8 * LD_SIGW * LD_SIGH) as *i64 160 let prev: *i64 = sys_mmap(8 * LD_SIGW * LD_SIGH) as *i64 161 let cells: i64 = LD_SIGW * LD_SIGH 162 163 ld_puts("LUMADIFF nkf=\x00" as *u8); ld_num(nkf) 164 ld_puts(" res=\x00" as *u8); ld_num(cropW); ld_puts("x\x00" as *u8); ld_num(cropH) 165 ld_puts(" samples=\x00" as *u8); ld_num(maxs); ld_puts("\n\x00" as *u8) 166 167 // GUARD: single-decode mode never uses step, but this line still ran and maxs 168 // can legitimately be 0 (decode keyframe 0), so it divided by zero -> SIGFPE on 169 // the FIRST child of every scan. A vestigial computation still faults. 170 var step: i64 = 1 171 if maxs > 0 { step = nkf / maxs } 172 if step < 1 { step = 1 } 173 var have: i64 = 0 174 var decoded: i64 = 0 175 var failed: i64 = 0 176 var lowruns: i64 = 0 177 var k: i64 = maxs 178 while k < nkf { 179 let t_ms: i64 = ld_r64(ib, ktab + k*16) 180 let boff: i64 = ld_r64(ib, ktab + k*16 + 8) 181 sys_lseek(tsfd, boff, 0) 182 var wl: i64 = 0 183 var g3: i64 = 1 184 while g3 == 1 { 185 let r: i64 = sys_read(tsfd, ((win as i64)+wl) as *u8, LD_WIN - wl) 186 if r <= 0 { g3 = 0 } 187 if r > 0 { wl = wl + r; if wl >= LD_WIN { g3 = 0 } } 188 } 189 ld_puts(" [seek] \x00" as *u8); ld_num(boff); ld_puts(" wl=\x00" as *u8); ld_num(wl); ld_puts("\n\x00" as *u8) 190 var el: i64 = demux_video_es(win, wl, es, pidout) 191 ld_puts(" [demux] el=\x00" as *u8); ld_num(el); ld_puts("\n\x00" as *u8) 192 let il: i64 = find_first_nal(es, el, 5, idrn, LD_NALCAP) 193 ld_puts(" [nal] il=\x00" as *u8); ld_num(il); ld_puts("\n\x00" as *u8) 194 if il > 0 { 195 let irl: i64 = nal_to_rbsp(idrn, il, irb) 196 ld_puts(" [pre-decode] irl=\x00" as *u8); ld_num(irl); ld_puts("\n\x00" as *u8) 197 let ok: i64 = nx_h264_decode_iframe(irb, irl, 5, sps, pps, yf, uf, vf, mbW, mbH) 198 ld_puts(" [decode] ok=\x00" as *u8); ld_num(ok); ld_puts("\n\x00" as *u8) 199 if ok == 1 { 200 ld_signature(yf, W, cropW, cropH, sig) 201 ld_puts("SIG k=\x00" as *u8); ld_num(k); ld_puts(" t_ms=\x00" as *u8); ld_num(t_ms) 202 var sq: i64 = 0 203 while sq < cells { ld_puts(" \x00" as *u8); ld_num(sig[sq]); sq = sq + 1 } 204 ld_puts("\n\x00" as *u8) 205 return 0 206 decoded = decoded + 1 207 if have == 1 { 208 var acc: i64 = 0 209 var c: i64 = 0 210 while c < cells { var d: i64 = sig[c] - prev[c]; if d < 0 { d = 0 - d } acc = acc + d; c = c + 1 } 211 let mad: i64 = acc / cells 212 ld_puts(" t_ms=\x00" as *u8); ld_num(t_ms) 213 ld_puts(" mad=\x00" as *u8); ld_num(mad) 214 if mad < 3 { ld_puts(" STATIC\x00" as *u8); lowruns = lowruns + 1 } 215 ld_puts("\n\x00" as *u8) 216 } 217 var c2: i64 = 0 218 while c2 < cells { prev[c2] = sig[c2]; c2 = c2 + 1 } 219 have = 1 220 } else { failed = failed + 1 } 221 } else { failed = failed + 1 } 222 k = k + step 223 } 224 sys_close(tsfd) 225 ld_puts("LUMADIFF decoded=\x00" as *u8); ld_num(decoded) 226 ld_puts(" failed=\x00" as *u8); ld_num(failed) 227 ld_puts(" static_samples=\x00" as *u8); ld_num(lowruns) 228 ld_puts("\n\x00" as *u8) 229 if decoded < 2 { return 6 } 230 return 0 231}