code wiki / _hdl_build / nx_dash_get.nx
nx_dash_get.nx source
↩ module page · 61 lines · 2844 B
1// nx_dash_get.nx -- the DASH download ORCHESTRATOR (the parallel to nx_hls_get, composing this session's
2// pieces): dash_parse (.mpd -> segment URLs) -> rdl_fetch_retry (per-segment retry + integrity, so a corrupt
3// or dropped fragment is re-fetched, never stitched) -> concat (init + media) into one output. Format kind =
4// RDL_GENERIC (DASH is fMP4/.m4s; the whole-fragment bar is non-empty; a fMP4-box check is a later rung). A
5// live caller passes a TLS fetch_fn; the gate passes a failure-injecting one. Parallel = wrap pdl_download
6// (nx_pardl, measured 4x) over the seglist -- a follow-on; this orchestrator is serial-with-retry.
7import "nx_syscalls.nx"
8import "nx_robust_dl.nx"
9import "nx_dash_parse.nx"
10const K_MAGIC_262144: i64 = 262144
11const K_MAGIC_4096: i64 = 4096
12const K_MAGIC_2097152: i64 = 2097152
13const K_MAGIC_4095: i64 = 4095
14
15// job config bundled into a struct (keeps dg_download under the arg-clobber limit + lets a struct carry the
16// fetch func-pointer, like nx_media_session's callback fields).
17struct DgJob {
18 fetch_fn: func(*u8, i64, i64, *u8, i64, i64) -> i64,
19 rctx: i64,
20 kind: i64,
21 max_tries: i64,
22}
23
24// Download every segment of `mpd` (retry+integrity each) and concat into `outbuf`. Returns total bytes, or
25// -1 if ANY segment couldn't be fetched after retries (abort rather than stitch a hole = no broken fragment).
26func dg_download(mpd: *u8, ml: i64, job: *DgJob, outbuf: *u8, outcap: i64) -> i64 {
27 let seglist: *u8 = sys_mmap(K_MAGIC_262144)
28 let nseg: i64 = dash_parse(mpd, ml, seglist, K_MAGIC_262144)
29 if nseg <= 0 { return 0 - 1 }
30 let url: *u8 = sys_mmap(K_MAGIC_4096)
31 let frag: *u8 = sys_mmap(K_MAGIC_2097152)
32 var o: i64 = 0
33 var li: i64 = 0
34 var got: i64 = 0
35 var abort: i64 = 0
36 while got < nseg {
37 if abort == 1 { got = nseg }
38 else {
39 // pull segment URL `got` (next line) from seglist
40 var q: i64 = 0
41 var inl: i64 = 1
42 while inl == 1 {
43 let c: i64 = seglist[li] & 0xff
44 if c == 0 { inl = 0 }
45 else { if c == 10 { inl = 0; li = li + 1 } else { if q < K_MAGIC_4095 { url[q] = c as u8; q = q + 1 } li = li + 1 } }
46 }
47 url[q] = 0 as u8
48 if q > 0 {
49 let n: i64 = rdl_fetch_retry(url, q, frag, K_MAGIC_2097152, job.kind, job.fetch_fn, job.rctx, job.max_tries, 0)
50 if n < 0 { abort = 1 } // exhausted -> do NOT stitch a broken/partial file
51 else {
52 var k: i64 = 0
53 while k < n { if o < outcap { outbuf[o] = frag[k]; o = o + 1 } k = k + 1 }
54 got = got + 1
55 }
56 } else { got = got + 1 }
57 }
58 }
59 if abort == 1 { return 0 - 1 }
60 return o
61}