code wiki / _hdl_build / nx_vcodec_sigcoder_gate.nx

nx_vcodec_sigcoder_gate.nx source

↩ module page · 206 lines · 9796 B

1import "nx_gate_base.nx" 2// nx_vcodec_sigcoder_gate.nx -- R2a PROOF, honest 2x2: {run-length rc_block64 | significance-map rc_sig} 3// x {uniform-2048 priors | TRAINED priors}. The live codec seeds every context to 2048 PER FRAME (see 4// vc_enc_frame_packed_rc) and pays the adaptation ramp every frame; TRAINED priors (empirical bit counts on 5// TRAIN frames, applied to HELD-OUT frames) are the first genuinely LEARNED entropy component -- the same 6// move as VP8/VP9's offline-trained default probability tables and the learned CDF tables of neural codecs. 7// Per-frame streams mirror the live behavior exactly. GREEN = sig-map bit-exact roundtrip on held-out data, 8// trained priors never hurt, and the best config beats the live config (RL+uniform) by a reported permille. 9// license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_dct8.nx" 12import "nx_vcodec.nx" 13import "nx_rangecoder.nx" 14import "nx_rangecoder_sig.nx" 15 16const NW: i64 = 576 17const NH: i64 = 1024 18const BPF: i64 = 9216 // 8x8 luma blocks per frame = (576/8)*(1024/8) 19 20func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 21" as *u8); return ok } 22func gn(v: i64) -> i64 { 23 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 24 let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} 25 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 26 27// fill BPF quantized 8x8 coefficient blocks for the diff of frame f vs f-1 into dst 28func fill_frame(yuv: *u8, f: i64, qp: i64, M: *i64, scr: *i64, ti: *i64, to: *i64, dst: *i64) -> i64 { 29 let N: i64=NW*NH; let FB: i64=N+N/2 30 let cur: *u8 = ((yuv as i64) + f*FB) as *u8 31 let prv: *u8 = ((yuv as i64) + (f-1)*FB) as *u8 32 var nb: i64 = 0 33 var by: i64 = 0 34 while by < NH/8 { var bx: i64 = 0 35 while bx < NW/8 { 36 let blk: *i64 = ((dst as i64) + nb*64*8) as *i64 37 var yy: i64=0 38 while yy < 8 { var xx: i64=0 39 while xx < 8 { let p: i64=(by*8+yy)*NW+(bx*8+xx); blk[yy*8+xx]=(cur[p]&0xff)-(prv[p]&0xff); xx=xx+1 } yy=yy+1 } 40 nx_dct8_forward_2d(M, blk, blk, scr, ti, to) 41 vc_quant8(blk, qp) 42 nb = nb + 1 43 bx=bx+1 } by=by+1 } 44 return nb } 45 46// ---- TRAINING TALLIES: mirror each coder's bit decisions, counting (ctx, bit) into h[ctx*2+bit] ---- 47func tally_rl(blocks: *i64, nb: i64, zz8: *i64, h: *i64) -> i64 { 48 var b: i64=0 49 while b < nb { 50 let c: *i64 = ((blocks as i64)+b*64*8) as *i64 51 var run: i64=0; var k: i64=0 52 while k < 64 { 53 let val: i64 = c[zz8[k]] 54 if val == 0 { run = run + 1 } else { 55 h[11*2+1] = h[11*2+1] + 1 56 var bi: i64=5; while bi >= 0 { let bit: i64=(run>>bi)&1; h[(12+(5-bi))*2+bit]=h[(12+(5-bi))*2+bit]+1; bi=bi-1 } 57 let z: i64 = ve_zze(val); let nbl: i64 = ve_blen(z) 58 bi = 4; while bi >= 0 { let bit2: i64=(nbl>>bi)&1; h[(18+(4-bi))*2+bit2]=h[(18+(4-bi))*2+bit2]+1; bi=bi-1 } 59 var m: i64 = nbl - 1; while m >= 0 { let bit3: i64=(z>>m)&1; h[23*2+bit3]=h[23*2+bit3]+1; m=m-1 } 60 run = 0 61 } 62 k = k + 1 63 } 64 h[11*2] = h[11*2] + 1 // EOB 65 b=b+1 66 } 67 return 0 } 68func tally_sig(blocks: *i64, nb: i64, sigmap: *i64, h: *i64) -> i64 { 69 var b: i64=0 70 while b < nb { 71 let c: *i64 = ((blocks as i64)+b*64*8) as *i64 72 var anynz: i64=0; var i: i64=0 73 while i < 64 { if c[i] != 0 { anynz=1 } sigmap[i]=0; i=i+1 } 74 h[0*2+anynz] = h[0*2+anynz] + 1 75 if anynz == 1 { 76 var p: i64=0 77 while p < 64 { 78 let nbr: i64 = rcs_nb(sigmap, p, 8) 79 var s: i64=0; if c[p] != 0 { s=1 } 80 let cx: i64 = rcs_sigctx(p, 64, nbr) 81 h[cx*2+s] = h[cx*2+s] + 1 82 sigmap[p] = s 83 p=p+1 84 } 85 p=0 86 while p < 64 { if c[p] != 0 { 87 var mag: i64=c[p]; var sgn: i64=0; if mag<0 { mag=0-mag; sgn=1 } 88 let nbl: i64 = ve_blen(mag) 89 var bi: i64=4; while bi >= 0 { let bit: i64=(nbl>>bi)&1; h[(17+(4-bi))*2+bit]=h[(17+(4-bi))*2+bit]+1; bi=bi-1 } 90 var m: i64 = nbl-2; while m >= 0 { let bit2: i64=(mag>>m)&1; h[22*2+bit2]=h[22*2+bit2]+1; m=m-1 } 91 h[23*2+sgn] = h[23*2+sgn] + 1 92 } p=p+1 } 93 } 94 b=b+1 95 } 96 return 0 } 97// counts -> 12-bit P(bit==0), clamped so adaptation can still move 98func mk_priors(h: *i64, nctx: i64, pr: *i64) -> i64 { 99 var c: i64=0 100 while c < nctx { 101 let n0: i64=h[c*2]; let n1: i64=h[c*2+1]; let tot: i64=n0+n1 102 var p: i64 = 2048 103 if tot > 0 { p = (n0*4096)/tot } 104 if p < 64 { p = 64 } 105 if p > 4032 { p = 4032 } 106 pr[c] = p 107 c=c+1 108 } 109 return 0 } 110 111// encode one frame's blocks with the chosen coder + priors; returns bytes. mode 0=RL, 1=SIG. 112func enc_frame(blocks: *i64, nb: i64, mode: i64, priors: *i64, nctx: i64, zz8: *i64, sigmap: *i64, 113 est: *i64, probs: *i64, out: *u8) -> i64 { 114 rc_enc_init(est) 115 var ci: i64=0; while ci < nctx { probs[ci]=priors[ci]; ci=ci+1 } 116 var b: i64=0 117 while b < nb { 118 let c: *i64 = ((blocks as i64)+b*64*8) as *i64 119 if mode == 0 { rc_block64_encode(c, est, out, probs, zz8) } 120 else { rc_sig_encode(c, 64, 8, est, out, probs, sigmap) } 121 b=b+1 122 } 123 return rc_enc_flush(est, out) } 124 125func main() -> i64 { 126 gw("=== nx_vcodec_sigcoder_gate v2: {RL|SIG} x {uniform|TRAINED priors}, per-frame, held-out ===\n" as *u8) 127 let box: *i64 = sys_mmap(16) as *i64 128 let yuv: *u8 = sys_read_file("/mnt/c/Users/elder/nishi-core/nxc2/knowledge/staging/media/bframe_test_decoded.yuv" as *u8, box) 129 if (yuv as i64) == 0 { gw("cannot read yuv -> RED\n" as *u8); return 1 } 130 if box[0] < 12*(NW*NH+NW*NH/2) { gw("file too small -> RED\n" as *u8); return 1 } 131 let M: *i64 = sys_mmap(64*8) as *i64; nx_dct8_init(M) 132 let scr: *i64 = sys_mmap(64*8) as *i64; let ti: *i64 = sys_mmap(8*8) as *i64; let to: *i64 = sys_mmap(8*8) as *i64 133 let t8c: *i64 = sys_mmap(5120) as *i64; vc_t8_init(t8c) 134 let zz8: *i64 = vc_t8p(t8c, VC_T8_ZZ) 135 let sigmap: *i64 = sys_mmap(64*8) as *i64 136 let fblocks: *i64 = sys_mmap(BPF*64*8) as *i64 137 let qp: i64 = 28 138 139 // ---- TRAIN on frames 8,9 (diffs 8-7, 9-8) ---- 140 let hRL: *i64 = sys_mmap(32*2*8) as *i64 141 let hSG: *i64 = sys_mmap(32*2*8) as *i64 142 var z: i64=0; while z<64 { hRL[z]=0; hSG[z]=0; z=z+1 } 143 var f: i64=8 144 while f < 10 { 145 let nb: i64 = fill_frame(yuv, f, qp, M, scr, ti, to, fblocks) 146 tally_rl(fblocks, nb, zz8, hRL) 147 tally_sig(fblocks, nb, sigmap, hSG) 148 f=f+1 149 } 150 let prRL: *i64 = sys_mmap(32*8) as *i64 151 let prSG: *i64 = sys_mmap(32*8) as *i64 152 mk_priors(hRL, RC_NCTX8, prRL) 153 mk_priors(hSG, RC_SIG_NCTX, prSG) 154 let un: *i64 = sys_mmap(32*8) as *i64 155 z=0; while z<32 { un[z]=2048; z=z+1 } 156 157 // ---- EVAL on HELD-OUT frames 10,11 (per-frame streams, like the live codec) ---- 158 let est: *i64 = sys_mmap(64) as *i64 159 let probs: *i64 = sys_mmap(32*8) as *i64 160 let out: *u8 = sys_mmap(8388608) 161 var bRLu: i64=0; var bRLt: i64=0; var bSGu: i64=0; var bSGt: i64=0 162 var mism: i64=0 163 let dblk: *i64 = sys_mmap(64*8) as *i64 164 let dprobs: *i64 = sys_mmap(32*8) as *i64 165 let dst: *i64 = sys_mmap(64) as *i64 166 f=10 167 while f < 12 { 168 let nb: i64 = fill_frame(yuv, f, qp, M, scr, ti, to, fblocks) 169 bRLu = bRLu + enc_frame(fblocks, nb, 0, un, RC_NCTX8, zz8, sigmap, est, probs, out) 170 bRLt = bRLt + enc_frame(fblocks, nb, 0, prRL, RC_NCTX8, zz8, sigmap, est, probs, out) 171 bSGu = bSGu + enc_frame(fblocks, nb, 1, un, RC_SIG_NCTX, zz8, sigmap, est, probs, out) 172 // SIG+trained: keep the stream in `out` and VERIFY the bit-exact roundtrip block-by-block 173 let nB: i64 = enc_frame(fblocks, nb, 1, prSG, RC_SIG_NCTX, zz8, sigmap, est, probs, out) 174 bSGt = bSGt + nB 175 rc_dec_init(dst, out) 176 var ci: i64=0; while ci < RC_SIG_NCTX { dprobs[ci]=prSG[ci]; ci=ci+1 } 177 var b: i64=0 178 while b < nb { 179 rc_sig_decode(dblk, 64, 8, dst, out, dprobs, sigmap) 180 let src: *i64 = ((fblocks as i64)+b*64*8) as *i64 181 var i: i64=0; while i < 64 { if dblk[i] != src[i] { mism=mism+1; i=64 } i=i+1 } 182 b=b+1 183 } 184 f=f+1 185 } 186 187 gw(" held-out bytes: RL+uniform(LIVE)=" as *u8); gn(bRLu) 188 gw(" RL+trained=" as *u8); gn(bRLt) 189 gw(" SIG+uniform=" as *u8); gn(bSGu) 190 gw(" SIG+trained=" as *u8); gn(bSGt) 191 gw(" mism=" as *u8); gn(mism); gw("\n" as *u8) 192 let svSGt: i64 = (bRLu - bSGt)*1000/bRLu 193 let svTR: i64 = (bRLu - bRLt)*1000/bRLu 194 let svSG: i64 = (bRLu - bSGu)*1000/bRLu 195 gw(" vs LIVE: sig-map alone " as *u8); gn(svSG) 196 gw("permille · trained-priors alone " as *u8); gn(svTR) 197 gw("permille · BOTH " as *u8); gn(svSGt); gw("permille\n" as *u8) 198 199 var pass: i64=0; var tot: i64=0 200 tot=tot+1; if mism == 0 { pass=pass+1 } // held-out bit-exact roundtrip 201 tot=tot+1; if bRLt <= bRLu { pass=pass+1 } // trained priors never hurt (RL) 202 tot=tot+1; if bSGt <= bSGu { pass=pass+1 } // trained priors never hurt (SIG) 203 tot=tot+1; if bSGt < bRLu { pass=pass+1 } // best config beats LIVE 204 gw("SIGCODER2: " as *u8); gn(pass); gw("/" as *u8); gn(tot) 205 if pass==tot { gw(" GREEN -- learned priors + neighbor-context sig-map beat the live coder on held-out frames\n" as *u8); return 0 } 206 gw(" RED\n" as *u8); return 1 }