code wiki / _hdl_build / nx_vdeblock_gate.nx
nx_vdeblock_gate.nx source
↩ module page · 65 lines · 3609 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"
9
10func g_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
11// sum of |left-right| across all internal 4x4 vertical block edges = the blocking discontinuity energy
12func block_edge_disc(f: *u8, W: i64, H: i64) -> i64 {
13 var s: i64=0; var x: i64=4
14 while x < W { var y: i64=0
15 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 }
16 return s
17}
18
19func main() -> i64 {
20 g_puts("nx_vdeblock gate (wired H.264 deblock reduces blocking, MEASURED)\n" as *u8)
21 var pass: i64 = 0; var total: i64 = 0
22 let W: i64 = 32; let H: i64 = 32; let N: i64 = W*H
23
24 let orig: *u8 = sys_mmap(N) as *u8 // smooth gradient = the true signal (no blocking)
25 let blocky: *u8 = sys_mmap(N) as *u8 // each 4x4 block flattened to its mean -> DC steps at edges
26 let line: *i64 = sys_mmap(8*8) as *i64
27
28 var y: i64 = 0
29 while y < H { var x: i64 = 0
30 while x < W { orig[y*W+x] = (40 + 2*x + 2*y) as u8; x = x + 1 } y = y + 1 }
31 // build blocky: per 4x4 block, set every pixel to the block mean (the classic transform-block artifact)
32 var by: i64 = 0
33 while by < H { var bx: i64 = 0
34 while bx < W {
35 var sum: i64 = 0; var yy: i64 = 0
36 while yy < 4 { var xx: i64 = 0
37 while xx < 4 { sum = sum + (orig[(by+yy)*W + (bx+xx)] as i64); xx = xx + 1 } yy = yy + 1 }
38 let mean: i64 = sum / 16
39 yy = 0
40 while yy < 4 { var xx: i64 = 0
41 while xx < 4 { blocky[(by+yy)*W + (bx+xx)] = mean as u8; xx = xx + 1 } yy = yy + 1 }
42 bx = bx + 4
43 }
44 by = by + 4
45 }
46
47 let psnr_blocky: i64 = qm_psnr_cdb(blocky, orig, N)
48 let disc_blocky: i64 = block_edge_disc(blocky, W, H)
49
50 vc_deblock_frame(blocky, W, H, 32, 3, line) // deblock in place (qp=32, bS=3 intra-edge strength)
51
52 let psnr_deblk: i64 = qm_psnr_cdb(blocky, orig, N)
53 let disc_deblk: i64 = block_edge_disc(blocky, W, H)
54
55 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)
56 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)
57
58 pass = pass + g_check("deblock raises PSNR toward the true smooth signal" as *u8, psnr_deblk > psnr_blocky); total=total+1
59 pass = pass + g_check("deblock reduces block-edge discontinuity" as *u8, disc_deblk < disc_blocky); total=total+1
60 pass = pass + g_check("blocking measurably reduced (>= 20% less edge discontinuity)" as *u8, disc_deblk * 5 <= disc_blocky * 4); total=total+1
61
62 g_puts("---- vdeblock gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8)
63 if pass == total { g_puts("verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
64 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1
65}