@blockcast/mmt-container 0.5.0-main.ed11aec88d91 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-runtime.js +150 -21
- package/dist/browser-runtime.js.map +2 -2
- package/dist/fec-manager.d.ts.map +1 -1
- package/dist/fec-manager.js.map +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +2 -2
- package/dist/mmtp-container-parser.d.ts +10 -0
- package/dist/mmtp-container-parser.d.ts.map +1 -1
- package/dist/mmtp-container-parser.js +31 -1
- package/dist/mmtp-container-parser.js.map +2 -2
- package/dist/mmtp-container-parser.no-modules.js +31 -1
- package/dist/mmtp-container-parser.no-modules.js.map +2 -2
- package/dist/mmtp-decode-pipeline.js +31 -1
- package/dist/mmtp-decode-pipeline.js.map +2 -2
- package/dist/mmtp-router.d.ts +11 -0
- package/dist/mmtp-router.d.ts.map +1 -1
- package/dist/mmtp-router.js +54 -1
- package/dist/mmtp-router.js.map +2 -2
- package/dist/multicast-manager.d.ts +25 -1
- package/dist/multicast-manager.d.ts.map +1 -1
- package/dist/multicast-manager.js +92 -2
- package/dist/multicast-manager.js.map +2 -2
- package/dist/no-modules.js +31 -1
- package/dist/no-modules.js.map +2 -2
- package/dist/repair-fetch.d.ts +41 -10
- package/dist/repair-fetch.d.ts.map +1 -1
- package/dist/repair-fetch.js +58 -19
- package/dist/repair-fetch.js.map +2 -2
- package/dist/wasm-mmtp-container-parser.js +31 -1
- package/dist/wasm-mmtp-container-parser.js.map +2 -2
- package/package.json +7 -6
- package/src/fec-manager.ts +3 -0
- package/src/index.ts +1 -0
- package/src/mmtp-container-parser.ts +48 -0
- package/src/mmtp-router.ts +27 -0
- package/src/multicast-manager.ts +68 -0
- package/src/repair-fetch.ts +131 -31
- package/test-vectors/catalog/negative/multicast-auth-padded-key.json +0 -1
- package/test-vectors/catalog/negative/multicast-auth-reused-track-format.json +0 -1
- package/test-vectors/catalog/negative/multicast-auth-root-dotted-key.json +0 -1
- package/test-vectors/catalog/negative/multicast-auth-trailing-pad-bits.json +0 -1
- package/test-vectors/repair-policy-v1.json +113 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"description": "Receiver repair policy (draft-ramadan-moq-fec-01 Section 11.4.2 and Section 11.4.5 item 3, Blockcast/moqcast-draft PR #2 @ 3162ef93). Which repair FETCHes a receiver sends, which it cancels, and which it never sends. Hand-authored from the specification, NOT generated by any implementation (BLO-49776).",
|
|
4
|
+
"scope": [
|
|
5
|
+
"Section 11.4 applies only to a multicast or AMT leg with a MoQ session (fec-01 11.4). These cases describe that leg; a receiver with no repair FETCH path records ABSENT, not a pass.",
|
|
6
|
+
"schedulerCases drive a repair scheduler. Every block spans K' = 4 SS_IDs, so block B covers SS_IDs B..B+3. Track video is a source track (packetId 1, keyframe or delta blocks); track audio is packetId 2 (audio blocks). A block is named track/SS_Start.",
|
|
7
|
+
"Best-effort (delta and audio) requests in schedulerCases are presumed covered by unexpired credit under fec-01 11.4.5 item 2; that credit is a precondition of each case, not something the case exercises.",
|
|
8
|
+
"A RAP 'held complete at ssId' is a keyframe access unit at SS_ID ssId that the receiver holds complete: admitted complete under the multicast-01 7.2.7 profile, received or recovered complete outside it. A block lies below it when the block's last SS_ID is less than ssId; a RAP at or inside the block does not make the block moot.",
|
|
9
|
+
"fetched lists every FETCH the receiver sends, in order. cancelled lists every sent FETCH it then cancels (FETCH_CANCEL on the wire). skipped names requests made but not sent, with the receiver's reason; stopped names sent FETCHes stopped, with the stop reason. A list not given is expected empty.",
|
|
10
|
+
"assistedCases drive one block of a protected flow (multicast-01 7.2.7) that is one symbol short of SSB_length, with unlisted repair symbols pooled for it. Each unlisted symbol triggers one unlisted-assisted decode in a scratch decoder; outcome 'fail' is a failed decode, 'recover' a decode whose recovered data unit admission accepts, 'recover-unadmitted' a decode whose recovered data unit admission refuses.",
|
|
11
|
+
"status names where a case's rule comes from: 'fec-01' is a -01 requirement; 'libmmt interpretation' is our reading where -01 is silent; 'regression' rows were already required at moqcast-draft main 615a9a8 and are kept to pin standing behaviour.",
|
|
12
|
+
"A keyframe request refused before its FETCH is sent (libmmt's reliable-path RTT check) is libmmt-local and deviates from the fec-01 11.4.2 MUST, so it is pinned in libmmt's own suite (repair-fetch-keyframe-budget.test.ts), not here. The 11.4.5 item 3 rule that a block 11.4.2 does not request cancels nothing is exercised by keyframe-below-complete-rap-not-requested."
|
|
13
|
+
],
|
|
14
|
+
"schedulerCases": [
|
|
15
|
+
{
|
|
16
|
+
"name": "keyframe-below-complete-rap-not-requested",
|
|
17
|
+
"status": "fec-01",
|
|
18
|
+
"rule": "fec-01 11.4.2: a keyframe-bearing block at its FEC deadline is requested unless it lies below a RAP already held complete; 11.4.5 item 3: a block whose repair 11.4.2 does not request cancels nothing (case a).",
|
|
19
|
+
"ops": [
|
|
20
|
+
{ "op": "fire", "track": "video", "block": 20, "class": "delta" },
|
|
21
|
+
{ "op": "rapHeld", "ssId": 4 },
|
|
22
|
+
{ "op": "fire", "track": "video", "block": 0, "class": "keyframe" }
|
|
23
|
+
],
|
|
24
|
+
"expect": {
|
|
25
|
+
"fetched": ["video/20"],
|
|
26
|
+
"skipped": [{ "block": "video/0", "reason": "moot-rap" }]
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "control-rap-inside-block-is-requested",
|
|
31
|
+
"status": "libmmt interpretation",
|
|
32
|
+
"rule": "Control for the case above. fec-01 does not define 'lies below'; libmmt reads it so that a RAP at the block's own last SS_ID is part of the block, so the block is not below it and is requested.",
|
|
33
|
+
"ops": [
|
|
34
|
+
{ "op": "rapHeld", "ssId": 3 },
|
|
35
|
+
{ "op": "fire", "track": "video", "block": 0, "class": "keyframe" }
|
|
36
|
+
],
|
|
37
|
+
"expect": { "fetched": ["video/0"] }
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "rap-completes-mid-fetch-cancels",
|
|
41
|
+
"status": "regression",
|
|
42
|
+
"rule": "fec-01 11.4.2 (already a SHOULD at main 615a9a8): a RAP completing while a keyframe repair is outstanding makes that repair moot and the receiver cancels it; a block above the RAP keeps its FETCH (case b).",
|
|
43
|
+
"ops": [
|
|
44
|
+
{ "op": "fire", "track": "video", "block": 0, "class": "keyframe" },
|
|
45
|
+
{ "op": "fire", "track": "video", "block": 8, "class": "keyframe" },
|
|
46
|
+
{ "op": "rapComplete", "ssId": 5 }
|
|
47
|
+
],
|
|
48
|
+
"expect": {
|
|
49
|
+
"fetched": ["video/0", "video/8"],
|
|
50
|
+
"cancelled": ["video/0"],
|
|
51
|
+
"stopped": [{ "block": "video/0", "reason": "moot" }]
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "audio-request-preempts-nothing",
|
|
56
|
+
"status": "fec-01",
|
|
57
|
+
"rule": "fec-01 11.4.5 item 3: only the keyframe repair 11.4.2 requests cancels best-effort FETCHes; an audio request cancels nothing.",
|
|
58
|
+
"ops": [
|
|
59
|
+
{ "op": "fire", "track": "video", "block": 20, "class": "delta" },
|
|
60
|
+
{ "op": "fire", "track": "audio", "block": 0, "class": "audio" }
|
|
61
|
+
],
|
|
62
|
+
"expect": { "fetched": ["video/20", "audio/0"] }
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "sent-keyframe-repair-cancels-delta-and-audio",
|
|
66
|
+
"status": "regression",
|
|
67
|
+
"rule": "fec-01 11.4.5 item 3 (standing at main 615a9a8): a keyframe repair FETCH that is sent cancels the outstanding delta and audio FETCHes (case c-pos).",
|
|
68
|
+
"ops": [
|
|
69
|
+
{ "op": "fire", "track": "video", "block": 20, "class": "delta" },
|
|
70
|
+
{ "op": "fire", "track": "audio", "block": 0, "class": "audio" },
|
|
71
|
+
{ "op": "fire", "track": "video", "block": 40, "class": "keyframe" }
|
|
72
|
+
],
|
|
73
|
+
"expect": {
|
|
74
|
+
"fetched": ["video/20", "audio/0", "video/40"],
|
|
75
|
+
"cancelled": ["video/20", "audio/0"],
|
|
76
|
+
"stopped": [
|
|
77
|
+
{ "block": "video/20", "reason": "preempted" },
|
|
78
|
+
{ "block": "audio/0", "reason": "preempted" }
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"assistedCases": [
|
|
84
|
+
{
|
|
85
|
+
"name": "two-failed-assisted-decodes-then-refused",
|
|
86
|
+
"status": "fec-01",
|
|
87
|
+
"rule": "multicast-01 7.2.7 step 2, referenced by fec-01 11.4: at most two unlisted-assisted decodes may fail per block; a failed decode's pooled symbol is discarded and a fresh one retried; a third is refused (case d).",
|
|
88
|
+
"decodes": ["fail", "fail", "fail"],
|
|
89
|
+
"expect": { "scratchDecodes": 2, "refused": 1, "recovered": false }
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "assisted-decode-recovers-on-retry",
|
|
93
|
+
"status": "fec-01",
|
|
94
|
+
"rule": "Control for the case above: after one failed decode, the retry on a fresh pooled symbol recovers the block (case d).",
|
|
95
|
+
"decodes": ["fail", "recover"],
|
|
96
|
+
"expect": { "scratchDecodes": 2, "refused": 0, "recovered": true }
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "recovered-but-unadmitted-is-unrecovered",
|
|
100
|
+
"status": "fec-01",
|
|
101
|
+
"rule": "multicast-01 7.2.7 / fec-01 11.4.2: a data unit recovered but refused by admission does not complete the block; the block stays unrecovered and is still due its repair at the FEC deadline (case e).",
|
|
102
|
+
"decodes": ["recover-unadmitted"],
|
|
103
|
+
"expect": { "scratchDecodes": 1, "refused": 0, "recovered": false }
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"name": "unadmitted-recovery-counts-toward-decode-cap",
|
|
107
|
+
"status": "fec-01",
|
|
108
|
+
"rule": "multicast-01 7.2.7: a decode none of whose recovered packets is admitted recovers nothing, so it counts toward the two-decode cap like a failed decode (case e).",
|
|
109
|
+
"decodes": ["recover-unadmitted", "fail", "fail"],
|
|
110
|
+
"expect": { "scratchDecodes": 2, "refused": 1, "recovered": false }
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|