code wiki / _hdl_build / nx_vcodec_ffv1_entropy_gate.nx
nx_vcodec_ffv1_entropy_gate.nx source
↩ module page · 344 lines · 20590 B
1// nx_vcodec_ffv1_entropy_gate.nx -- MEASURE an FFV1/RFC-9043-style integer entropy-coding improvement on REAL
2// quantized residuals, BEFORE any wire change. The shipped range coder (nx_rangecoder) adapts each per-context
3// 12-bit probability with a FIXED shift-5 multiplicative step (rc_p_update). FFV1's edge is a NON-UNIFORM,
4// extreme-reaching adaptation rate (fast while uncertain, tiny steps once confidently skewed) -> lower steady-
5// state variance + probabilities that reach the true extremes. rc_p_update_adv (nx_rangecoder.nx) is that idea
6// in pure integers, parameterised by cfg=[s_start,s_floor,minstep,lo,hi]. This gate builds real 8x8 DCT+quant
7// residual blocks (frame diffs of bframe_test_decoded.yuv, the exact source the other entropy gates use) and
8// A/Bs the shipped shift-5 coder vs the _adv sweep on BOTH the LIVE run-length path (rc_block64) AND the sig-map
9// path (rc_sig), reporting bytes + permille saved, the per-frame Shannon headroom (the ceiling any adaptation
10// can reach), and a BIT-EXACT roundtrip verdict (mism count). MEASURE-FIRST: honest number, negative allowed.
11// license_tier: ORIGINAL
12import "nx_syscalls.nx"
13import "nx_dct8.nx"
14import "nx_vcodec.nx"
15import "nx_rangecoder.nx"
16import "nx_rangecoder_sig.nx"
17import "nx_quality_metric.nx"
18
19const NW: i64 = 576
20const NH: i64 = 1024
21const BPF: i64 = 9216 // 8x8 luma blocks per frame = (576/8)*(1024/8)
22
23func gw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
24func gn(v: i64) -> i64 {
25 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m}
26 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}
27 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 }
28
29// fill BPF quantized 8x8 coefficient blocks for the diff of frame f vs f-1 into dst (copied from sigcoder_gate)
30func fill_frame(yuv: *u8, f: i64, qp: i64, M: *i64, scr: *i64, ti: *i64, to: *i64, dst: *i64) -> i64 {
31 let N: i64=NW*NH; let FB: i64=N+N/2
32 let cur: *u8 = ((yuv as i64) + f*FB) as *u8
33 let prv: *u8 = ((yuv as i64) + (f-1)*FB) as *u8
34 var nb: i64 = 0
35 var by: i64 = 0
36 while by < NH/8 { var bx: i64 = 0
37 while bx < NW/8 {
38 let blk: *i64 = ((dst as i64) + nb*64*8) as *i64
39 var yy: i64=0
40 while yy < 8 { var xx: i64=0
41 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 }
42 nx_dct8_forward_2d(M, blk, blk, scr, ti, to)
43 vc_quant8(blk, qp)
44 nb = nb + 1
45 bx=bx+1 } by=by+1 }
46 return nb }
47
48// ---- ideal (per-frame Shannon) entropy of the coder's OWN bins -- the ceiling any adaptation can reach ----
49// conditional entropy in BITS over C binary contexts; h[c*2+s]=count of symbol s in ctx c. qm_log2_q16 = Q16 log2.
50func cond_bits(h: *i64, C: i64) -> i64 {
51 var bitsq: i64 = 0
52 var c: i64 = 0
53 while c < C {
54 let n0: i64 = h[c*2]; let n1: i64 = h[c*2+1]; let tot: i64 = n0 + n1
55 if tot > 0 {
56 let lt: i64 = qm_log2_q16(tot)
57 if n0 > 0 { bitsq = bitsq + n0 * (lt - qm_log2_q16(n0)) }
58 if n1 > 0 { bitsq = bitsq + n1 * (lt - qm_log2_q16(n1)) }
59 }
60 c = c + 1
61 }
62 return bitsq >> 16 }
63// tally the run-length coder's bins (contexts 11..23) for one frame's blocks (copied from sigcoder_gate)
64func tally_rl(blocks: *i64, nb: i64, zz8: *i64, h: *i64) -> i64 {
65 var b: i64=0
66 while b < nb {
67 let c: *i64 = ((blocks as i64)+b*64*8) as *i64
68 var run: i64=0; var k: i64=0
69 while k < 64 {
70 let val: i64 = c[zz8[k]]
71 if val == 0 { run = run + 1 } else {
72 h[11*2+1] = h[11*2+1] + 1
73 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 }
74 let z: i64 = ve_zze(val); let nbl: i64 = ve_blen(z)
75 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 }
76 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 }
77 run = 0
78 }
79 k = k + 1
80 }
81 h[11*2] = h[11*2] + 1
82 b=b+1
83 }
84 return 0 }
85// tally the sig-map coder's bins (contexts 0..23) for one frame's blocks (copied from sigcoder_gate)
86func tally_sig(blocks: *i64, nb: i64, sigmap: *i64, h: *i64) -> i64 {
87 var b: i64=0
88 while b < nb {
89 let c: *i64 = ((blocks as i64)+b*64*8) as *i64
90 var anynz: i64=0; var i: i64=0
91 while i < 64 { if c[i] != 0 { anynz=1 } sigmap[i]=0; i=i+1 }
92 h[0*2+anynz] = h[0*2+anynz] + 1
93 if anynz == 1 {
94 var p: i64=0
95 while p < 64 {
96 let nbr: i64 = rcs_nb(sigmap, p, 8)
97 var s: i64=0; if c[p] != 0 { s=1 }
98 let cx: i64 = rcs_sigctx(p, 64, nbr)
99 h[cx*2+s] = h[cx*2+s] + 1
100 sigmap[p] = s
101 p=p+1
102 }
103 p=0
104 while p < 64 { if c[p] != 0 {
105 var mag: i64=c[p]; var sgn: i64=0; if mag<0 { mag=0-mag; sgn=1 }
106 let nbl: i64 = ve_blen(mag)
107 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 }
108 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 }
109 h[23*2+sgn] = h[23*2+sgn] + 1
110 } p=p+1 }
111 }
112 b=b+1
113 }
114 return 0 }
115
116// ---- per-frame stream encoders (reset probs->2048 per frame, mirroring the LIVE codec) ----
117func rlbytes_base(blocks: *i64, nb: i64, zz8: *i64, est: *i64, probs: *i64, out: *u8) -> i64 {
118 rc_enc_init(est)
119 var ci: i64=0; while ci < RC_NCTX8 { probs[ci]=2048; ci=ci+1 }
120 var b: i64=0
121 while b < nb { let c: *i64 = ((blocks as i64)+b*64*8) as *i64; rc_block64_encode(c, est, out, probs, zz8); b=b+1 }
122 return rc_enc_flush(est, out) }
123func rlbytes_adv(blocks: *i64, nb: i64, cfg: *i64, zz8: *i64, est: *i64, probs: *i64, cnt: *i64, out: *u8) -> i64 {
124 rc_enc_init(est)
125 var ci: i64=0; while ci < RC_NCTX8 { probs[ci]=2048; cnt[ci]=0; ci=ci+1 }
126 var b: i64=0
127 while b < nb { let c: *i64 = ((blocks as i64)+b*64*8) as *i64; rc_block64_encode_adv(c, est, out, probs, cnt, zz8, cfg); b=b+1 }
128 return rc_enc_flush(est, out) }
129func sigbytes_base(blocks: *i64, nb: i64, est: *i64, probs: *i64, sigmap: *i64, out: *u8) -> i64 {
130 rc_enc_init(est)
131 var ci: i64=0; while ci < RC_SIG_NCTX { probs[ci]=2048; ci=ci+1 }
132 var b: i64=0
133 while b < nb { let c: *i64 = ((blocks as i64)+b*64*8) as *i64; rc_sig_encode(c, 64, 8, est, out, probs, sigmap); b=b+1 }
134 return rc_enc_flush(est, out) }
135func sigbytes_adv(blocks: *i64, nb: i64, cfg: *i64, est: *i64, probs: *i64, cnt: *i64, sigmap: *i64, out: *u8) -> i64 {
136 rc_enc_init(est)
137 var ci: i64=0; while ci < RC_SIG_NCTX { probs[ci]=2048; cnt[ci]=0; ci=ci+1 }
138 var b: i64=0
139 while b < nb { let c: *i64 = ((blocks as i64)+b*64*8) as *i64; rc_sig_encode_adv(c, 64, 8, est, out, probs, cnt, sigmap, cfg); b=b+1 }
140 return rc_enc_flush(est, out) }
141
142// ---- roundtrip verifiers: encode the whole frame with the _adv coder, decode, count coeff mismatches ----
143func rlverify_adv(blocks: *i64, nb: i64, cfg: *i64, zz8: *i64, est: *i64, probs: *i64, cnt: *i64, out: *u8,
144 dst: *i64, dprobs: *i64, dcnt: *i64, dblk: *i64) -> i64 {
145 rc_enc_init(est)
146 var ci: i64=0; while ci < RC_NCTX8 { probs[ci]=2048; cnt[ci]=0; ci=ci+1 }
147 var b: i64=0
148 while b < nb { let c: *i64 = ((blocks as i64)+b*64*8) as *i64; rc_block64_encode_adv(c, est, out, probs, cnt, zz8, cfg); b=b+1 }
149 rc_enc_flush(est, out)
150 rc_dec_init(dst, out)
151 ci=0; while ci < RC_NCTX8 { dprobs[ci]=2048; dcnt[ci]=0; ci=ci+1 }
152 var mism: i64=0
153 b=0
154 while b < nb {
155 rc_block64_decode_adv(dblk, dst, out, dprobs, dcnt, zz8, cfg)
156 let src: *i64 = ((blocks as i64)+b*64*8) as *i64
157 var i: i64=0; while i < 64 { if dblk[i] != src[i] { mism=mism+1; i=64 } i=i+1 }
158 b=b+1
159 }
160 return mism }
161func sigverify_adv(blocks: *i64, nb: i64, cfg: *i64, est: *i64, probs: *i64, cnt: *i64, sigmap: *i64, out: *u8,
162 dst: *i64, dprobs: *i64, dcnt: *i64, dblk: *i64) -> i64 {
163 rc_enc_init(est)
164 var ci: i64=0; while ci < RC_SIG_NCTX { probs[ci]=2048; cnt[ci]=0; ci=ci+1 }
165 var b: i64=0
166 while b < nb { let c: *i64 = ((blocks as i64)+b*64*8) as *i64; rc_sig_encode_adv(c, 64, 8, est, out, probs, cnt, sigmap, cfg); b=b+1 }
167 rc_enc_flush(est, out)
168 rc_dec_init(dst, out)
169 ci=0; while ci < RC_SIG_NCTX { dprobs[ci]=2048; dcnt[ci]=0; ci=ci+1 }
170 var mism: i64=0
171 b=0
172 while b < nb {
173 rc_sig_decode_adv(dblk, 64, 8, dst, out, dprobs, dcnt, sigmap, cfg)
174 let src: *i64 = ((blocks as i64)+b*64*8) as *i64
175 var i: i64=0; while i < 64 { if dblk[i] != src[i] { mism=mism+1; i=64 } i=i+1 }
176 b=b+1
177 }
178 return mism }
179
180func setcfg(c: *i64, a: i64, b: i64, d: i64, e: i64, f: i64) -> i64 { c[0]=a; c[1]=b; c[2]=d; c[3]=e; c[4]=f; return 0 }
181func row(lbl: *u8, bytes: i64, base: i64) -> i64 {
182 gw(lbl); gw("=" as *u8); gn(bytes); gw("B (" as *u8); gn((base-bytes)*1000/base); gw(" permille vs base)\n" as *u8); return 0 }
183
184func main() -> i64 {
185 gw("=== nx_vcodec_ffv1_entropy_gate: FFV1-style adaptation vs shipped shift-5, REAL residuals, per-frame ===\n" as *u8)
186 let box: *i64 = sys_mmap(16) as *i64
187 let yuv: *u8 = sys_read_file("/mnt/c/Users/elder/nishi-core/nxc2/knowledge/staging/media/bframe_test_decoded.yuv" as *u8, box)
188 if (yuv as i64) == 0 { gw("cannot read yuv -> RED\n" as *u8); return 1 }
189 if box[0] < 12*(NW*NH+NW*NH/2) { gw("file too small -> RED\n" as *u8); return 1 }
190 let M: *i64 = sys_mmap(64*8) as *i64; nx_dct8_init(M)
191 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
192 let t8c: *i64 = sys_mmap(5120) as *i64; vc_t8_init(t8c)
193 let zz8: *i64 = vc_t8p(t8c, VC_T8_ZZ)
194 let sigmap: *i64 = sys_mmap(64*8) as *i64
195 let fblocks: *i64 = sys_mmap(BPF*64*8) as *i64
196 let est: *i64 = sys_mmap(64) as *i64
197 let probs: *i64 = sys_mmap(32*8) as *i64
198 let cnt: *i64 = sys_mmap(32*8) as *i64
199 let out: *u8 = sys_mmap(8388608)
200 let dst: *i64 = sys_mmap(64) as *i64
201 let dprobs: *i64 = sys_mmap(32*8) as *i64
202 let dcnt: *i64 = sys_mmap(32*8) as *i64
203 let dblk: *i64 = sys_mmap(64*8) as *i64
204 let hRL: *i64 = sys_mmap(32*2*8) as *i64
205 let hSG: *i64 = sys_mmap(32*2*8) as *i64
206
207 // configs: cfg=[s_start,s_floor,minstep,lo,hi]. ID reproduces shipped shift-5 exactly.
208 let cID: *i64 = sys_mmap(5*8) as *i64; setcfg(cID, 5,5,0,1,4095) // == shipped rc_p_update (control)
209 let cS4: *i64 = sys_mmap(5*8) as *i64; setcfg(cS4, 4,4,0,1,4095) // faster fixed rate
210 let cS6: *i64 = sys_mmap(5*8) as *i64; setcfg(cS6, 6,6,0,1,4095) // slower fixed rate (less variance)
211 let cS7: *i64 = sys_mmap(5*8) as *i64; setcfg(cS7, 7,7,0,1,4095) // slower still
212 let cX6: *i64 = sys_mmap(5*8) as *i64; setcfg(cX6, 6,6,1,4,4092) // FFV1x: rate 1/64 + crawl to extremes
213 let cX7: *i64 = sys_mmap(5*8) as *i64; setcfg(cX7, 7,7,1,4,4092) // FFV1x: rate 1/128 + crawl to extremes
214 let cR37: *i64 = sys_mmap(5*8) as *i64; setcfg(cR37, 3,7,1,4,4092) // FFV1x + fast->slow count ramp (3..7)
215 let cE5: *i64 = sys_mmap(5*8) as *i64; setcfg(cE5, 5,5,1,4,4092) // KEEP shift-5 rate, ONLY add extreme reach
216 let cE4: *i64 = sys_mmap(5*8) as *i64; setcfg(cE4, 4,4,1,4,4092) // shift-4 rate + extreme reach
217 let cB2: *i64 = sys_mmap(5*8) as *i64; setcfg(cB2, 5,5,1,2,4094) // extreme-bound sweep (widest)
218 let cB8: *i64 = sys_mmap(5*8) as *i64; setcfg(cB8, 5,5,1,8,4088)
219 let cB16: *i64 = sys_mmap(5*8) as *i64; setcfg(cB16, 5,5,1,16,4080) // extreme-bound sweep (tightest)
220
221 gw(" source: bframe_test_decoded.yuv 576x1024, 10 real inter-frame residual fields (diffs 2..11), qp=28\n" as *u8)
222 gw(" configs: base=shipped shift-5 | S4/S6/S7=fixed shift | X6/X7=slow+extreme-reach | R37=ramp3->7+extreme\n" as *u8)
223
224 let qp: i64 = 28
225 var bRLb: i64=0; var bRLid: i64=0; var bRL4: i64=0; var bRL6: i64=0; var bRL7: i64=0; var bRLx6: i64=0; var bRLx7: i64=0; var bRLr: i64=0
226 var bRLe5: i64=0; var bRLe4: i64=0
227 var bSGb: i64=0; var bSGid: i64=0; var bSG4: i64=0; var bSG6: i64=0; var bSG7: i64=0; var bSGx6: i64=0; var bSGx7: i64=0; var bSGr: i64=0
228 var bSGe5: i64=0; var bSGe4: i64=0; var bSGb2: i64=0; var bSGb8: i64=0; var bSGb16: i64=0
229 var mRLid: i64=0; var mRLx7: i64=0; var mRLr: i64=0; var mSGid: i64=0; var mSGx7: i64=0; var mSGr: i64=0
230 var mRLe5: i64=0; var mSGe5: i64=0
231 var bidRL: i64=0; var bidSG: i64=0
232 var f: i64=2
233 while f < 12 {
234 let nb: i64 = fill_frame(yuv, f, qp, M, scr, ti, to, fblocks)
235 bRLb = bRLb + rlbytes_base(fblocks, nb, zz8, est, probs, out)
236 bRLid = bRLid + rlbytes_adv(fblocks, nb, cID, zz8, est, probs, cnt, out)
237 bRL4 = bRL4 + rlbytes_adv(fblocks, nb, cS4, zz8, est, probs, cnt, out)
238 bRL6 = bRL6 + rlbytes_adv(fblocks, nb, cS6, zz8, est, probs, cnt, out)
239 bRL7 = bRL7 + rlbytes_adv(fblocks, nb, cS7, zz8, est, probs, cnt, out)
240 bRLx6 = bRLx6 + rlbytes_adv(fblocks, nb, cX6, zz8, est, probs, cnt, out)
241 bRLx7 = bRLx7 + rlbytes_adv(fblocks, nb, cX7, zz8, est, probs, cnt, out)
242 bRLr = bRLr + rlbytes_adv(fblocks, nb, cR37, zz8, est, probs, cnt, out)
243 bRLe5 = bRLe5 + rlbytes_adv(fblocks, nb, cE5, zz8, est, probs, cnt, out)
244 bRLe4 = bRLe4 + rlbytes_adv(fblocks, nb, cE4, zz8, est, probs, cnt, out)
245 bSGb = bSGb + sigbytes_base(fblocks, nb, est, probs, sigmap, out)
246 bSGid = bSGid + sigbytes_adv(fblocks, nb, cID, est, probs, cnt, sigmap, out)
247 bSG4 = bSG4 + sigbytes_adv(fblocks, nb, cS4, est, probs, cnt, sigmap, out)
248 bSG6 = bSG6 + sigbytes_adv(fblocks, nb, cS6, est, probs, cnt, sigmap, out)
249 bSG7 = bSG7 + sigbytes_adv(fblocks, nb, cS7, est, probs, cnt, sigmap, out)
250 bSGx6 = bSGx6 + sigbytes_adv(fblocks, nb, cX6, est, probs, cnt, sigmap, out)
251 bSGx7 = bSGx7 + sigbytes_adv(fblocks, nb, cX7, est, probs, cnt, sigmap, out)
252 bSGr = bSGr + sigbytes_adv(fblocks, nb, cR37, est, probs, cnt, sigmap, out)
253 bSGe5 = bSGe5 + sigbytes_adv(fblocks, nb, cE5, est, probs, cnt, sigmap, out)
254 bSGe4 = bSGe4 + sigbytes_adv(fblocks, nb, cE4, est, probs, cnt, sigmap, out)
255 bSGb2 = bSGb2 + sigbytes_adv(fblocks, nb, cB2, est, probs, cnt, sigmap, out)
256 bSGb8 = bSGb8 + sigbytes_adv(fblocks, nb, cB8, est, probs, cnt, sigmap, out)
257 bSGb16 = bSGb16 + sigbytes_adv(fblocks, nb, cB16, est, probs, cnt, sigmap, out)
258 mRLe5 = mRLe5 + rlverify_adv(fblocks, nb, cE5, zz8, est, probs, cnt, out, dst, dprobs, dcnt, dblk)
259 mSGe5 = mSGe5 + sigverify_adv(fblocks, nb, cE5, est, probs, cnt, sigmap, out, dst, dprobs, dcnt, dblk)
260 mRLid = mRLid + rlverify_adv(fblocks, nb, cID, zz8, est, probs, cnt, out, dst, dprobs, dcnt, dblk)
261 mRLx7 = mRLx7 + rlverify_adv(fblocks, nb, cX7, zz8, est, probs, cnt, out, dst, dprobs, dcnt, dblk)
262 mRLr = mRLr + rlverify_adv(fblocks, nb, cR37, zz8, est, probs, cnt, out, dst, dprobs, dcnt, dblk)
263 mSGid = mSGid + sigverify_adv(fblocks, nb, cID, est, probs, cnt, sigmap, out, dst, dprobs, dcnt, dblk)
264 mSGx7 = mSGx7 + sigverify_adv(fblocks, nb, cX7, est, probs, cnt, sigmap, out, dst, dprobs, dcnt, dblk)
265 mSGr = mSGr + sigverify_adv(fblocks, nb, cR37, est, probs, cnt, sigmap, out, dst, dprobs, dcnt, dblk)
266 var z: i64=0; while z<48 { hRL[z]=0; hSG[z]=0; z=z+1 }
267 tally_rl(fblocks, nb, zz8, hRL)
268 tally_sig(fblocks, nb, sigmap, hSG)
269 bidRL = bidRL + cond_bits(hRL, 24)
270 bidSG = bidSG + cond_bits(hSG, 24)
271 f=f+1
272 }
273 let bidRLB: i64 = bidRL/8
274 let bidSGB: i64 = bidSG/8
275
276 gw("\n-- LIVE run-length path (rc_block64) --\n" as *u8)
277 row(" base(shift5) " as *u8, bRLb, bRLb)
278 row(" _adv[5,5,0]=ID " as *u8, bRLid, bRLb)
279 row(" S4 (shift4) " as *u8, bRL4, bRLb)
280 row(" S6 (shift6) " as *u8, bRL6, bRLb)
281 row(" S7 (shift7) " as *u8, bRL7, bRLb)
282 row(" X6 (slow+xtrm) " as *u8, bRLx6, bRLb)
283 row(" X7 (slow+xtrm) " as *u8, bRLx7, bRLb)
284 row(" R37(ramp+xtrm) " as *u8, bRLr, bRLb)
285 row(" E5 (sh5+xtrm) " as *u8, bRLe5, bRLb)
286 row(" E4 (sh4+xtrm) " as *u8, bRLe4, bRLb)
287 gw(" Shannon per-frame ideal=" as *u8); gn(bidRLB); gw("B (headroom " as *u8); gn((bRLb-bidRLB)*1000/bRLb); gw(" permille below base)\n" as *u8)
288
289 gw("\n-- sig-map path (rc_sig, neighbor-context) --\n" as *u8)
290 row(" base(shift5) " as *u8, bSGb, bSGb)
291 row(" _adv[5,5,0]=ID " as *u8, bSGid, bSGb)
292 row(" S4 (shift4) " as *u8, bSG4, bSGb)
293 row(" S6 (shift6) " as *u8, bSG6, bSGb)
294 row(" S7 (shift7) " as *u8, bSG7, bSGb)
295 row(" X6 (slow+xtrm) " as *u8, bSGx6, bSGb)
296 row(" X7 (slow+xtrm) " as *u8, bSGx7, bSGb)
297 row(" R37(ramp+xtrm) " as *u8, bSGr, bSGb)
298 row(" E5 (sh5+xtrm) " as *u8, bSGe5, bSGb)
299 row(" E4 (sh4+xtrm) " as *u8, bSGe4, bSGb)
300 gw(" extreme-bound sweep @shift5+min1 (proves the win isn't a knife-edge):\n" as *u8)
301 row(" B2 [4,4094] " as *u8, bSGb2, bSGb)
302 row(" B8 [8,4088] " as *u8, bSGb8, bSGb)
303 row(" B16[16,4080] " as *u8, bSGb16, bSGb)
304 gw(" Shannon per-frame ideal=" as *u8); gn(bidSGB); gw("B (headroom " as *u8); gn((bSGb-bidSGB)*1000/bSGb); gw(" permille below base)\n" as *u8)
305
306 gw("\n roundtrip mism (must be 0): RL[ID=" as *u8); gn(mRLid); gw(" X7=" as *u8); gn(mRLx7); gw(" R37=" as *u8); gn(mRLr)
307 gw("] SIG[ID=" as *u8); gn(mSGid); gw(" X7=" as *u8); gn(mSGx7); gw(" R37=" as *u8); gn(mSGr); gw("]\n" as *u8)
308 gw(" roundtrip mism E5 (shift5+extreme, the ship candidate): RL=" as *u8); gn(mRLe5); gw(" SIG=" as *u8); gn(mSGe5); gw("\n" as *u8)
309
310 // ---- robustness at other rate points: base vs best two, verify R37 ----
311 gw("\n-- robustness across qp (base vs E5=shift5+extreme, the ship candidate, RL & SIG) --\n" as *u8)
312 let qps: *i64 = sys_mmap(32) as *i64; qps[0]=22; qps[1]=34
313 var mAll: i64 = mRLid + mRLx7 + mRLr + mSGid + mSGx7 + mSGr + mRLe5 + mSGe5
314 var qi: i64=0
315 while qi < 2 {
316 let q: i64 = qps[qi]
317 var rb: i64=0; var re: i64=0; var sb: i64=0; var se: i64=0; var mq: i64=0
318 var ff: i64=2
319 while ff < 12 {
320 let nb: i64 = fill_frame(yuv, ff, q, M, scr, ti, to, fblocks)
321 rb = rb + rlbytes_base(fblocks, nb, zz8, est, probs, out)
322 re = re + rlbytes_adv(fblocks, nb, cE5, zz8, est, probs, cnt, out)
323 sb = sb + sigbytes_base(fblocks, nb, est, probs, sigmap, out)
324 se = se + sigbytes_adv(fblocks, nb, cE5, est, probs, cnt, sigmap, out)
325 mq = mq + rlverify_adv(fblocks, nb, cE5, zz8, est, probs, cnt, out, dst, dprobs, dcnt, dblk)
326 mq = mq + sigverify_adv(fblocks, nb, cE5, est, probs, cnt, sigmap, out, dst, dprobs, dcnt, dblk)
327 ff=ff+1
328 }
329 mAll = mAll + mq
330 gw(" qp=" as *u8); gn(q)
331 gw(" RL base=" as *u8); gn(rb); gw(" E5=" as *u8); gn(re); gw("(" as *u8); gn((rb-re)*1000/rb); gw("permille)" as *u8)
332 gw(" SIG base=" as *u8); gn(sb); gw(" E5=" as *u8); gn(se); gw("(" as *u8); gn((sb-se)*1000/sb); gw("permille) mism=" as *u8); gn(mq); gw("\n" as *u8)
333 qi=qi+1
334 }
335
336 // ---- verdict: machinery must be sound (ID == base bit-for-bit, all roundtrips exact). The bit-savings sign
337 // is REPORTED, not gated -- a measured 0 or negative is a valid, honest outcome for this task. ----
338 var pass: i64=0; var tot: i64=0
339 tot=tot+1; if mAll == 0 { pass=pass+1 } // every _adv roundtrip bit-exact
340 tot=tot+1; if bRLid == bRLb { pass=pass+1 } // _adv[5,5,0] reproduces shipped RL byte-for-byte
341 tot=tot+1; if bSGid == bSGb { pass=pass+1 } // _adv[5,5,0] reproduces shipped SIG byte-for-byte
342 gw("\nFFV1-ENTROPY: " as *u8); gn(pass); gw("/" as *u8); gn(tot)
343 if pass==tot { gw(" GREEN -- measurement sound (adv is a faithful superset; all roundtrips bit-exact). See permille above for the MEASURED delta.\n" as *u8); return 0 }
344 gw(" RED -- measurement machinery unsound; numbers not trustworthy\n" as *u8); return 1 }