code wiki / _hdl_build / nx_vdeblock_gate.nx

nx_vdeblock_gate.nx source

↩ module page · 73 lines · 4051 B

1// nx_vdeblock_gate.nx -- proves the wired deblocking pass (nx_vdeblock) reduces BLOCKING artifacts. Build a smooth 2// gradient (the true signal), then a "blocky" version that quantizes each 4x4 block to its block mean (the DC-step 3// artifact quantization leaves at block edges). Deblock the blocky frame and MEASURE that it moves back toward the 4// smooth original (higher PSNR, lower block-edge discontinuity) -- i.e. the filter smooths false block edges. 5import "nx_syscalls.nx" 6import "nx_gate_emit_lib.nx" 7import "nx_vdeblock.nx" 8import "nx_quality_metric.nx" 9import "nx_gate_verdict.nx" 10 11func g_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 12// sum of |left-right| across all internal 4x4 vertical block edges = the blocking discontinuity energy 13func block_edge_disc(f: *u8, W: i64, H: i64) -> i64 { 14 var s: i64=0; var x: i64=4 15 while x < W { var y: i64=0 16 while y < H { s = s + g_abs((f[y*W+(x-1)] as i64) - (f[y*W+x] as i64)); y=y+1 } x=x+4 } 17 return s 18} 19 20func main() -> i64 { 21 g_puts("nx_vdeblock gate (wired H.264 deblock reduces blocking, MEASURED)\n" as *u8) 22 var pass: i64 = 0; var total: i64 = 0 23 let W: i64 = 32; let H: i64 = 32; let N: i64 = W*H 24 25 let orig: *u8 = sys_mmap(N) as *u8 // smooth gradient = the true signal (no blocking) 26 let blocky: *u8 = sys_mmap(N) as *u8 // each 4x4 block flattened to its mean -> DC steps at edges 27 let line: *i64 = sys_mmap(8*8) as *i64 28 29 var y: i64 = 0 30 while y < H { var x: i64 = 0 31 while x < W { orig[y*W+x] = (40 + 2*x + 2*y) as u8; x = x + 1 } y = y + 1 } 32 // build blocky: per 4x4 block, set every pixel to the block mean (the classic transform-block artifact) 33 var by: i64 = 0 34 while by < H { var bx: i64 = 0 35 while bx < W { 36 var sum: i64 = 0; var yy: i64 = 0 37 while yy < 4 { var xx: i64 = 0 38 while xx < 4 { sum = sum + (orig[(by+yy)*W + (bx+xx)] as i64); xx = xx + 1 } yy = yy + 1 } 39 let mean: i64 = sum / 16 40 yy = 0 41 while yy < 4 { var xx: i64 = 0 42 while xx < 4 { blocky[(by+yy)*W + (bx+xx)] = mean as u8; xx = xx + 1 } yy = yy + 1 } 43 bx = bx + 4 44 } 45 by = by + 4 46 } 47 48 let psnr_blocky: i64 = qm_psnr_cdb(blocky, orig, N) 49 let disc_blocky: i64 = block_edge_disc(blocky, W, H) 50 51 vc_deblock_frame(blocky, W, H, 32, 3, line) // deblock in place (qp=32, bS=3 intra-edge strength) 52 53 let psnr_deblk: i64 = qm_psnr_cdb(blocky, orig, N) 54 let disc_deblk: i64 = block_edge_disc(blocky, W, H) 55 56 g_puts(" [measure] PSNR vs smooth original: blocky=" as *u8); g_pn(psnr_blocky/100); g_puts("." as *u8); g_pn(psnr_blocky%100); g_puts("dB -> deblocked=" as *u8); g_pn(psnr_deblk/100); g_puts("." as *u8); g_pn(psnr_deblk%100); g_puts("dB\n" as *u8) 57 g_puts(" [measure] block-edge discontinuity: blocky=" as *u8); g_pn(disc_blocky); g_puts(" -> deblocked=" as *u8); g_pn(disc_deblk); g_puts("\n" as *u8) 58 59 pass = pass + g_check("deblock raises PSNR toward the true smooth signal" as *u8, psnr_deblk > psnr_blocky); total=total+1 60 pass = pass + g_check("deblock reduces block-edge discontinuity" as *u8, disc_deblk < disc_blocky); total=total+1 61 pass = pass + g_check("blocking measurably reduced (>= 20% less edge discontinuity)" as *u8, disc_deblk * 5 <= disc_blocky * 4); total=total+1 62 63 g_puts("---- vdeblock gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 64 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 65 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 66 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 67 let ctr__dry: *i64 = gv_ctr() 68 ctr__dry[0] = pass 69 ctr__dry[1] = total 70 let rc__dry: i64 = gv_verdict("VDEBLOCK-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 71 sys_exit(rc__dry) 72 return rc__dry 73}