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 }