code wiki / (root) / nx_video_frame.nx

nx_video_frame.nx source

↩ module page · 133 lines · 4466 B

1// nx_video_frame.nx -- wire frame format for Nishi sovereign video. 2// 3// Magic "NXVD" (Nishi Video), hash-chained header just like 4// nx_voice_frame. Carries one I-frame as a sequence of 8x8 DCT 5// blocks. Future P-frame support will reuse the same envelope with 6// a different flag. 7// 8// Wire layout (little-endian): 9// [0..3] magic "NXVD" 10// [4] version major (1) 11// [5] tier hint (NX_HW_TIER_*) 12// [6..7] width_blocks (each block is 8 pixels) 13// [8..9] height_blocks 14// [10] frame_kind (1 = I-frame; 2 = P-frame queued) 15// [11] quant_step (1..64; per-frame uniform quantisation) 16// [12..15] sequence 17// [16..47] prev_frame_hash (32 bytes; FNV 4-lane shared with voice) 18// [48..49] payload_bytes (= width_blocks * height_blocks * 64 * 2) 19// [50..] payload: per block, 64 quantised coefficients as int16 LE 20// 21// Per-frame size for a 16x16 I-frame (2x2 blocks of 8x8): 22// header 50 + payload 4 * 64 * 2 = 50 + 512 = 562 bytes. 23// At 30 fps that's 16.86 kbps for 16x16 -- proof of concept. 24// 25// genealogy_id: nx_voice_frame_q10 + jpeg_iso_10918 + h264_iso_14496_10 + 26// nx_dct8_q10 27// lineage_id: nishi_video_frame_q10 28 29// nx_safety_envelope: 30// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 31// sil_target: SIL1 32// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 33// verdict: NOT_YET_EVALUATED 34 35import "nx_syscalls.nx" 36 37// Sealed verdict. 38const NX_VID_VERDICT_UNKNOWN: i64 = 0 39const NX_VID_VERDICT_OK: i64 = 1 40const NX_VID_VERDICT_BAD_MAGIC: i64 = 2 41const NX_VID_VERDICT_VERSION_MISMATCH: i64 = 3 42const NX_VID_VERDICT_TRUNCATED: i64 = 4 43const NX_VID_VERDICT_CHAIN_BROKEN: i64 = 5 44const NX_VID_VERDICT_BAD_PARAMS: i64 = 6 45const NX_VID_VERDICT_N: i64 = 7 46 47const NX_VID_KIND_I: i64 = 1 48const NX_VID_KIND_P: i64 = 2 49 50const NX_VID_HEADER_BYTES: i64 = 50 51 52func nx_vid_build_header( 53 out: *u8, out_cap: i64, 54 tier: i64, 55 width_blocks: i64, height_blocks: i64, 56 frame_kind: i64, 57 quant_step: i64, 58 sequence: i64, 59 prev_hash: *u8, 60 payload_bytes: i64 61) -> i64 { 62 if out_cap < NX_VID_HEADER_BYTES + payload_bytes { return -1 } 63 if width_blocks < 1 { return -1 } 64 if height_blocks < 1 { return -1 } 65 if quant_step < 1 { return -1 } 66 if quant_step > 255 { return -1 } 67 68 out[0]=78; out[1]=88; out[2]=86; out[3]=68 // "NXVD" 69 out[4]=1 70 out[5]=tier & 0xff 71 out[6]=width_blocks & 0xff 72 out[7]=(width_blocks >> 8) & 0xff 73 out[8]=height_blocks & 0xff 74 out[9]=(height_blocks >> 8) & 0xff 75 out[10]=frame_kind & 0xff 76 out[11]=quant_step & 0xff 77 out[12]=sequence & 0xff 78 out[13]=(sequence >> 8) & 0xff 79 out[14]=(sequence >> 16) & 0xff 80 out[15]=(sequence >> 24) & 0xff 81 var i: i64 = 0 82 while i < 32 { 83 out[16 + i] = prev_hash[i] 84 i = i + 1 85 } 86 out[48] = payload_bytes & 0xff 87 out[49] = (payload_bytes >> 8) & 0xff 88 return NX_VID_HEADER_BYTES 89} 90 91func nx_vid_parse_header( 92 buf: *u8, buf_len: i64, 93 expected_prev_hash: *u8, 94 out_width_blocks: *i64, out_height_blocks: *i64, 95 out_frame_kind: *i64, out_quant: *i64, out_sequence: *i64, 96 out_payload_off: *i64, out_payload_len: *i64 97) -> i64 { 98 if buf_len < NX_VID_HEADER_BYTES { return NX_VID_VERDICT_TRUNCATED } 99 if buf[0] != 78 { return NX_VID_VERDICT_BAD_MAGIC } 100 if buf[1] != 88 { return NX_VID_VERDICT_BAD_MAGIC } 101 if buf[2] != 86 { return NX_VID_VERDICT_BAD_MAGIC } 102 if buf[3] != 68 { return NX_VID_VERDICT_BAD_MAGIC } 103 if buf[4] != 1 { return NX_VID_VERDICT_VERSION_MISMATCH } 104 105 *out_width_blocks = buf[6] | (buf[7] << 8) 106 *out_height_blocks = buf[8] | (buf[9] << 8) 107 *out_frame_kind = buf[10] 108 *out_quant = buf[11] 109 *out_sequence = buf[12] | (buf[13] << 8) | (buf[14] << 16) | (buf[15] << 24) 110 111 let plen: i64 = buf[48] | (buf[49] << 8) 112 if NX_VID_HEADER_BYTES + plen > buf_len { return NX_VID_VERDICT_TRUNCATED } 113 114 if (expected_prev_hash as i64) != 0 { 115 var i: i64 = 0 116 var bad: i64 = 0 117 while i < 32 { 118 if buf[16 + i] != expected_prev_hash[i] { bad = 1 } 119 i = i + 1 120 } 121 if bad == 1 { return NX_VID_VERDICT_CHAIN_BROKEN } 122 } 123 124 *out_payload_off = NX_VID_HEADER_BYTES 125 *out_payload_len = plen 126 return NX_VID_VERDICT_OK 127} 128 129func nx_vid_verdict_is_valid(v: i64) -> i64 { 130 if v < 0 { return 0 } 131 if v >= NX_VID_VERDICT_N { return 0 } 132 return 1 133}