nx_uxf_negotiate.nx source
↩ module page · 96 lines · 4354 B
1// nx_uxf_negotiate.nx -- UXF arc B: ENDPOINT-ADAPTIVE capability negotiation -- "never a walled
2// garden, serve what the endpoint can consume" (Law-1/2). Given a stored media asset's
3// self-describing profile {container, vcodec, acodec} and an endpoint's declared capabilities
4// (data-driven, knowledge/registry/endpoint_caps.tsv), decide the EMIT PLAN:
5// DIRECT -- endpoint supports container + both codecs -> serve bytes unchanged.
6// REMUX -- both CODECS supported but CONTAINER not -> rewrap losslessly (NO re-encode).
7// This is the real "Chrome can't play MKV" fix: H.264/AAC-in-MKV -> MP4, lossless.
8// TRANSCODE -- a codec is unsupported -> must re-encode (lossy/expensive) -- the heavy downstream.
9// HONEST SCOPE: this organ builds + proves the PLAN (the negotiation). The actual remux/transcode
10// EXECUTION (container rewrap, codec re-encode) is the named heavy downstream, NOT faked here.
11// No hardware writes (Rule 26). license_tier: ORIGINAL
12import "nx_syscalls.nx"
13
14const PLAN_DIRECT: i64 = 0
15const PLAN_REMUX: i64 = 1
16const PLAN_TRANSCODE: i64 = 2
17
18func ng_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
19
20// is null-terminated `token` present as a whole field in comma-separated null-terminated `list`?
21func ng_csv_has(list: *u8, token: *u8) -> i64 {
22 let tl: i64 = ng_slen(token)
23 var fstart: i64 = 0
24 var done: i64 = 0
25 while done == 0 {
26 var p: i64 = fstart
27 var f: i64 = 1
28 while f == 1 {
29 let c: i64 = list[p] as i64
30 if c == 0 { f = 0 } else { if c == 44 { f = 0 } else { p = p + 1 } } // 44=','
31 }
32 let flen: i64 = p - fstart
33 if flen == tl {
34 var eq: i64 = 1
35 var t: i64 = 0
36 while t < tl { if list[fstart + t] != token[t] { eq = 0; t = tl } else { t = t + 1 } }
37 if eq == 1 { return 1 }
38 }
39 if list[p] == (0 as u8) { done = 1 } else { fstart = p + 1 }
40 }
41 return 0
42}
43
44// compare buf[a..b) to null-terminated z
45func ng_streq_slice(buf: *u8, a: i64, b: i64, z: *u8) -> i64 {
46 let zl: i64 = ng_slen(z)
47 if (b - a) != zl { return 0 }
48 var i: i64 = 0
49 while i < zl { if buf[a + i] != z[i] { return 0 } i = i + 1 }
50 return 1
51}
52
53func ng_copy_slice(buf: *u8, a: i64, b: i64, dst: *u8) -> i64 {
54 var i: i64 = 0
55 while i < (b - a) { dst[i] = buf[a + i]; i = i + 1 }
56 dst[b - a] = 0 as u8
57 return b - a
58}
59
60// find `endpoint` in the caps TSV; fill out_cont/out_codec (null-term). returns 1 if found.
61func ng_caps_lookup(tsv: *u8, n: i64, endpoint: *u8, out_cont: *u8, out_codec: *u8) -> i64 {
62 var i: i64 = 0
63 while i < n {
64 let ls: i64 = i
65 var le: i64 = i
66 var f: i64 = 1
67 while f == 1 { if le >= n { f = 0 } else { if tsv[le] == (0x0A as u8) { f = 0 } else { le = le + 1 } } }
68 if le > ls {
69 if tsv[ls] != (0x23 as u8) { // not '#'
70 var t0: i64 = ls
71 var g0: i64 = 1
72 while g0 == 1 { if t0 >= le { g0 = 0 } else { if tsv[t0] == (0x09 as u8) { g0 = 0 } else { t0 = t0 + 1 } } }
73 if ng_streq_slice(tsv, ls, t0, endpoint) == 1 {
74 var t1: i64 = t0 + 1
75 var g1: i64 = 1
76 while g1 == 1 { if t1 >= le { g1 = 0 } else { if tsv[t1] == (0x09 as u8) { g1 = 0 } else { t1 = t1 + 1 } } }
77 ng_copy_slice(tsv, t0 + 1, t1, out_cont)
78 if t1 < le { ng_copy_slice(tsv, t1 + 1, le, out_codec) } else { out_codec[0] = 0 as u8 }
79 return 1
80 }
81 }
82 }
83 i = le + 1
84 }
85 return 0
86}
87
88// the negotiation: given asset {container,vcodec,acodec} and endpoint caps, return the emit plan.
89func ng_negotiate(container: *u8, vcodec: *u8, acodec: *u8, ep_cont: *u8, ep_codec: *u8) -> i64 {
90 let cont_ok: i64 = ng_csv_has(ep_cont, container)
91 let v_ok: i64 = ng_csv_has(ep_codec, vcodec)
92 let a_ok: i64 = ng_csv_has(ep_codec, acodec)
93 if cont_ok == 1 { if v_ok == 1 { if a_ok == 1 { return PLAN_DIRECT } } }
94 if v_ok == 1 { if a_ok == 1 { return PLAN_REMUX } } // codecs fine, container not -> lossless rewrap
95 return PLAN_TRANSCODE // a codec unsupported -> must re-encode
96}