code wiki / _hdl_build / nx_vcodec_msu_ours.nx

nx_vcodec_msu_ours.nx source

↩ module page · 91 lines · 4945 B

1// nx_vcodec_msu_ours.nx -- Encodes video frames with specific codec settings and measures byte counts and quality metrics for benchmarking. 2import "nx_gate_base.nx" 3// nx_vcodec_msu_ours.nx -- EXACT RD points for OUR codec on /tmp/seq.y4m, for the MSU head-to-head. Encodes the 4// live config (emode 169 = rc+rich-intra+sig-map+P_8x8 partition) at a qp sweep and reports, per qp: total bytes, 5// KEYFRAME bytes, P-total bytes, and the luma SSE + luma pixel count (PSNR computed exactly downstream in awk, no 6// NishiLang float). Emits nothing to compare against here -- the harness runs x264/x265/av1 through ffmpeg on the 7// SAME sequence and BD-rate's the two curves. CIF only. license: ORIGINAL 8import "nx_syscalls.nx" 9import "nx_video_codec_wasm.nx" 10const K_MAGIC_4194304: i64 = 4194304 11const K_MAGIC_5120: i64 = 5120 12 13const SW: i64 = 352 14const SH: i64 = 288 15const NF: i64 = 48 16const SKIPMUL: i64 = 30 // skip-threshold multiplier (qp*SKIPMUL). 188=drift-prone baseline; TEST lower. 17 18func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 19" as *u8); return ok } 20func gn(v: i64) -> i64 { 21 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 22 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} 23 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 24func cpb(d: *u8, s: *u8, n: i64) -> i64 { var i: i64=0; while i<n { d[i]=s[i]; i=i+1 } return 0 } 25 26func frames(yuv: *u8, hi: i64, total: i64, fp: *i64, fdata: i64) -> i64 { 27 var nf: i64=0; var p: i64=hi 28 while nf < NF { if p>=total { break } 29 var q: i64=p; while q<total { if (yuv[q]&0xff)==10 { break } q=q+1 } q=q+1 30 if q+fdata>total { break } fp[nf]=(yuv as i64)+q; nf=nf+1; p=q+fdata } 31 return nf } 32 33func run(fp: *i64, qp: i64, emode: i64, sz: i64, allkey: i64) -> i64 { 34 return runpq(fp, qp, qp, emode, sz, allkey) } 35// keyframe uses kq, P-frames use pq (drift/rate test: does spending more on P hold quality efficiently?) 36func runpq(fp: *i64, kq: i64, pq: i64, emode: i64, sz: i64, allkey: i64) -> i64 { 37 let prevE: *u8=sys_mmap(sz+64); let reconE: *u8=sys_mmap(sz+64) 38 let wire: *u8=sys_mmap(K_MAGIC_4194304); let blk: *i64=sys_mmap(512) as *i64; let mv: *i64=sys_mmap(128) as *i64 39 let est: *i64=sys_mmap(64) as *i64; let probs: *i64=sys_mmap(32*8) as *i64; let rcbuf: *u8=sys_mmap(K_MAGIC_4194304) 40 let t8c: *i64=sys_mmap(K_MAGIC_5120) as *i64; let rctx: *i64=sys_mmap(64) as *i64 41 vc_t8_init(t8c) 42 var z: i64=0; while z<sz { prevE[z]=0 as u8; z=z+1 } 43 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 44 var keyB: i64=0; var pB: i64=0; var sseY: i64=0; var keySSE: i64=0; var npix: i64=0 45 let NL: i64=SW*SH 46 var f: i64=0 47 while f < NF { 48 let cur: *u8=fp[f] as *u8 49 var key: i64=0; if f==0 { key=1 } if allkey==1 { key=1 } 50 var fq: i64 = kq; if key==0 { fq = pq } 51 rctx[0]=emode 52 let nb: i64 = vv_enc_rct8(cur, prevE, reconE, SW, SH, fq, key, fq*SKIPMUL, wire, K_MAGIC_4194304, blk, mv, rctx) 53 if nb<=0 { gw("enc fail\n" as *u8); return 1 } 54 if f==0 { keyB=nb } else { pB=pB+nb } 55 var pxi: i64=0; var fsse: i64=0 56 while pxi<NL { let d: i64=(reconE[pxi]&0xff)-(cur[pxi]&0xff); fsse=fsse+d*d; pxi=pxi+1 } 57 sseY=sseY+fsse; if f==0 { keySSE=fsse } 58 npix=npix+NL 59 cpb(prevE, reconE, sz) 60 f=f+1 61 } 62 if allkey==1 { gw("OURSINTRA kq=" as *u8) } else { gw("OURS kq=" as *u8) } 63 gn(kq); gw(" pq=" as *u8); gn(pq); gw(" total=" as *u8); gn(keyB+pB); gw(" key=" as *u8); gn(keyB) 64 gw(" ptot=" as *u8); gn(pB); gw(" sseY=" as *u8); gn(sseY); gw(" keySSE=" as *u8); gn(keySSE) 65 gw(" npix=" as *u8); gn(npix); gw("\n" as *u8) 66 return 0 } 67 68func main() -> i64 { 69 let box: *i64 = sys_mmap(16) as *i64 70 let yuv: *u8 = sys_read_file("/tmp/seq.y4m" as *u8, box) 71 if (yuv as i64)==0 { gw("cannot read /tmp/seq.y4m -> RED\n" as *u8); return 1 } 72 let total: i64=box[0] 73 var hi: i64=0; while hi<total { if (yuv[hi]&0xff)==10 { break } hi=hi+1 } hi=hi+1 74 let C2: i64=(SW/2)*(SH/2); let fdata: i64=SW*SH+2*C2; let sz: i64=fdata 75 let fp: *i64=sys_mmap(128*8) as *i64 76 let nf: i64=frames(yuv, hi, total, fp, fdata) 77 if nf < NF { gw("too few frames -> RED\n" as *u8); return 1 } 78 // I+P RD curve (GOP48, live partition config) for BD-rate vs the oracles 79 run(fp, 8, 169, sz, 0) 80 run(fp, 16, 169, sz, 0) 81 run(fp, 24, 169, sz, 0) 82 run(fp, 32, 169, sz, 0) 83 run(fp, 44, 169, sz, 0) 84 // ALL-INTRA (isolates the intra path -- keyframe/mode-decision changes show here) 85 run(fp, 8, 169, sz, 1) 86 run(fp, 16, 169, sz, 1) 87 run(fp, 24, 169, sz, 1) 88 run(fp, 32, 169, sz, 1) 89 run(fp, 44, 169, sz, 1) 90 gw("MSU_OURS: DONE\n" as *u8) 91 return 0 }