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}