code wiki / _hdl_build / nx_vcodec_emode_gate.nx

nx_vcodec_emode_gate.nx source

↩ module page · 66 lines · 3759 B

1import "nx_gate_base.nx" 2// nx_vcodec_emode_gate.nx -- the coded ~5% of P-MBs carry the whole P-frame cost (skiprate gate: 95% skip). 3// This measures P-total bytes on standard akiyo under each shipped encoder-only feature, cumulatively, so we 4// see how much each already buys on P-frames and what the honest post-all-wins baseline is BEFORE deciding the 5// next (wire-format) build. emode bits: bit0 range-coder, bit2 RD-auto 8x8, bit3 rich-intra, bit5 sig-map. 6// RDOQ rides inside the transform path automatically. Reports keyframe + P-total + meanP per config. ORIGINAL 7import "nx_syscalls.nx" 8import "nx_video_codec_wasm.nx" 9 10const SW: i64 = 352 11const SH: i64 = 288 12const NF: i64 = 48 13 14func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 15" as *u8); return ok } 16func gn(v: i64) -> i64 { 17 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 18 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} 19 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 20func cpb(d: *u8, s: *u8, n: i64) -> i64 { var i: i64=0; while i<n { d[i]=s[i]; i=i+1 } return 0 } 21 22func run(yuv: *u8, hi: i64, total: i64, qp: i64, emode: i64, label: *u8) -> i64 { 23 let N: i64=SW*SH; let C2: i64=(SW/2)*(SH/2); let fdata: i64=N+2*C2; let sz: i64=fdata 24 let fp: *i64 = sys_mmap(128*8) as *i64 25 var nf: i64=0; var p: i64=hi 26 while nf < NF { if p>=total { break } 27 var q: i64=p; while q<total { if (yuv[q]&0xff)==10 { break } q=q+1 } q=q+1 28 if q+fdata>total { break } fp[nf]=(yuv as i64)+q; nf=nf+1; p=q+fdata } 29 if nf < NF { gw("too few frames\n" as *u8); return 1 } 30 let prevE: *u8=sys_mmap(sz+64); let reconE: *u8=sys_mmap(sz+64) 31 let wire: *u8=sys_mmap(2097152); let blk: *i64=sys_mmap(512) as *i64; let mv: *i64=sys_mmap(128) as *i64 32 let est: *i64=sys_mmap(64) as *i64; let probs: *i64=sys_mmap(32*8) as *i64; let rcbuf: *u8=sys_mmap(2097152) 33 let t8c: *i64=sys_mmap(5120) as *i64; let rctx: *i64=sys_mmap(64) as *i64 34 vc_t8_init(t8c) 35 var z: i64=0; while z<sz { prevE[z]=0 as u8; z=z+1 } 36 rctx[1]=est as i64; rctx[2]=probs as i64; rctx[3]=rcbuf as i64; rctx[4]=t8c as i64; rctx[5]=0; rctx[6]=0; rctx[7]=0 37 var keyB: i64=0; var pB: i64=0 38 var f: i64=0 39 while f < NF { 40 let cur: *u8=fp[f] as *u8 41 var key: i64=0; if f==0 { key=1 } 42 rctx[0]=emode 43 let nb: i64 = vv_enc_rct8(cur, prevE, reconE, SW, SH, qp, key, qp*188, wire, 2097152, blk, mv, rctx) 44 if nb<=0 { gw("enc fail\n" as *u8); return 1 } 45 if key==1 { keyB=nb } else { pB=pB+nb } 46 cpb(prevE, reconE, sz) 47 f=f+1 48 } 49 let meanP: i64 = pB/(NF-1) 50 gw(" " as *u8); gw(label); gw(" emode=" as *u8); gn(emode) 51 gw(" KEY=" as *u8); gn(keyB); gw("B P-total=" as *u8); gn(pB); gw("B meanP=" as *u8); gn(meanP); gw("B\n" as *u8) 52 return 0 } 53 54func main() -> i64 { 55 gw("=== nx_vcodec_emode_gate: P-frame cost per shipped encoder feature on akiyo (qp=8) ===\n" as *u8) 56 let box: *i64 = sys_mmap(16) as *i64 57 let yuv: *u8 = sys_read_file("/tmp/akiyo_cif.y4m" as *u8, box) 58 if (yuv as i64)==0 { gw("cannot read /tmp/akiyo_cif.y4m -> RED\n" as *u8); return 1 } 59 let total: i64=box[0] 60 var hi: i64=0; while hi<total { if (yuv[hi]&0xff)==10 { break } hi=hi+1 } hi=hi+1 61 run(yuv, hi, total, 8, 1, "range-coder only " as *u8) 62 run(yuv, hi, total, 8, 1+4, "+RD-auto 8x8 " as *u8) 63 run(yuv, hi, total, 8, 1+4+8, "+rich-intra " as *u8) 64 run(yuv, hi, total, 8, 1+4+8+32, "+sig-map (SHIPPED) " as *u8) 65 gw("EMODE: DONE (cumulative feature cost on P-frames)\n" as *u8) 66 return 0 }