nx_mp4_real_probe.nx source
↩ module page · 79 lines · 3880 B
1// nx_mp4_real_probe.nx -- run the whole H.264 front-end on a REAL recording.
2// Reads knowledge/staging/media/realtest.mp4, demuxes tracks (incl. audio
3// presence -> the audio-drop signal), identifies the codec, finds the avcC
4// config record, extracts the real SPS NAL, de-emulates + parses it -> the
5// real profile/level/resolution decoded straight from the bitstream.
6// First time the front-end runs on real data instead of synthesized boxes.
7// license_tier: ORIGINAL
8import "nx_syscalls.nx"
9import "nx_mp4_demux.nx"
10import "nx_mp4_stbl.nx"
11import "nx_h264_bits.nx"
12import "nx_h264_sps.nx"
13
14func gp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
15func gn(v: i64) -> i64 {
16 let bb: *u8 = sys_mmap(28)
17 var m: i64 = v
18 if m < 0 { sys_write(1, "-\x00" as *u8, 1); m = 0 - m }
19 let t: *u8 = sys_mmap(28)
20 var k: i64 = 0
21 if m == 0 { t[0] = 48 as u8; k = 1 }
22 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
23 var i: i64 = 0
24 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
25 sys_write(1, bb, k)
26 return 0
27}
28// scan [start,end) for a 4-char box tag; return box start (tag-4) or -1
29func find_tag(b: *u8, start: i64, end: i64, s: *u8) -> i64 {
30 var i: i64 = start
31 while i + 4 <= end {
32 if mp4_t4(b, i, s) == 1 { return i - 4 }
33 i = i + 1
34 }
35 return 0 - 1
36}
37
38func main() -> i64 {
39 let szp: *i64 = sys_mmap(16) as *i64
40 let b: *u8 = sys_read_file("knowledge/staging/media/realtest.mp4\x00" as *u8, szp)
41 if (b as i64) == 0 { gp("real_probe: no realtest.mp4\n\x00" as *u8); return 1 }
42 let len: i64 = szp[0]
43 gp("REAL-PROBE file bytes=\x00" as *u8); gn(len); gp("\n\x00" as *u8)
44
45 let dm: *i64 = sys_mmap(64) as *i64
46 nx_mp4_demux(b, len, dm)
47 gp(" demux: tracks=\x00" as *u8); gn(dm[0]); gp(" video=\x00" as *u8); gn(dm[1]); gp(" audio=\x00" as *u8); gn(dm[2])
48 gp(" ftyp=\x00" as *u8); gn(dm[3]); gp(" moov=\x00" as *u8); gn(dm[4]); gp("\n\x00" as *u8)
49
50 let vi: *i64 = sys_mmap(64) as *i64
51 let f: i64 = nx_mp4_video_info(b, len, vi)
52 gp(" video_info: found=\x00" as *u8); gn(f); gp(" codec=\x00" as *u8); gn(vi[0]); gp(" (1=H264 2=H265 3=VP9 5=AAC) frames=\x00" as *u8); gn(vi[1]); gp("\n\x00" as *u8)
53
54 // extract SPS from avcC config record
55 let avcc: i64 = find_tag(b, 0, len, "avcC\x00" as *u8)
56 if avcc < 0 { gp(" avcC: not found (no SPS to parse)\n\x00" as *u8); return 0 }
57 let pay: i64 = avcc + 8
58 let cfgver: i64 = b[pay + 0] as i64
59 let prof: i64 = b[pay + 1] as i64
60 let levl: i64 = b[pay + 3] as i64
61 let lensz: i64 = ((b[pay + 4] as i64) & 3) + 1
62 let nsps: i64 = (b[pay + 5] as i64) & 31
63 let spslen: i64 = (b[pay + 6] as i64) * 256 + (b[pay + 7] as i64)
64 gp(" avcC@\x00" as *u8); gn(avcc); gp(" ver=\x00" as *u8); gn(cfgver); gp(" prof=\x00" as *u8); gn(prof); gp(" level=\x00" as *u8); gn(levl)
65 gp(" nal_len_size=\x00" as *u8); gn(lensz); gp(" nSPS=\x00" as *u8); gn(nsps); gp(" spsLen=\x00" as *u8); gn(spslen); gp("\n\x00" as *u8)
66
67 // SPS NAL starts at pay+8 (byte 0 = 0x67 header); RBSP = after header byte
68 let sps_nal: i64 = pay + 8
69 let nal_hdr: i64 = b[sps_nal] as i64
70 let rbsp_src: *u8 = (b as i64 + sps_nal + 1) as *u8
71 let dst: *u8 = sys_mmap(spslen + 16)
72 let rbsp_len: i64 = nx_h264_unescape_rbsp(rbsp_src, spslen - 1, dst)
73 let out: *i64 = sys_mmap(64) as *i64
74 nx_h264_parse_sps(dst, rbsp_len, out)
75 gp(" SPS nal_hdr=0x\x00" as *u8); gn(nal_hdr); gp(" -> profile=\x00" as *u8); gn(out[0]); gp(" level=\x00" as *u8); gn(out[1])
76 gp(" RESOLUTION=\x00" as *u8); gn(out[2]); gp("x\x00" as *u8); gn(out[3])
77 gp(" (mbs \x00" as *u8); gn(out[4] + 1); gp("x\x00" as *u8); gn(out[5] + 1); gp(" frame_mbs_only=\x00" as *u8); gn(out[6]); gp(" chroma=\x00" as *u8); gn(out[7]); gp(")\n\x00" as *u8)
78 return 0
79}