code wiki / _hdl_build / nx_vcodec_tf_speed.nx

nx_vcodec_tf_speed.nx source

↩ module page · 44 lines · 2818 B

1import "nx_gate_base.nx" 2// nx_vcodec_tf_speed.nx -- decisive WHT(tf=0) vs DCT(tf=1) ENCODE-TIME probe on the SAME real P-frame at the 3// live geometry. DCT gives +2.12dB (measured) but costs more per block; this answers whether that costs fps. 4// If DCT is within ~1.5x WHT, the quality win ships free (motion search dominates); if 2x+, it's a real fps hit. 5import "nx_syscalls.nx" 6import "nx_video_codec_wasm.nx" 7const K_MAGIC_262144: i64 = 262144 8const K_MAGIC_6016: i64 = 6016 9 10func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 11" as *u8); return ok } 12func gn(v: i64) -> i64 { 13 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 14 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} 15 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 16func fillf(yuv: *u8, W: i64, H: i64, sh: i64) -> i64 { 17 let N: i64=W*H; let C: i64=(W/2)*(H/2) 18 var r: i64=0 19 while r<H { var c: i64=0 20 while c<W { let sc: i64=c+sh; var v: i64=(sc*255)/W+(((sc/2+r/3)%7)*20-60); if sc>W/2{v=v+45} 21 if v<0{v=0} if v>255{v=255}; yuv[r*W+c]=v as u8; c=c+1 } r=r+1 } 22 var i: i64=N; while i<N+2*C { yuv[i]=120 as u8; i=i+1 } return 0 } 23 24func speed(W: i64, H: i64, tf: i64, ITER: i64) -> i64 { 25 let N: i64=W*H; let C: i64=(W/2)*(H/2); let sz: i64=N+2*C 26 let cur: *u8=sys_mmap(sz); let prev: *u8=sys_mmap(sz); let recon: *u8=sys_mmap(sz) 27 let out: *u8=sys_mmap(K_MAGIC_262144); let blk: *i64=sys_mmap(512) as *i64; let mv: *i64=sys_mmap(128) as *i64 28 fillf(prev, W, H, 0); fillf(cur, W, H, 3) // 3px shift -> real motion to search 29 let t0: i64=sys_now_us(); var i: i64=0 30 while i < ITER { vc_enc_frame_packed_tf(cur, prev, recon, W, H, 18, 0, K_MAGIC_6016, out, blk, mv, tf); i=i+1 } 31 return (sys_now_us()-t0)/ITER } 32 33func main() -> i64 { 34 gw("=== nx_vcodec_tf_speed: WHT vs DCT encode time (same real P-frame) ===\n" as *u8) 35 let IT: i64=30 36 let w0: i64=speed(320, 256, 0, IT); let d0: i64=speed(320, 256, 1, IT) // Y-plane full-frame at 320x256 37 gw(" 320x256 Y-plane WHT=" as *u8); gn(w0); gw("us DCT=" as *u8); gn(d0) 38 gw("us ratio=" as *u8); gn(d0*100/(w0+1)); gw("%\n" as *u8) 39 let w1: i64=speed(256, 192, 0, IT); let d1: i64=speed(256, 192, 1, IT) 40 gw(" 256x192 Y-plane WHT=" as *u8); gn(w1); gw("us DCT=" as *u8); gn(d1) 41 gw("us ratio=" as *u8); gn(d1*100/(w1+1)); gw("%\n" as *u8) 42 gw("VERDICT: DCT/WHT = " as *u8); gn((d0+d1)*100/(w0+w1+1)) 43 if (d0+d1) < (w0+w1)*15/10 { gw("% (<150% -> quality win ships ~free; motion search dominates)\n" as *u8); return 0 } 44 gw("% (>=150% -> real fps cost; gate DCT to keyframes or capable devices)\n" as *u8); return 0 }