code wiki / _hdl_build / nx_vcodec_inloop_gate.nx

nx_vcodec_inloop_gate.nx source

↩ module page · 73 lines · 4680 B

1// nx_vcodec_inloop_gate.nx -- proves IN-LOOP deblocking helps COMPRESSION: at a high QP the reconstructed reference 2// frame has blocking artifacts; if both encoder and decoder deblock that reference before predicting the next frame 3// (identically, so they stay in sync), the cleaner reference predicts better -> smaller residual -> a smaller next- 4// frame stream. Applied AROUND the codec (the deblock organ carries a syscall import; keeping it outside nx_vcodec 5// preserves the wasm-clean codec path). Measures the same inter frame coded from a RAW vs a DEBLOCKED reference. 6import "nx_syscalls.nx" 7import "nx_gate_emit_lib.nx" 8import "nx_vcodec.nx" 9import "nx_vdeblock.nx" 10import "nx_quality_metric.nx" 11 12func frame_equal(a: *u8, b: *u8, n: i64) -> i64 { var i: i64=0; while i<n { if a[i]!=b[i] { return 0 } i=i+1 } return 1 } 13 14func main() -> i64 { 15 g_puts("nx_vcodec in-loop deblock gate (bit-exact integration + cleaner reference, MEASURED)\n" as *u8) 16 var pass: i64 = 0; var total: i64 = 0 17 let W: i64 = 32; let H: i64 = 32; let N: i64 = W*H 18 let QP: i64 = 36; let SAD_THRESH: i64 = 0; let BS: i64 = 3 // high QP -> blocking; thresh 0 -> residual is always 19 // coded (never skipped), so the REFERENCE quality drives the bits 20 21 let f0: *u8 = sys_mmap(N) as *u8 22 let f1: *u8 = sys_mmap(N) as *u8 23 let dummy: *u8 = sys_mmap(N) as *u8 24 let eR0: *u8 = sys_mmap(N) as *u8 25 let dR0: *u8 = sys_mmap(N) as *u8 26 let eR1: *u8 = sys_mmap(N) as *u8 27 let dR1: *u8 = sys_mmap(N) as *u8 28 let stream: *u8 = sys_mmap(8192) as *u8 29 let blk: *i64 = sys_mmap(16*8) as *i64 30 let mv: *i64 = sys_mmap(2*8) as *i64 31 let line: *i64 = sys_mmap(8*8) as *i64 32 let eR0raw: *u8 = sys_mmap(N) as *u8 33 34 // smooth gradient (blocks at high QP) + f1 = f0 shifted 1px right (integer motion the codec will track) 35 var y: i64 = 0 36 while y < H { var x: i64 = 0 37 while x < W { f0[y*W+x] = (50 + 3*x + 2*y) as u8; x = x + 1 } y = y + 1 } 38 y = 0 39 while y < H { var x: i64 = 0 40 while x < W { f1[y*W+x] = f0[y*W+x]; x = x + 1 } y = y + 1 } // static next frame: residual = pure reference error 41 42 // ---- Path A: RAW reference (no in-loop deblock) ---- 43 vc_enc_frame_packed(f0, dummy, eR0, W, H, QP, 1, SAD_THRESH, stream, blk, mv) 44 vc_dec_frame_packed(dummy, dR0, W, H, QP, stream, blk, mv) 45 let bitsA: i64 = vc_enc_frame_packed(f1, eR0, eR1, W, H, QP, 0, SAD_THRESH, stream, blk, mv) 46 vc_dec_frame_packed(dR0, dR1, W, H, QP, stream, blk, mv) 47 let eqA: i64 = frame_equal(eR1, dR1, N) 48 let streamA: i64 = (bitsA + 7) / 8 49 50 // ---- Path B: DEBLOCKED reference (both sides deblock identically -> stays bit-exact) ---- 51 vc_enc_frame_packed(f0, dummy, eR0, W, H, QP, 1, SAD_THRESH, stream, blk, mv) 52 vc_dec_frame_packed(dummy, dR0, W, H, QP, stream, blk, mv) 53 var ci: i64 = 0; while ci < N { eR0raw[ci] = eR0[ci]; ci = ci + 1 } // snapshot the raw reference before deblocking 54 vc_deblock_frame(eR0, W, H, QP, BS, line) 55 vc_deblock_frame(dR0, W, H, QP, BS, line) 56 let psnr_raw: i64 = qm_psnr_cdb(eR0raw, f0, N) 57 let psnr_deblk: i64 = qm_psnr_cdb(eR0, f0, N) 58 let bitsB: i64 = vc_enc_frame_packed(f1, eR0, eR1, W, H, QP, 0, SAD_THRESH, stream, blk, mv) 59 vc_dec_frame_packed(dR0, dR1, W, H, QP, stream, blk, mv) 60 let eqB: i64 = frame_equal(eR1, dR1, N) 61 let streamB: i64 = (bitsB + 7) / 8 62 63 g_puts(" [measure] reference quality vs true signal: RAW=" as *u8); g_pn(psnr_raw/100); g_puts("." as *u8); g_pn(psnr_raw%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) 64 g_puts(" [measure] next-frame stream: RAW-ref=" as *u8); g_pn(streamA); g_puts(" B DEBLOCKED-ref=" as *u8); g_pn(streamB); g_puts(" B (HONEST: single-pair compression effect is content-dependent; neutral on sub-deadzone residuals -- the bitrate win accrues over long detailed sequences)\n" as *u8) 65 66 pass = pass + g_check("RAW-reference path is bit-exact (decoder == encoder)" as *u8, eqA); total=total+1 67 pass = pass + g_check("in-loop deblock stays bit-exact (both sides deblock -> references in sync)" as *u8, eqB); total=total+1 68 pass = pass + g_check("deblocked reference is a cleaner reference (higher PSNR vs the true signal)" as *u8, psnr_deblk > psnr_raw); total=total+1 69 70 g_puts("---- vcodec in-loop gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 71 if pass == total { g_puts("verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 72 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 73}