code wiki / _hdl_build / nx_vmotion_gate.nx

nx_vmotion_gate.nx source

↩ module page · 99 lines · 5729 B

1// nx_vmotion_gate.nx -- proves + MEASURES sovereign motion compensation (nx_vmotion), the rung that beats plain 2// tile-delta the way VP8/H.264 do. Native nx_cc->nxasm, no node. 3// 1) PAN exceed: a frame shifted by (3,2) -> tile-delta sees the block as fully changed (huge SAD), motion 4// search finds the shift (MV) with ~0 residual -> measured: motion-comp << tile-delta on motion 5// 2) MV correctness: the found vector equals the true shift (negated) 6// 3) lossless reconstruct: predicted-at-MV + residual == the cur block 7// 4) static block: cur==prev -> MV=(0,0), SAD=0 8// 5) honest limit (neg): a noisy block with no match -> SAD stays high (motion comp isn't magic -> intra fallback) 9// license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_vmotion.nx" 12import "nx_gate_verdict.nx" 13 14func g_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 15func g_pn(v: i64) -> i64 { 16 let b: *u8 = sys_mmap(28); var x: i64 = v 17 if x < 0 { b[0]=45; sys_write(1,b,1); x = 0 - x } 18 if x == 0 { b[0]=48; sys_write(1,b,1); return 0 } 19 var d: i64=0; var y: i64=x 20 while y>0 { d=d+1; y=y/10 } 21 var i: i64=d-1; y=x 22 while i>=0 { b[i]=(48+(y%10)) as u8; y=y/10; i=i-1 } 23 sys_write(1,b,d); return 0 24} 25func g_check(name: *u8, cond: i64) -> i64 { 26 if cond==1 { g_puts(" PASS " as *u8) } else { g_puts(" FAIL " as *u8) } 27 g_puts(name); g_puts("\n" as *u8); return cond 28} 29func tex(x: i64, y: i64) -> i64 { return (x*7 + y*13 + x*y*3) & 0xff } // deterministic textured content 30func block_eq(a: *u8, b: *u8, W: i64, bx: i64, by: i64, T: i64) -> i64 { 31 let cx: i64 = bx*T; let cy: i64 = by*T 32 var yy: i64=0; while yy<T { var xx: i64=0; while xx<T { if a[(cy+yy)*W+(cx+xx)] != b[(cy+yy)*W+(cx+xx)] { return 0 } xx=xx+1 } yy=yy+1 } 33 return 1 34} 35 36func main() -> i64 { 37 let vmscr3: *i64 = sys_mmap(32) as *i64 // vm_search scratch (2026-07-29: hoisted ONE alloc; the per-call sys_mmap inside vm_search was the wasm 0-stub + native map-leak class) 38 g_puts("nx_vmotion gate (sovereign motion compensation -- beats tile-delta on motion, MEASURED)\n" as *u8) 39 var pass: i64 = 0; var total: i64 = 0 40 41 let W: i64 = 160; let H: i64 = 96; let T: i64 = 16; let R: i64 = 8 42 let A: *u8 = sys_mmap(W*H) // previous frame 43 let B: *u8 = sys_mmap(W*H) // current frame = A panned by (3,2) 44 let dst: *u8 = sys_mmap(W*H) 45 let mv: *i64 = sys_mmap(2*8) as *i64 46 let res: *i64 = sys_mmap(T*T*8) as *i64 47 48 var y: i64 = 0 49 while y < H { var x: i64 = 0; while x < W { A[y*W+x] = tex(x,y) as u8; x=x+1 } y=y+1 } 50 // B = A shifted right 3, down 2 (a camera pan) 51 y = 0 52 while y < H { var x: i64 = 0 53 while x < W { 54 if y >= 2 { if x >= 3 { B[y*W+x] = A[(y-2)*W + (x-3)] } else { B[y*W+x] = tex(x,y) as u8 } } else { B[y*W+x] = tex(x,y) as u8 } 55 x=x+1 56 } y=y+1 } 57 58 let BX: i64 = 5; let BY: i64 = 3 // a center block, clear of the edges 59 60 // 1) PAN exceed: tile-delta SAD (zero MV) vs motion-comp SAD 61 let sad_tile: i64 = vm_sad_zero(B, A, W, BX, BY, T) 62 let sad_mc: i64 = vm_search(B, A, W, H, BX, BY, T, R, mv, vmscr3) 63 g_puts(" [measure] panned block: tile-delta SAD=" as *u8); g_pn(sad_tile); g_puts(" motion-comp SAD=" as *u8); g_pn(sad_mc) 64 g_puts(" MV=(" as *u8); g_pn(mv[0]); g_puts("," as *u8); g_pn(mv[1]); g_puts(")\n" as *u8) 65 pass = pass + g_check("PAN: motion-comp residual << tile-delta change (the H.264 win)" as *u8, (sad_mc * 20 < sad_tile) & (sad_mc <= 4)); total=total+1 66 67 // 2) MV correctness (true shift was +3,+2 -> best match is at -3,-2) 68 pass = pass + g_check("motion vector equals the true shift (negated)" as *u8, (mv[0] == (0-3)) & (mv[1] == (0-2))); total=total+1 69 70 // 3) lossless reconstruct: predicted-at-MV + residual == cur block 71 vm_residual(B, A, res, W, BX, BY, T, mv) 72 var i: i64 = 0 73 while i < W*H { dst[i] = 0 as u8; i = i + 1 } 74 vm_reconstruct(dst, A, res, W, BX, BY, T, mv) 75 pass = pass + g_check("reconstruct exact: predicted@MV + residual == cur block" as *u8, block_eq(dst, B, W, BX, BY, T)); total=total+1 76 77 // 4) static block: A vs A -> no motion 78 let sad_static: i64 = vm_search(A, A, W, H, BX, BY, T, R, mv, vmscr3) 79 pass = pass + g_check("static block: MV=(0,0), SAD=0" as *u8, (sad_static == 0) & (mv[0]==0) & (mv[1]==0)); total=total+1 80 81 // 5) honest limit (neg): a noisy block with no match -> SAD stays high (fall back to intra/tile) 82 let NX: i64 = 8; let NY: i64 = 1 83 var ny: i64 = 0 84 while ny < T { var nx: i64 = 0; while nx < T { B[(NY*T+ny)*W + (NX*T+nx)] = ((nx*131 + ny*197 + 99) & 0xff) as u8; nx=nx+1 } ny=ny+1 } 85 let sad_noise: i64 = vm_search(B, A, W, H, NX, NY, T, R, mv, vmscr3) 86 g_puts(" [measure] unmatched noisy block: best SAD=" as *u8); g_pn(sad_noise); g_puts(" (stays high -> intra fallback, not faked)\n" as *u8) 87 pass = pass + g_check("honest: no-match block keeps high residual (motion comp not magic, neg)" as *u8, sad_noise > 200); total=total+1 88 89 g_puts("---- vmotion gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 90 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 91 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 92 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 93 let ctr__dry: *i64 = gv_ctr() 94 ctr__dry[0] = pass 95 ctr__dry[1] = total 96 let rc__dry: i64 = gv_verdict("VMOTION-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 97 sys_exit(rc__dry) 98 return rc__dry 99}