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 }