code wiki / _hdl_build / nx_codec_real_rd3.nx
nx_codec_real_rd3.nx source
↩ module page · 204 lines · 11900 B
1// nx_codec_real_rd3.nx -- the INTRA-PREDICTED patent-free intra codec on a REAL frame (576x1024 luma).
2// The efficiency rung above nx_codec_real_rd2 (modeled entropy): adds sovereign 8x8 directional INTRA
3// PREDICTION (DC/V/H/DDR, generalizing nx_intra_pred's 4x4 modes), so each block is predicted from its
4// already-RECONSTRUCTED neighbors and only the small residual is transform-coded. Pipeline per 8x8 block:
5// pick mode by SAD vs reconstructed-neighbor prediction -> residual = orig - pred -> 2D DCT (nx_dct8,
6// EXPIRED) -> perceptual quant (nx_qt_luma) -> zigzag -> [recon: dequant -> IDCT -> +pred -> clamp ->
7// feed forward]. Entropy: per-block mode byte + DC-diff/run-size symbols (nx_jsym) -> rANS (nx_rans,
8// PD); magnitude bits raw. HONEST total = 512B table + 64B quant + 8B hdr + rANS(symbols incl modes) +
9// magbits. The decoder REPLAYS prediction from its own reconstructed neighbors; rec(enc)==rec(dec)
10// pixel-exact is the liar-kill. Bordered recon buffer (1px 128 border) makes all 4 modes always
11// available with no edge special-casing. Every tool EXPIRED/PD; no CABAC; integer-only; no gcc. license_tier: ORIGINAL
12import "nx_syscalls.nx"
13import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
14import "nx_h264_bitwriter.nx"
15import "nx_dct8.nx"
16import "nx_quant_table.nx"
17import "nx_zigzag.nx"
18import "nx_jpeg_huff_enc.nx"
19import "nx_jpeg_sym.nx"
20import "nx_rans.nx"
21const K_MAGIC_1024: i64 = 1024
22const K_MAGIC_4096: i64 = 4096
23
24func g_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
25// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
26// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
27// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
28// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
29func g_num(v: i64) -> i64 { nxi_out(v); return 0 }
30func g_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
31// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
32// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
33// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
34// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
35func g_wn(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 }
36func iabs(v: i64) -> i64 { if v<0 { return 0-v } return v }
37func qrnd(v: i64, q: i64) -> i64 { if v>=0 { return (v + q/2)/q } return 0 - (((0-v) + q/2)/q) }
38
39// 8x8 intra prediction from a bordered recon buffer (stride RW; pixel (x,y) at rec[(y+1)*RW+(x+1)];
40// row 0 / col 0 are the 128 border). px,py = block top-left in image coords. mode: 0=DC 1=V 2=H 3=DDR.
41func pred8(rec: *u8, RW: i64, px: i64, py: i64, mode: i64, pred: *i64) -> i64 {
42 if mode==0 {
43 var s: i64=0; var i: i64=0
44 while i<8 { s=s+(rec[py*RW+px+i+1] as i64)+(rec[(py+i+1)*RW+px] as i64); i=i+1 }
45 let dc: i64=(s+8)/16
46 var k: i64=0; while k<64 { pred[k]=dc; k=k+1 }
47 return 0
48 }
49 if mode==1 {
50 var y: i64=0; while y<8 { var x: i64=0; while x<8 { pred[y*8+x]=rec[py*RW+px+x+1] as i64; x=x+1 } y=y+1 }
51 return 0
52 }
53 if mode==2 {
54 var y: i64=0; while y<8 { var x: i64=0; while x<8 { pred[y*8+x]=rec[(py+y+1)*RW+px] as i64; x=x+1 } y=y+1 }
55 return 0
56 }
57 let corner: i64=rec[py*RW+px] as i64
58 var y: i64=0
59 while y<8 {
60 var x: i64=0
61 while x<8 {
62 var p: i64=corner
63 if x>y { p=rec[py*RW+px+(x-y-1)+1] as i64 }
64 if x<y { p=rec[(py+(y-x-1)+1)*RW+px] as i64 }
65 pred[y*8+x]=p
66 x=x+1
67 }
68 y=y+1
69 }
70 return 0
71}
72func sad8(fb: *u8, W: i64, px: i64, py: i64, pred: *i64) -> i64 {
73 var s: i64=0; var y: i64=0
74 while y<8 { var x: i64=0; while x<8 { s=s+iabs((fb[(py+y)*W+px+x] as i64)-pred[y*8+x]); x=x+1 } y=y+1 }
75 return s
76}
77
78func main() -> i64 {
79 g_puts("=== OURS-INTRA: patent-free codec + 8x8 directional intra prediction + modeled entropy, REAL frame 576x1024 ===\n" as *u8)
80 let W: i64=576; let H: i64=K_MAGIC_1024; let sb: i64=12
81 let npx: i64=W*H
82 let bw8: i64=W/8; let bh8: i64=H/8; let nblk: i64=bw8*bh8
83 let ncoef: i64=nblk*64
84 let RW: i64=W+1; let RH: i64=H+1
85
86 let flen: *i64=sys_mmap(8) as *i64
87 let fb: *u8=sys_read_file("knowledge/staging/media/ref_frame0.yuv" as *u8, flen)
88 if flen[0] < npx { g_puts("FATAL: frame read short\n" as *u8); sys_exit(2); return 2 }
89 g_puts("-- read " as *u8); g_num(flen[0]); g_puts(" bytes; luma " as *u8); g_num(npx); g_puts(" blocks=" as *u8); g_num(nblk); g_puts("\n" as *u8)
90
91 let DM: *i64=sys_mmap(64*8) as *i64; nx_dct8_init(DM)
92 let to_zz: *i64=sys_mmap(64*8) as *i64; let from_zz: *i64=sys_mmap(64*8) as *i64; nx_zigzag_init(to_zz, from_zz)
93 let scratch: *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
94 let qt: *i64=sys_mmap(64*8) as *i64
95 let pred: *i64=sys_mmap(64*8) as *i64; let sh: *i64=sys_mmap(64*8) as *i64; let co: *i64=sys_mmap(64*8) as *i64
96 let q: *i64=sys_mmap(64*8) as *i64; let zz: *i64=sys_mmap(64*8) as *i64; let dq: *i64=sys_mmap(64*8) as *i64; let rres: *i64=sys_mmap(64*8) as *i64
97 let qall: *i64=sys_mmap(ncoef*8) as *i64; let modes: *u8=sys_mmap(nblk+16)
98 let rec: *u8=sys_mmap(RW*RH+16); let rec2: *u8=sys_mmap(RW*RH+16)
99
100 let sym: *u8=sys_mmap(nblk*140 + K_MAGIC_4096); let sp: *i64=sys_mmap(8) as *i64
101 let magw: *BitWriter=sys_mmap(64) as *BitWriter
102 let counts: *i64=sys_mmap(257*8) as *i64; let fr: *i64=sys_mmap(257*8) as *i64; let cu: *i64=sys_mmap(257*8) as *i64; let s2s: *i64=sys_mmap((1<<sb)*8) as *i64
103 let cap: i64=nblk*140 + K_MAGIC_4096; let senc: *u8=sys_mmap(cap); let sdec: *u8=sys_mmap(cap)
104 let sp2: *i64=sys_mmap(8) as *i64; let mpos: *i64=sys_mmap(8) as *i64
105 let zzm: *i64=sys_mmap(64*8) as *i64; let qnat: *i64=sys_mmap(64*8) as *i64; let dq2: *i64=sys_mmap(64*8) as *i64; let rres2: *i64=sys_mmap(64*8) as *i64; let pred2: *i64=sys_mmap(64*8) as *i64
106
107 let qs: *i64=sys_mmap(16*8) as *i64
108 qs[0]=92; qs[1]=85; qs[2]=72; qs[3]=55; qs[4]=40; qs[5]=28; qs[6]=16; qs[7]=8
109 let nq: i64=8
110
111 let lg: i64=sys_openat_append("knowledge/status/codec_real_rd3.log" as *u8, 0x1a4)
112 var all_ok: i64=1
113 var qi: i64=0
114 while qi<nq {
115 let Q: i64=qs[qi]
116 nx_qt_luma(qt, Q)
117 // init bordered recon buffer to 128
118 var ii: i64=0; while ii<RW*RH { rec[ii]=128 as u8; ii=ii+1 }
119 // ENCODE pass (raster) with in-loop reconstruction
120 var by: i64=0
121 while by<bh8 {
122 var bx: i64=0
123 while bx<bw8 {
124 let px: i64=bx*8; let py: i64=by*8; let bidx: i64=by*bw8+bx
125 // mode select by SAD vs reconstructed-neighbor prediction
126 var bestm: i64=0; var bestsad: i64=0x7fffffffffff; var m: i64=0
127 while m<4 { pred8(rec, RW, px, py, m, pred); let s: i64=sad8(fb, W, px, py, pred); if s<bestsad { bestsad=s; bestm=m } m=m+1 }
128 modes[bidx]=bestm as u8
129 pred8(rec, RW, px, py, bestm, pred)
130 // residual -> DCT -> quant -> zigzag (store)
131 var k: i64=0; while k<64 { let yy: i64=k/8; let xx: i64=k%8; sh[k]=(fb[(py+yy)*W+px+xx] as i64)-pred[k]; k=k+1 }
132 nx_dct8_forward_2d(DM, sh, co, scratch, ti, to)
133 var i: i64=0; while i<64 { q[i]=qrnd(co[i], qt[i]); i=i+1 }
134 nx_zigzag_scan(q, to_zz, zz)
135 i=0; while i<64 { qall[bidx*64+i]=zz[i]; i=i+1 }
136 // reconstruct -> feed forward into rec
137 i=0; while i<64 { dq[i]=q[i]*qt[i]; i=i+1 }
138 nx_dct8_inverse_2d(DM, dq, rres, scratch, ti, to)
139 var y2: i64=0
140 while y2<8 { var x2: i64=0; while x2<8 { var p: i64=pred[y2*8+x2]+rres[y2*8+x2]; if p<0{p=0} if p>255{p=255} rec[(py+y2+1)*RW+(px+x2+1)]=p as u8; x2=x2+1 } y2=y2+1 }
141 bx=bx+1
142 }
143 by=by+1
144 }
145 // ENTROPY: per-block [mode byte] + jsym symbols -> rANS ; magbits raw
146 let magbuf: *u8=sys_mmap(npx*2 + K_MAGIC_4096)
147 sp[0]=0; bw_init(magw, magbuf, npx*2+K_MAGIC_4096)
148 // NO cross-block DC-diff: intra prediction already decorrelates DC, so diffing small independent
149 // residual DCs would INCREASE their magnitude. Code each residual DC absolutely (prevdc=0).
150 var b: i64=0
151 while b<nblk { sym[sp[0]]=modes[b]; sp[0]=sp[0]+1; jsym_encode_block(sym, sp, magw, ((qall as i64)+(b*64*8)) as *i64, 0); b=b+1 }
152 while magw.bit_pos != 0 { bw_write_bit(magw, 0) }
153 let nsym: i64=sp[0]
154 let magbytes: i64=(bw_total_bits(magw)+7)/8
155 rans_count(sym, nsym, counts); rans_normalize(counts, fr, sb); rans_cum(fr, cu); rans_build_slot2sym(fr, cu, s2s)
156 let sym_payload: i64=rans_encode(sym, nsym, fr, cu, sb, senc, cap)
157 let total: i64=512+64+8+sym_payload+magbytes
158 // DECODE replay: rANS -> symbols ; per block mode+coeffs ; predict from rec2 neighbors ; reconstruct
159 rans_decode(senc, sym_payload, nsym, fr, cu, sb, s2s, sdec)
160 var rans_ok: i64=1; var i2: i64=0; while i2<nsym { if sdec[i2]!=sym[i2] { rans_ok=0 } i2=i2+1 }
161 var jj: i64=0; while jj<RW*RH { rec2[jj]=128 as u8; jj=jj+1 }
162 sp2[0]=0; mpos[0]=0; var coeff_ok: i64=1
163 b=0
164 while b<nblk {
165 let by2: i64=b/bw8; let bx2: i64=b%bw8; let px: i64=bx2*8; let py: i64=by2*8
166 let mode: i64=sdec[sp2[0]] as i64; sp2[0]=sp2[0]+1
167 jsym_decode_block(sdec, sp2, magbuf, mpos, 0, zzm)
168 var i: i64=0; while i<64 { if zzm[i]!=qall[b*64+i] { coeff_ok=0 } i=i+1 }
169 nx_zigzag_unscan(zzm, from_zz, qnat)
170 i=0; while i<64 { dq2[i]=qnat[i]*qt[i]; i=i+1 }
171 nx_dct8_inverse_2d(DM, dq2, rres2, scratch, ti, to)
172 pred8(rec2, RW, px, py, mode, pred2)
173 var y3: i64=0
174 while y3<8 { var x3: i64=0; while x3<8 { var p: i64=pred2[y3*8+x3]+rres2[y3*8+x3]; if p<0{p=0} if p>255{p=255} rec2[(py+y3+1)*RW+(px+x3+1)]=p as u8; x3=x3+1 } y3=y3+1 }
175 b=b+1
176 }
177 // recon_ok (enc==dec) + SSE vs original
178 var recon_ok: i64=1; var sse: i64=0; var maxe: i64=0
179 var yy2: i64=0
180 while yy2<H {
181 var xx2: i64=0
182 while xx2<W {
183 let rv: i64=rec[(yy2+1)*RW+(xx2+1)] as i64
184 let dv: i64=rec2[(yy2+1)*RW+(xx2+1)] as i64
185 if rv!=dv { recon_ok=0 }
186 let d: i64=dv-(fb[yy2*W+xx2] as i64); sse=sse+d*d; let a: i64=iabs(d); if a>maxe { maxe=a }
187 xx2=xx2+1
188 }
189 yy2=yy2+1
190 }
191 if rans_ok==0 { all_ok=0 }
192 if coeff_ok==0 { all_ok=0 }
193 if recon_ok==0 { all_ok=0 }
194 let okf: i64=rans_ok*coeff_ok*recon_ok
195
196 g_puts("OURS3 q=" as *u8); g_num(Q); g_puts(" total=" as *u8); g_num(total); g_puts(" sympay=" as *u8); g_num(sym_payload); g_puts(" magB=" as *u8); g_num(magbytes)
197 g_puts(" sse=" as *u8); g_num(sse); g_puts(" maxErr=" as *u8); g_num(maxe); g_puts(" ok=" as *u8); g_num(okf); g_puts("\n" as *u8)
198 if lg>=0 { g_w(lg,"OURS3 q=" as *u8); g_wn(lg,Q); g_w(lg," total=" as *u8); g_wn(lg,total); g_w(lg," sse=" as *u8); g_wn(lg,sse); g_w(lg," maxErr=" as *u8); g_wn(lg,maxe); g_w(lg," ok=" as *u8); g_wn(lg,okf); g_w(lg,"\n" as *u8) }
199 qi=qi+1
200 }
201 if lg>=0 { sys_close(lg) }
202 if all_ok==1 { g_puts("---- round-trip lossless + enc/dec recon-exact ALL q verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
203 g_puts("---- BUG (round-trip or recon mismatch) verdict=RED\n" as *u8); sys_exit(1); return 1
204}