nx_ts_nal_gate.nx source
↩ module page · 177 lines · 8581 B
1// nx_ts_nal_gate.nx -- proof for the HEVC indexing hole (2026-07-31).
2//
3// The load-bearing tests are T7/T8: an HEVC keyframe byte, read through the
4// H.264 mask, classifies as NOT a keyframe. That is exactly what the pre-fix
5// nx_ts_index did to every H.265 recording -- and it is why the failure was
6// silent. It never errored; it just found no keyframes, forever.
7//
8// T11/T12 are the RANGE boundaries. IRAP is 16..23, not a single value, so an
9// off-by-one at either end silently drops real seek points on a CRA-heavy
10// stream while still looking like it works.
11// license_tier: ORIGINAL
12import "nx_ts_nal.nx"
13import "nx_gate.nx"
14import "nx_gate_verdict.nx" // D001: inherit the canonical verdict lib instead of hand-rolling
15
16// Thin wrapper over the BASE CLASS so all 23 call sites stay unchanged: the
17// retrofit changes how checks are counted and emitted, never what they assert.
18// ctr is the gv_ctr() pair -- ctr[0]=pass ctr[1]=total.
19func tg(cond: i64, label: *u8, ctr: *i64, unused: *i64) -> i64 {
20 gv_check(label, cond, ctr)
21 return 0
22}
23
24func main() -> i64 {
25 gw("=== nx_ts_nal_gate: HEVC is different GEOMETRY, not a tuning difference ===\n" as *u8)
26 // gv_ctr() is the base class counter pair: [0]=pass [1]=total. Call sites
27 // still pass (pass, tot); tot is now inert and kept only so the 23 existing
28 // calls need no edit.
29 let pass: *i64 = gv_ctr()
30 let tot: *i64 = sys_mmap(16) as *i64
31
32 // ---- stream_type dispatch ----
33 var c1: i64 = 0
34 if tsn_codec_of_stream_type(0x1b) == TSN_H264 { c1 = 1 }
35 tg(c1, "T1 stream_type 0x1b -> H.264" as *u8, pass, tot)
36
37 var c2: i64 = 0
38 if tsn_codec_of_stream_type(0x24) == TSN_HEVC { c2 = 1 }
39 tg(c2, "T2 stream_type 0x24 -> HEVC (the type that used to be ignored entirely)" as *u8, pass, tot)
40
41 var c3: i64 = 0
42 if tsn_codec_of_stream_type(0x0f) == (0 - 1) { c3 = 1 }
43 tg(c3, "T3 an AUDIO stream_type (0x0f) is NOT claimed as video" as *u8, pass, tot)
44
45 // ---- header geometry ----
46 // H.264 IDR byte 0x65 -> type 5
47 var c4: i64 = 0
48 if tsn_nal_type(0x65, TSN_H264) == 5 { c4 = 1 }
49 tg(c4, "T4 H.264 1-byte header: 0x65 & 0x1f = 5 (IDR)" as *u8, pass, tot)
50
51 // HEVC IDR_W_RADL = 19 -> header byte (19<<1) = 0x26
52 var c5: i64 = 0
53 if tsn_nal_type(0x26, TSN_HEVC) == 19 { c5 = 1 }
54 tg(c5, "T5 HEVC 2-byte header: (0x26 >> 1) & 0x3f = 19 (IDR_W_RADL)" as *u8, pass, tot)
55
56 // ★ THE SAME BYTE, TWO CODECS, TWO ANSWERS -- this is why one mask cannot serve both
57 var c6: i64 = 0
58 if tsn_nal_type(0x26, TSN_H264) != tsn_nal_type(0x26, TSN_HEVC) { c6 = 1 }
59 tg(c6, "T6 TOOTH the SAME byte decodes to a DIFFERENT type per codec" as *u8, pass, tot)
60
61 // ---- keyframe classification ----
62 var c7: i64 = 0
63 if tsn_nal_is_key(tsn_nal_type(0x26, TSN_HEVC), TSN_HEVC) == 1 { c7 = 1 }
64 tg(c7, "T7 an HEVC IDR IS a keyframe when read as HEVC" as *u8, pass, tot)
65
66 // ★★★ THE REGRESSION TOOTH: the pre-fix path in one line.
67 var c8: i64 = 0
68 if tsn_nal_is_key(tsn_nal_type(0x26, TSN_H264), TSN_H264) == 0 { c8 = 1 }
69 tg(c8, "T8 TOOTH the SAME HEVC IDR read as H.264 is NOT a keyframe -- the silent pre-fix bug" as *u8, pass, tot)
70
71 var c9: i64 = 0
72 if tsn_nal_is_key(5, TSN_H264) == 1 { c9 = 1 }
73 tg(c9, "T9 H.264 IDR (5) is a keyframe" as *u8, pass, tot)
74
75 var c10: i64 = 0
76 if tsn_nal_is_key(1, TSN_H264) == 0 { c10 = 1 }
77 tg(c10, "T10 NEG-CONTROL a non-IDR H.264 slice (1) is not a keyframe" as *u8, pass, tot)
78
79 // ---- IRAP is a RANGE: guard BOTH boundaries ----
80 var c11: i64 = 0
81 if tsn_nal_is_key(16, TSN_HEVC) == 1 { if tsn_nal_is_key(23, TSN_HEVC) == 1 { if tsn_nal_is_key(21, TSN_HEVC) == 1 { c11 = 1 } } }
82 tg(c11, "T11 TOOTH the WHOLE IRAP range 16/21/23 counts (BLA, CRA, RSV) -- not just IDR" as *u8, pass, tot)
83
84 var c12: i64 = 0
85 if tsn_nal_is_key(15, TSN_HEVC) == 0 { if tsn_nal_is_key(24, TSN_HEVC) == 0 { c12 = 1 } }
86 tg(c12, "T12 TOOTH just OUTSIDE the range (15 and 24) is NOT a keyframe -- no off-by-one" as *u8, pass, tot)
87
88 // ---- VCL ranges decide where AU scanning stops ----
89 var c13: i64 = 0
90 if tsn_nal_is_vcl(5, TSN_H264) == 1 { if tsn_nal_is_vcl(7, TSN_H264) == 0 { c13 = 1 } }
91 tg(c13, "T13 H.264 VCL = 1..5, so SPS(7) is not VCL" as *u8, pass, tot)
92
93 var c14: i64 = 0
94 if tsn_nal_is_vcl(31, TSN_HEVC) == 1 { if tsn_nal_is_vcl(32, TSN_HEVC) == 0 { c14 = 1 } }
95 tg(c14, "T14 HEVC VCL = 0..31, so VPS(32) is not VCL" as *u8, pass, tot)
96
97 // ---- parameter sets differ, which is why 7/8 must not be hardcoded ----
98 var c15: i64 = 0
99 if tsn_sps_type(TSN_H264) == 7 { if tsn_sps_type(TSN_HEVC) == 33 { c15 = 1 } }
100 tg(c15, "T15 SPS is 7 on H.264 but 33 on HEVC" as *u8, pass, tot)
101
102 var c16: i64 = 0
103 if tsn_pps_type(TSN_H264) == 8 { if tsn_pps_type(TSN_HEVC) == 34 { c16 = 1 } }
104 tg(c16, "T16 PPS is 8 on H.264 but 34 on HEVC" as *u8, pass, tot)
105
106 // ---- hvcC construction (what HEVC fMP4 playback needs) ----
107 // synthetic SPS: 2-byte NAL header (type 33), then the ids byte, then the
108 // 12 profile_tier_level bytes with RECOGNISABLE values so a byte-exact copy
109 // is provable rather than merely plausible.
110 let sps: *u8 = sys_mmap(64)
111 sps[0] = 0x42 as u8; sps[1] = 0x01 as u8 // nal type 33 << 1
112 sps[2] = 0x01 as u8 // max_sub_layers_minus1 = 0
113 sps[3] = 0x21 as u8 // profile_space/tier/idc
114 sps[4] = 0xa1 as u8; sps[5] = 0xa2 as u8; sps[6] = 0xa3 as u8; sps[7] = 0xa4 as u8
115 sps[8] = 0xb1 as u8; sps[9] = 0xb2 as u8; sps[10] = 0xb3 as u8
116 sps[11] = 0xb4 as u8; sps[12] = 0xb5 as u8; sps[13] = 0xb6 as u8
117 sps[14] = 0x5a as u8 // level_idc
118 sps[15] = 0x00 as u8
119 let vps: *u8 = sys_mmap(32); vps[0] = 0x40 as u8; vps[1] = 0x01 as u8; vps[2] = 0x0c as u8
120 let pps: *u8 = sys_mmap(32); pps[0] = 0x44 as u8; pps[1] = 0x01 as u8; pps[2] = 0xc1 as u8
121
122 let hv: *u8 = sys_mmap(512)
123 let hn: i64 = tsn_build_hvcc(hv, vps, 3, sps, 16, pps, 3)
124
125 var c17: i64 = 0
126 if hn > 0 { if hv[0] == (1 as u8) { c17 = 1 } }
127 tg(c17, "T17 hvcC builds and starts with configurationVersion = 1" as *u8, pass, tot)
128
129 // ★ THE POINT OF THE WHOLE FUNCTION: profile_tier_level must be copied
130 // BYTE-EXACT out of the SPS. A transcription slip here yields a player that
131 // decodes garbage rather than one that refuses.
132 var c18: i64 = 0
133 if hn > 0 {
134 var ok: i64 = 1
135 if hv[1] != (0x21 as u8) { ok = 0 }
136 if hv[2] != (0xa1 as u8) { ok = 0 }
137 if hv[5] != (0xa4 as u8) { ok = 0 }
138 if hv[6] != (0xb1 as u8) { ok = 0 }
139 if hv[11] != (0xb6 as u8) { ok = 0 }
140 if hv[12] != (0x5a as u8) { ok = 0 }
141 c18 = ok
142 }
143 tg(c18, "T18 TOOTH profile_tier_level is copied BYTE-EXACT from the SPS (all 12)" as *u8, pass, tot)
144
145 var c19: i64 = 0
146 if hn > 0 { if hv[21] == (0x0f as u8) { c19 = 1 } }
147 tg(c19, "T19 lengthSizeMinusOne = 3, matching the 4-byte NAL lengths the muxer writes" as *u8, pass, tot)
148
149 var c20: i64 = 0
150 if hn > 0 { if hv[22] == (3 as u8) { c20 = 1 } }
151 tg(c20, "T20 numOfArrays = 3 (VPS + SPS + PPS)" as *u8, pass, tot)
152
153 var c21: i64 = 0
154 if hn > 0 { if hv[23] == (0xa0 as u8) { c21 = 1 } }
155 tg(c21, "T21 first array is VPS(32) with array_completeness set (0x80|32 = 0xa0)" as *u8, pass, tot)
156
157 // ★★★ THE REFUSAL TOOTH: with sub-layers present the profile_tier_level grows
158 // and every field after it shifts, so the 12-byte copy would be WRONG. Refuse.
159 let sps2: *u8 = sys_mmap(64)
160 var z: i64 = 0
161 while z < 16 { sps2[z] = sps[z]; z = z + 1 }
162 sps2[2] = 0x03 as u8 // max_sub_layers_minus1 = 1
163 var c22: i64 = 0
164 if tsn_build_hvcc(hv, vps, 3, sps2, 16, pps, 3) == (0 - 1) { c22 = 1 }
165 tg(c22, "T22 TOOTH sub-layered SPS is REFUSED, not guessed at (wrong hvcC > no hvcC)" as *u8, pass, tot)
166
167 var c23: i64 = 0
168 if tsn_build_hvcc(hv, vps, 3, sps, 10, pps, 3) == (0 - 1) { c23 = 1 }
169 tg(c23, "T23 TOOTH a too-short SPS is REFUSED rather than read past its end" as *u8, pass, tot)
170
171 // gv_verdict emits the canonical summary AND the verdict= anchor that
172 // gate_run / nx_gate_green already judge, and self-records a fail-soft
173 // actlog frame via gv_journal -- both gained for free by adopting.
174 let rc: i64 = gv_verdict("TS-NAL" as *u8, pass, "HEVC classifies correctly and the H.264 path is unchanged" as *u8)
175 sys_exit(rc)
176 return rc
177}