nx_uxf_mp4box_test.nx source
↩ module page · 123 lines · 6468 B
1// nx_uxf_mp4box_test.nx -- UXF arc #2 (real remux), rung 1: the ISO-BMFF (MP4) container BOX
2// primitive -- the OUTPUT side of an MKV->MP4 remux. An MP4 is a tree of boxes:
3// [u32be size (incl. 8-byte header)][4cc type][payload | child boxes].
4// This builds a real box WRITER (begin/end with size back-patching) + a box PARSER (walk), then
5// KAT-proves: a built ftyp + moov{mvhd} tree has correct sizes, parses back to the right types,
6// nests correctly, and a corrupted size is DETECTED (neg-control).
7//
8// HONEST SCOPE: this is the container-construction primitive (the foundation for "rewrap into MP4").
9// It does NOT yet emit a *playable* MP4 (needs populated sample tables stsd/stts/stsc/stsz/stco) nor
10// parse MKV/EBML (the input side) -- those are the named downstream rungs of #2.
11// No hardware writes (Rule 26). expect_exit: 0 license_tier: ORIGINAL
12import "nx_syscalls.nx"
13
14func m_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
15func m_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 }
16
17func mp4_w32(out: *u8, off: i64, v: i64) -> i64 {
18 out[off] = ((v >> 24) & 0xff) as u8
19 out[off + 1] = ((v >> 16) & 0xff) as u8
20 out[off + 2] = ((v >> 8) & 0xff) as u8
21 out[off + 3] = (v & 0xff) as u8
22 return off + 4
23}
24func mp4_r32(buf: *u8, off: i64) -> i64 {
25 return ((buf[off] as i64) * 16777216) + ((buf[off + 1] as i64) * 65536) + ((buf[off + 2] as i64) * 256) + (buf[off + 3] as i64)
26}
27func mp4_4cc(out: *u8, off: i64, a: i64, b: i64, c: i64, d: i64) -> i64 {
28 out[off] = a as u8; out[off + 1] = b as u8; out[off + 2] = c as u8; out[off + 3] = d as u8
29 return off + 4
30}
31func mp4_type_is(buf: *u8, off: i64, a: i64, b: i64, c: i64, d: i64) -> i64 {
32 if buf[off] != (a as u8) { return 0 }
33 if buf[off + 1] != (b as u8) { return 0 }
34 if buf[off + 2] != (c as u8) { return 0 }
35 if buf[off + 3] != (d as u8) { return 0 }
36 return 1
37}
38// open a box: placeholder size + 4cc type; returns the offset AFTER the 8-byte header.
39func mp4_box_begin(out: *u8, off: i64, a: i64, b: i64, c: i64, d: i64) -> i64 {
40 mp4_w32(out, off, 0)
41 mp4_4cc(out, off + 4, a, b, c, d)
42 return off + 8
43}
44// close a box opened at `start`: back-patch its size = (curoff - start).
45func mp4_box_end(out: *u8, start: i64, curoff: i64) -> i64 {
46 mp4_w32(out, start, curoff - start)
47 return curoff
48}
49
50// walk top-level boxes [0..n): set count, and aligned=1 iff sizes land exactly on n.
51func mp4_walk(buf: *u8, n: i64, out_first_off: *i64, out_count: *i64) -> i64 {
52 var off: i64 = 0
53 var c: i64 = 0
54 out_first_off[0] = 0 - 1
55 while (off + 8) <= n {
56 let sz: i64 = mp4_r32(buf, off)
57 if sz < 8 { out_count[0] = c; return 0 } // invalid box -> not aligned
58 if c == 0 { out_first_off[0] = off }
59 off = off + sz
60 c = c + 1
61 }
62 out_count[0] = c
63 if off == n { return 1 }
64 return 0
65}
66
67func main() -> i64 {
68 m_puts("#2 rung-1 ISO-BMFF (MP4) BOX PRIMITIVE -- container build + parse + verify\n" as *u8)
69 let out: *u8 = sys_mmap(65536)
70 var off: i64 = 0
71
72 // ftyp box: major 'isom', minor 0x200, compat 'isom','mp41'
73 let ftyp: i64 = off
74 off = mp4_box_begin(out, off, 102, 116, 121, 112) // 'ftyp'
75 off = mp4_4cc(out, off, 105, 115, 111, 109) // 'isom'
76 off = mp4_w32(out, off, 512) // minor 0x200
77 off = mp4_4cc(out, off, 105, 115, 111, 109) // 'isom'
78 off = mp4_4cc(out, off, 109, 112, 52, 49) // 'mp41'
79 off = mp4_box_end(out, ftyp, off)
80 let ftyp_size: i64 = off - ftyp
81
82 // moov { mvhd[100 zero bytes] }
83 let moov: i64 = off
84 off = mp4_box_begin(out, off, 109, 111, 111, 118) // 'moov'
85 let mvhd: i64 = off
86 off = mp4_box_begin(out, off, 109, 118, 104, 100) // 'mvhd'
87 var z: i64 = 0
88 while z < 100 { out[off] = 0 as u8; off = off + 1; z = z + 1 }
89 off = mp4_box_end(out, mvhd, off)
90 off = mp4_box_end(out, moov, off)
91 let total: i64 = off
92
93 m_puts(" built ftyp_size=" as *u8); m_putn(ftyp_size); m_puts(" total_bytes=" as *u8); m_putn(total); m_puts("\n" as *u8)
94
95 let fo: *i64 = sys_mmap(8) as *i64
96 let cc: *i64 = sys_mmap(8) as *i64
97 let aligned: i64 = mp4_walk(out, total, fo, cc)
98
99 var pass: i64 = 0
100 var ttl: i64 = 0
101
102 // T1: ftyp size is exactly 8 header + 16 payload = 24
103 ttl = ttl + 1; m_puts(" T1 ftyp_size==24: " as *u8); if ftyp_size == 24 { pass = pass + 1; m_puts("PASS\n" as *u8) } else { m_puts("FAIL\n" as *u8) }
104 // T2: top-level walk is size-aligned AND has exactly 2 boxes
105 ttl = ttl + 1; m_puts(" T2 walk aligned + 2 boxes (aligned=" as *u8); m_putn(aligned); m_puts(" count=" as *u8); m_putn(cc[0]); m_puts("): " as *u8)
106 if aligned == 1 { if cc[0] == 2 { pass = pass + 1; m_puts("PASS\n" as *u8) } else { m_puts("FAIL\n" as *u8) } } else { m_puts("FAIL\n" as *u8) }
107 // T3: box0 type=='ftyp' and box1 (at ftyp_size) type=='moov' whose first child=='mvhd'
108 ttl = ttl + 1; m_puts(" T3 types ftyp/moov/mvhd nested: " as *u8)
109 var t3: i64 = 0
110 if mp4_type_is(out, 4, 102, 116, 121, 112) == 1 { if mp4_type_is(out, ftyp_size + 4, 109, 111, 111, 118) == 1 { if mp4_type_is(out, ftyp_size + 12, 109, 118, 104, 100) == 1 { t3 = 1 } } }
111 if t3 == 1 { pass = pass + 1; m_puts("PASS\n" as *u8) } else { m_puts("FAIL\n" as *u8) }
112 // T4 neg-control: corrupt ftyp size -> walk must NOT be aligned
113 ttl = ttl + 1
114 mp4_w32(out, 0, 23) // was 24
115 let aligned2: i64 = mp4_walk(out, total, fo, cc)
116 m_puts(" T4 neg corrupt-size detected (aligned2=" as *u8); m_putn(aligned2); m_puts("): " as *u8)
117 if aligned2 == 0 { pass = pass + 1; m_puts("PASS\n" as *u8) } else { m_puts("FAIL\n" as *u8) }
118 mp4_w32(out, 0, 24) // restore
119
120 m_puts("UXF-MP4BOX-GATE passed " as *u8); m_putn(pass); m_puts("/" as *u8); m_putn(ttl)
121 if pass == ttl { m_puts(" verdict=GREEN (MP4 container primitive; sample-tables + MKV-parse = downstream)\n" as *u8); sys_exit(0); return 0 }
122 m_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1
123}