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}