code wiki / (root) / nx_uxf_ebml_test.nx

nx_uxf_ebml_test.nx source

↩ module page · 98 lines · 5253 B

1// nx_uxf_ebml_test.nx -- UXF arc #2 (real remux), rung 2: the EBML/Matroska parser primitive -- 2// the INPUT side of an MKV->MP4 remux. MKV is an EBML document: a tree of elements 3// [element-ID (vint, marker KEPT)][size (vint, marker STRIPPED)][data]. 4// A vint's first byte encodes its length: leading-zero count + 1 (the first 1-bit is the marker). 5// This builds vint length + ID read + size read, and KAT-proves them on the real EBML magic header 6// (0x1A45DFA3) + a size vint, plus a malformed-vint neg-control. 7// 8// HONEST SCOPE: this is the EBML element primitive (read IDs/sizes -> walk MKV structure). Mapping 9// MKV tracks/codec-private/SimpleBlock frames into MP4 sample tables (the actual rewrap) is the next 10// rung. No hardware writes (Rule 26). expect_exit: 0 license_tier: ORIGINAL 11import "nx_syscalls.nx" 12 13func e_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 14func e_putn(v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 } 15 16// vint byte-length from the first byte: leading-zero count + 1; 0 = invalid (no marker bit). 17func ebml_vint_len(b: i64) -> i64 { 18 if b >= 0x80 { return 1 } 19 if b >= 0x40 { return 2 } 20 if b >= 0x20 { return 3 } 21 if b >= 0x10 { return 4 } 22 if b >= 0x08 { return 5 } 23 if b >= 0x04 { return 6 } 24 if b >= 0x02 { return 7 } 25 if b >= 0x01 { return 8 } 26 return 0 27} 28 29// read an element ID at pos (marker bit KEPT = raw big-endian bytes); advance pos; -1 if invalid. 30func ebml_read_id(buf: *u8, pos: *i64) -> i64 { 31 let p: i64 = pos[0] 32 let len: i64 = ebml_vint_len(buf[p] as i64) 33 if len == 0 { return 0 - 1 } 34 var v: i64 = 0 35 var i: i64 = 0 36 while i < len { v = (v * 256) + (buf[p + i] as i64); i = i + 1 } 37 pos[0] = p + len 38 return v 39} 40 41// read a size at pos (marker bit STRIPPED from the first byte); advance pos; -1 if invalid. 42func ebml_read_size(buf: *u8, pos: *i64) -> i64 { 43 let p: i64 = pos[0] 44 let len: i64 = ebml_vint_len(buf[p] as i64) 45 if len == 0 { return 0 - 1 } 46 var v: i64 = (buf[p] as i64) & (255 >> len) 47 var i: i64 = 1 48 while i < len { v = (v * 256) + (buf[p + i] as i64); i = i + 1 } 49 pos[0] = p + len 50 return v 51} 52 53func main() -> i64 { 54 e_puts("#2 rung-2 EBML/MKV PARSER PRIMITIVE -- vint + element ID/size, KAT on real EBML header\n" as *u8) 55 // EBML magic ID 0x1A45DFA3 | size vint 0x84 (=4) | 4 data bytes 56 let buf: *u8 = sys_mmap(64) 57 buf[0] = 0x1A as u8; buf[1] = 0x45 as u8; buf[2] = 0xDF as u8; buf[3] = 0xA3 as u8 58 buf[4] = 0x84 as u8 59 buf[5] = 0xDE as u8; buf[6] = 0xAD as u8; buf[7] = 0xBE as u8; buf[8] = 0xEF as u8 60 61 var pass: i64 = 0 62 var ttl: i64 = 0 63 64 // T1: vint length of 0x1A is 4 (the EBML magic is a 4-byte vint) 65 ttl = ttl + 1; e_puts(" T1 vint_len(0x1A)==4: " as *u8); if ebml_vint_len(0x1A) == 4 { pass = pass + 1; e_puts("PASS\n" as *u8) } else { e_puts("FAIL\n" as *u8) } 66 67 // T2: read the EBML magic ID (marker kept) == 0x1A45DFA3 (=440786851); pos advances to 4 68 let pos: *i64 = sys_mmap(8) as *i64 69 pos[0] = 0 70 let id: i64 = ebml_read_id(buf, pos) 71 ttl = ttl + 1; e_puts(" T2 read_id==0x1A45DFA3 (got " as *u8); e_putn(id); e_puts(" pos=" as *u8); e_putn(pos[0]); e_puts("): " as *u8) 72 if id == 440786851 { if pos[0] == 4 { pass = pass + 1; e_puts("PASS\n" as *u8) } else { e_puts("FAIL\n" as *u8) } } else { e_puts("FAIL\n" as *u8) } 73 74 // T3: read the size vint (marker stripped) == 4; pos advances to 5 75 let sz: i64 = ebml_read_size(buf, pos) 76 ttl = ttl + 1; e_puts(" T3 read_size==4 (got " as *u8); e_putn(sz); e_puts(" pos=" as *u8); e_putn(pos[0]); e_puts("): " as *u8) 77 if sz == 4 { if pos[0] == 5 { pass = pass + 1; e_puts("PASS\n" as *u8) } else { e_puts("FAIL\n" as *u8) } } else { e_puts("FAIL\n" as *u8) } 78 79 // T4: vint_len across the length classes (1..8) 80 ttl = ttl + 1 81 var ok4: i64 = 1 82 if ebml_vint_len(0x80) != 1 { ok4 = 0 } 83 if ebml_vint_len(0x40) != 2 { ok4 = 0 } 84 if ebml_vint_len(0x20) != 3 { ok4 = 0 } 85 if ebml_vint_len(0x10) != 4 { ok4 = 0 } 86 if ebml_vint_len(0x08) != 5 { ok4 = 0 } 87 if ebml_vint_len(0x04) != 6 { ok4 = 0 } 88 if ebml_vint_len(0x02) != 7 { ok4 = 0 } 89 if ebml_vint_len(0x01) != 8 { ok4 = 0 } 90 e_puts(" T4 vint_len classes 1..8: " as *u8); if ok4 == 1 { pass = pass + 1; e_puts("PASS\n" as *u8) } else { e_puts("FAIL\n" as *u8) } 91 92 // T5 neg-control: a malformed vint (first byte 0x00, no marker) is rejected 93 ttl = ttl + 1; e_puts(" T5 neg vint_len(0x00)==0: " as *u8); if ebml_vint_len(0x00) == 0 { pass = pass + 1; e_puts("PASS\n" as *u8) } else { e_puts("FAIL\n" as *u8) } 94 95 e_puts("UXF-EBML-GATE passed " as *u8); e_putn(pass); e_puts("/" as *u8); e_putn(ttl) 96 if pass == ttl { e_puts(" verdict=GREEN (EBML element primitive; MKV-track->MP4-sample-table = downstream)\n" as *u8); sys_exit(0); return 0 } 97 e_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1 98}