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}