code wiki / (root) / nx_mp4_real_probe.nx

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}