nx_vid_dur_gate.nx source
↩ module page · 88 lines · 6234 B
1// nx_vid_dur_gate.nx -- SOVEREIGN gate for the container-duration parsers (vd_mp4_dur / vd_mkv_dur / vd_sniff).
2// Crafts minimal mp4 + mkv byte fixtures with KNOWN durations and asserts the parsers recover them. No files,
3// no external tools -- pure in-memory byte parsing. license_tier: ORIGINAL
4import "nx_syscalls.nx"
5import "nx_vid_dur_lib.nx"
6
7func g_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
8func g_n(v: i64) -> i64 {
9 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
10 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 }
11 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
12 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0
13}
14func g_eq(label: *u8, got: i64, want: i64, pass: *i64, fail: *i64) -> i64 {
15 if got == want { pass[0] = pass[0] + 1; g_p(" ok " as *u8); g_p(label); g_p("\n" as *u8) }
16 else { fail[0] = fail[0] + 1; g_p(" FAIL " as *u8); g_p(label); g_p(" got=" as *u8); g_n(got); g_p(" want=" as *u8); g_n(want); g_p("\n" as *u8) }
17 return 0
18}
19func g_str(buf: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { buf[off + i] = s[i]; i = i + 1 } return off + i }
20
21func main(argc: i64, argv: *i64) -> i64 {
22 let pass: *i64 = sys_mmap(16) as *i64; pass[0] = 0
23 let fail: *i64 = sys_mmap(16) as *i64; fail[0] = 0
24
25 // ---- MP4 fixture: "ftypisom" + "mvhd" + v0(timescale=1000, duration=120000) -> 120000 ms ----
26 let mp4: *u8 = sys_mmap(128)
27 var o: i64 = g_str(mp4, 0, "ftypisommvhd" as *u8) // ftyp (sniff) + mvhd at offset 8
28 // version(1)+flags(3) = 0
29 mp4[o]=0 as u8; mp4[o+1]=0 as u8; mp4[o+2]=0 as u8; mp4[o+3]=0 as u8; o=o+4
30 // creation(4)+modification(4) = 0
31 var z: i64 = 0; while z < 8 { mp4[o]=0 as u8; o=o+1; z=z+1 }
32 // timescale = 1000 = 00 00 03 E8
33 mp4[o]=0 as u8; mp4[o+1]=0 as u8; mp4[o+2]=0x03 as u8; mp4[o+3]=0xE8 as u8; o=o+4
34 // duration = 120000 = 00 01 D4 C0
35 mp4[o]=0 as u8; mp4[o+1]=0x01 as u8; mp4[o+2]=0xD4 as u8; mp4[o+3]=0xC0 as u8; o=o+4
36 g_eq("mp4 sniff=1" as *u8, vd_sniff(mp4, o), 1, pass, fail)
37 g_eq("mp4 dur=120000" as *u8, vd_mp4_dur(mp4, o), 120000, pass, fail)
38
39 // second mp4: timescale=600, duration=27000 -> 27000*1000/600 = 45000 ms (proves not hardcoded)
40 let mp4b: *u8 = sys_mmap(128)
41 var ob: i64 = g_str(mp4b, 0, "moovmvhd" as *u8)
42 mp4b[ob]=0 as u8; mp4b[ob+1]=0 as u8; mp4b[ob+2]=0 as u8; mp4b[ob+3]=0 as u8; ob=ob+4
43 var z2: i64 = 0; while z2 < 8 { mp4b[ob]=0 as u8; ob=ob+1; z2=z2+1 }
44 mp4b[ob]=0 as u8; mp4b[ob+1]=0 as u8; mp4b[ob+2]=0x02 as u8; mp4b[ob+3]=0x58 as u8; ob=ob+4 // 600
45 mp4b[ob]=0 as u8; mp4b[ob+1]=0 as u8; mp4b[ob+2]=0x69 as u8; mp4b[ob+3]=0x78 as u8; ob=ob+4 // 27000
46 g_eq("mp4b dur=45000" as *u8, vd_mp4_dur(mp4b, ob), 45000, pass, fail)
47
48 // ---- MKV fixture: EBML magic + TimecodeScale(1000000) + Duration(double 120000.0) -> 120000 ms ----
49 let mkv: *u8 = sys_mmap(128); var mo: i64 = 0
50 mkv[mo]=0x1A as u8; mkv[mo+1]=0x45 as u8; mkv[mo+2]=0xDF as u8; mkv[mo+3]=0xA3 as u8; mo=mo+4 // EBML magic
51 mkv[mo]=0x2A as u8; mkv[mo+1]=0xD7 as u8; mkv[mo+2]=0xB1 as u8; mkv[mo+3]=0x83 as u8; mo=mo+4 // TimecodeScale id + size=3
52 mkv[mo]=0x0F as u8; mkv[mo+1]=0x42 as u8; mkv[mo+2]=0x40 as u8; mo=mo+3 // 1000000
53 mkv[mo]=0x44 as u8; mkv[mo+1]=0x89 as u8; mkv[mo+2]=0x88 as u8; mo=mo+3 // Duration id + size=8
54 mkv[mo]=0x40 as u8; mkv[mo+1]=0xFD as u8; mkv[mo+2]=0x4C as u8; mkv[mo+3]=0 as u8 // double 120000.0
55 mkv[mo+4]=0 as u8; mkv[mo+5]=0 as u8; mkv[mo+6]=0 as u8; mkv[mo+7]=0 as u8; mo=mo+8
56 g_eq("mkv sniff=2" as *u8, vd_sniff(mkv, mo), 2, pass, fail)
57 g_eq("mkv dur=120000" as *u8, vd_mkv_dur(mkv, mo), 120000, pass, fail)
58
59 // sanity: the IEEE decoders on a known small value (45000.0 double = 40 E5 F9 00 00 00 00 00)
60 let f: *u8 = sys_mmap(16)
61 f[0]=0x40 as u8; f[1]=0xE5 as u8; f[2]=0xF9 as u8; f[3]=0 as u8; f[4]=0 as u8; f[5]=0 as u8; f[6]=0 as u8; f[7]=0 as u8
62 g_eq("ieee64 45000.0" as *u8, vd_ieee64(f, 0), 45000, pass, fail)
63
64 // ---- >24h REJECT GUARD: a false 4-byte "mvhd" / 3-byte "44 89 8x" match in a multi-MB window decodes
65 // garbage into a huge duration. A real recording is never >24h, so the parsers must return -1, not a bogus
66 // runtime that sorts/badges as the "longest" video. mp4: timescale=1000, duration=90000000 -> 25h.
67 let mp4c: *u8 = sys_mmap(128)
68 var oc: i64 = g_str(mp4c, 0, "moovmvhd" as *u8)
69 mp4c[oc]=0 as u8; mp4c[oc+1]=0 as u8; mp4c[oc+2]=0 as u8; mp4c[oc+3]=0 as u8; oc=oc+4
70 var z3: i64 = 0; while z3 < 8 { mp4c[oc]=0 as u8; oc=oc+1; z3=z3+1 }
71 mp4c[oc]=0 as u8; mp4c[oc+1]=0 as u8; mp4c[oc+2]=0x03 as u8; mp4c[oc+3]=0xE8 as u8; oc=oc+4 // 1000
72 mp4c[oc]=0x05 as u8; mp4c[oc+1]=0x5D as u8; mp4c[oc+2]=0x4A as u8; mp4c[oc+3]=0x80 as u8; oc=oc+4 // 90000000
73 g_eq("mp4 >24h rejected=-1" as *u8, vd_mp4_dur(mp4c, oc), 0-1, pass, fail)
74
75 // mkv: TimecodeScale=1000000, Duration=double 90000000.0 (41 95 75 2A 00 00 00 00) -> 25h.
76 let mkv2: *u8 = sys_mmap(128); var m2: i64 = 0
77 mkv2[m2]=0x1A as u8; mkv2[m2+1]=0x45 as u8; mkv2[m2+2]=0xDF as u8; mkv2[m2+3]=0xA3 as u8; m2=m2+4
78 mkv2[m2]=0x2A as u8; mkv2[m2+1]=0xD7 as u8; mkv2[m2+2]=0xB1 as u8; mkv2[m2+3]=0x83 as u8; m2=m2+4
79 mkv2[m2]=0x0F as u8; mkv2[m2+1]=0x42 as u8; mkv2[m2+2]=0x40 as u8; m2=m2+3 // 1000000
80 mkv2[m2]=0x44 as u8; mkv2[m2+1]=0x89 as u8; mkv2[m2+2]=0x88 as u8; m2=m2+3 // Duration size=8
81 mkv2[m2]=0x41 as u8; mkv2[m2+1]=0x95 as u8; mkv2[m2+2]=0x75 as u8; mkv2[m2+3]=0x2A as u8 // double 90000000.0
82 mkv2[m2+4]=0 as u8; mkv2[m2+5]=0 as u8; mkv2[m2+6]=0 as u8; mkv2[m2+7]=0 as u8; m2=m2+8
83 g_eq("mkv >24h rejected=-1" as *u8, vd_mkv_dur(mkv2, m2), 0-1, pass, fail)
84
85 g_p("\nvid_dur gate pass=" as *u8); g_n(pass[0]); g_p(" fail=" as *u8); g_n(fail[0]); g_p("\n" as *u8)
86 if fail[0] == 0 { g_p("GREEN\n" as *u8); sys_exit(0) } else { g_p("RED\n" as *u8); sys_exit(1) }
87 return 0
88}