code wiki / _hdl_build / nx_vcodec_timing_probe.nx

nx_vcodec_timing_probe.nx source

↩ module page · 63 lines · 3343 B

1import "nx_gate_base.nx" 2// nx_vcodec_timing_probe.nx -- where does the per-frame CPU go? Times vv_enc (incl deblock), vv_dec (incl 3// deblock), and vv_deblock ALONE, at the live geometries + qp, so the fps drop is diagnosed with numbers 4// not guesses. license_tier: ORIGINAL 5import "nx_syscalls.nx" 6import "nx_video_codec_wasm.nx" 7const K_MAGIC_262144: i64 = 262144 8const K_MAGIC_6016: i64 = 6016 9const K_MAGIC_1000000: i64 = 1000000 10 11func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 12" as *u8); return ok } 13func gn(v: i64) -> i64 { 14 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 15 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} 16 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 17 18func fill(yuv: *u8, W: i64, H: i64, shift: i64) -> i64 { 19 let N: i64=W*H; let C: i64=(W/2)*(H/2) 20 var y: i64=0 21 while y<H { var x: i64=0 22 while x<W { let sx: i64=x+shift 23 var v: i64=(sx*255)/W + (((sx/2+y/3)%7)*20-60); if sx>W/2 { v=v+45 } 24 if v<0 {v=0} if v>255 {v=255}; yuv[y*W+x]=v as u8; x=x+1 } y=y+1 } 25 var i: i64=N; while i<N+2*C { yuv[i]=120 as u8; i=i+1 } return 0 } 26 27func run(W: i64, H: i64, q: i64) -> i64 { 28 let N: i64=W*H; let C: i64=(W/2)*(H/2); let sz: i64=N+2*C 29 let a: *u8=sys_mmap(sz); let b: *u8=sys_mmap(sz) 30 let pe: *u8=sys_mmap(sz); let re: *u8=sys_mmap(sz); let pd: *u8=sys_mmap(sz); let rd: *u8=sys_mmap(sz) 31 let stream: *u8=sys_mmap(K_MAGIC_262144); let blk: *i64=sys_mmap(512) as *i64; let mv: *i64=sys_mmap(128) as *i64 32 var i: i64=0; while i<sz { pe[i]=0 as u8; pd[i]=0 as u8; i=i+1 } 33 fill(a, W, H, 0); fill(b, W, H, 6) 34 // warm one keyframe so P-path is measured 35 let kb: i64 = vv_enc(a, pe, re, W, H, q, 1, K_MAGIC_6016, stream, K_MAGIC_262144, blk, mv) 36 vv_dec(pd, rd, W, H, q, stream, kb, blk, mv) 37 let ITER: i64 = 60 38 // encode (P) timing 39 let t0: i64 = sys_now_us(); var it: i64=0 40 while it < ITER { vv_enc(b, re, a, W, H, q, 0, K_MAGIC_6016, stream, K_MAGIC_262144, blk, mv); it=it+1 } 41 let encus: i64 = (sys_now_us()-t0)/ITER 42 let pkb: i64 = vv_enc(b, re, a, W, H, q, 0, K_MAGIC_6016, stream, K_MAGIC_262144, blk, mv) 43 // decode timing 44 let t1: i64 = sys_now_us(); it=0 45 while it < ITER { vv_dec(pd, rd, W, H, q, stream, pkb, blk, mv); it=it+1 } 46 let decus: i64 = (sys_now_us()-t1)/ITER 47 // deblock ALONE (all 3 planes) 48 let t2: i64 = sys_now_us(); it=0 49 while it < ITER { vv_deblock(rd, W, H, q); it=it+1 } 50 let dblus: i64 = (sys_now_us()-t2)/ITER 51 gw(" " as *u8); gn(W); gw("x" as *u8); gn(H); gw(" q=" as *u8); gn(q) 52 gw(" P-enc=" as *u8); gn(encus); gw("us dec=" as *u8); gn(decus); gw("us deblock-alone=" as *u8); gn(dblus) 53 gw("us Pbytes=" as *u8); gn(pkb); gw(" (enc caps ~" as *u8); gn(K_MAGIC_1000000/(encus+1)); gw("fps)\n" as *u8) 54 return 0 } 55 56func main() -> i64 { 57 gw("=== nx_vcodec_timing_probe: per-frame CPU (enc incl deblock / dec / deblock-alone) ===\n" as *u8) 58 run(256, 192, 10) 59 run(288, 224, 10) 60 run(288, 224, 24) 61 run(320, 240, 10) 62 gw("(deblock-alone shows what the filter costs; if enc caps >> 30fps the fps drop is elsewhere)\n" as *u8) 63 return 0 }