@blockcast/mmt-base 0.5.0 → 1.0.0-main.3cb7359ea316

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.
@@ -1,154 +0,0 @@
1
- /**
2
- * Catalog FEC source rules shared by every catalog reader (BLO-40851).
3
- *
4
- * These are the dialect-level reads the container resolvers
5
- * (`resolveRepairLayers`, `catalogFecUnavailable`), the transport endpoint
6
- * selection (`selectEndpointPacketIds`) and a player's repair inventory all
7
- * need to agree on. They live here, in the leaf package every one of those
8
- * depends on, so there is one copy of each rule instead of copies pinned
9
- * against each other by tests.
10
- *
11
- * - `locateCatalogFecSource`: which catalog entry declares a source's `fec`
12
- * block. hang `video`/`audio` rendition blocks are authoritative over an MSF
13
- * `tracks[]` entry of the same name.
14
- * - `catalogFecAvailable`: draft-ramadan-moq-fec §5.1, whether a block's FEC
15
- * is usable at all (implemented `blockProfile`, usable span).
16
- * - `catalogFecDeclaresUnconfigurableInstance`: a declared FEC instance whose
17
- * geometry a decoder cannot configure, which is a malformed catalog rather
18
- * than "no FEC".
19
- *
20
- * Every function is total: it never throws, whatever the input.
21
- */
22
- import { isFecBlockProfile } from './fec-block-profile.js';
23
- const ALL_ROLES = Object.freeze(['video', 'audio']);
24
- function recordOf(value) {
25
- return value !== null && typeof value === 'object' && !Array.isArray(value)
26
- ? value
27
- : undefined;
28
- }
29
- /**
30
- * Locate the catalog entry that declares one media source's `fec` block, in
31
- * either catalog dialect.
32
- *
33
- * A hang `video`/`audio` rendition named `source` wins, in `roles` order, over
34
- * a `tracks[]` entry of the same name: when a catalog carries rendition blocks
35
- * beside a `tracks[]` switching-set index (the unified ABR ladder catalog),
36
- * the rendition blocks are authoritative, exactly as they are for hang's own
37
- * catalog decode. The precedence is keyed on the rendition EXISTING as an
38
- * object, not on it carrying `fec`: a rendition without `fec` locates with
39
- * `fec: undefined` and never falls through to `tracks[]`.
40
- *
41
- * Otherwise the first `tracks[]` entry named `source` locates. Returns
42
- * undefined when neither dialect names it, or when `catalog` is not an object.
43
- *
44
- * @param roles the hang roles to search, in order (both by default). A typed
45
- * track reference passes its own role only.
46
- */
47
- export function locateCatalogFecSource(catalog, source, roles = ALL_ROLES) {
48
- const root = recordOf(catalog);
49
- if (root === undefined)
50
- return undefined;
51
- for (const role of roles) {
52
- const renditions = recordOf(recordOf(root[role])?.['renditions']);
53
- if (renditions === undefined || !Object.hasOwn(renditions, source))
54
- continue;
55
- const entry = recordOf(renditions[source]);
56
- if (entry === undefined)
57
- continue;
58
- return Object.freeze({
59
- dialect: 'hang',
60
- role,
61
- entry,
62
- fec: entry['fec'],
63
- fecPath: `$.${role}.renditions[${JSON.stringify(source)}].fec`,
64
- });
65
- }
66
- const tracks = root['tracks'];
67
- if (!Array.isArray(tracks))
68
- return undefined;
69
- const index = tracks.findIndex((track) => recordOf(track)?.['name'] === source);
70
- if (index < 0)
71
- return undefined;
72
- const entry = recordOf(tracks[index]) ?? {};
73
- return Object.freeze({
74
- dialect: 'msf',
75
- index,
76
- entry,
77
- fec: entry['fec'],
78
- fecPath: `$.tracks[${index}].fec`,
79
- });
80
- }
81
- /**
82
- * Whether an `iso-ssbg1-v1` block's optional `interleaveDepthMs` span is
83
- * usable: absent, or a non-negative safe integer. Zero or absence supplies no
84
- * elapsed deadline and still permits in-band FEC. True for every block that
85
- * names another profile (the span is not read) and for a non-object.
86
- */
87
- export function isoBlockSpanUsable(fec) {
88
- const block = recordOf(fec);
89
- if (block === undefined || block['blockProfile'] !== 'iso-ssbg1-v1')
90
- return true;
91
- const ms = block['interleaveDepthMs'];
92
- return ms === undefined || (typeof ms === 'number' && Number.isSafeInteger(ms) && ms >= 0);
93
- }
94
- /**
95
- * Whether one catalog `fec` block leaves its FEC available
96
- * (draft-ramadan-moq-fec §5.1): the decision the container's
97
- * `catalogFecUnavailable` explains with a typed reason.
98
- *
99
- * False when the block's `algorithm` is a token this receiver does not
100
- * implement (`fecAlgorithmUnimplemented`); when it declares an FEC instance
101
- * (any `algorithm` but `"none"`) and names no implemented `blockProfile` (the retired `k-padded-v1`
102
- * included), or carries an `iso-ssbg1-v1` span it cannot use; and when a block
103
- * declaring no FEC instance carries a profile token that is not implemented.
104
- * True for a non-object and for every other block. It reads only the profile
105
- * and the span: malformed geometry (`sourceSymbols`, `symbolSize`) is
106
- * `catalogFecDeclaresUnconfigurableInstance`'s.
107
- *
108
- * A receiver applies no FEC to a source whose block is unavailable and joins
109
- * none of its repair tracks, without failing the session.
110
- */
111
- export function catalogFecAvailable(fec) {
112
- const block = recordOf(fec);
113
- if (block === undefined)
114
- return true;
115
- if (fecAlgorithmUnimplemented(block['algorithm']))
116
- return false;
117
- const declaresFecInstance = block['algorithm'] !== 'none';
118
- const profile = block['blockProfile'];
119
- const profileOk = isFecBlockProfile(profile) || (profile === undefined && !declaresFecInstance);
120
- return profileOk && (!declaresFecInstance || isoBlockSpanUsable(block));
121
- }
122
- /**
123
- * Whether `algorithm` is a token this receiver does not implement
124
- * (draft-ramadan-moq-fec-01 4): any string but `none`, `raptorq` and
125
- * `reed-solomon`. Such a track is consumed without FEC and its repair tracks
126
- * are not joined; the catalog is not in error. An absent algorithm is not a
127
- * token (the hang dialect omits it) and stays implemented.
128
- */
129
- export function fecAlgorithmUnimplemented(algorithm) {
130
- return typeof algorithm === 'string' && algorithm !== 'none' && algorithm !== 'raptorq' && algorithm !== 'reed-solomon';
131
- }
132
- function isPositiveSafeInteger(value) {
133
- return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;
134
- }
135
- /** Smallest `symbolSize` under `iso-ssbg1-v1` (draft-ramadan-moq-fec-01 5.1, 6.3.4 rule 13). */
136
- export const ISO_SSBG1_MIN_SYMBOL_SIZE = 14;
137
- /**
138
- * Whether a source's `fec` block declares an FEC instance (any `algorithm`
139
- * but `"none"`) whose `sourceSymbols` or `symbolSize` is not a positive
140
- * integer, or whose `iso-ssbg1-v1` `symbolSize` is below
141
- * `ISO_SSBG1_MIN_SYMBOL_SIZE` (rule 13: such a symbol carries no protected
142
- * MMTP packet). Geometry a decoder cannot configure is a malformed catalog, not
143
- * "no FEC": the container's per-track resolver throws `track_fec` for exactly
144
- * this block, whatever its profile or span.
145
- */
146
- export function catalogFecDeclaresUnconfigurableInstance(fec) {
147
- const block = recordOf(fec);
148
- if (block === undefined || block['algorithm'] === 'none' || fecAlgorithmUnimplemented(block['algorithm']))
149
- return false;
150
- if (!(isPositiveSafeInteger(block['sourceSymbols']) && isPositiveSafeInteger(block['symbolSize'])))
151
- return true;
152
- return block['blockProfile'] === 'iso-ssbg1-v1' && block['symbolSize'] < ISO_SSBG1_MIN_SYMBOL_SIZE;
153
- }
154
- //# sourceMappingURL=catalog-fec-source.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"catalog-fec-source.js","sourceRoot":"","sources":["../src/catalog-fec-source.ts"],"names":[],"mappings":"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"}
@@ -1,183 +0,0 @@
1
- /**
2
- * Catalog FEC source rules shared by every catalog reader (BLO-40851).
3
- *
4
- * These are the dialect-level reads the container resolvers
5
- * (`resolveRepairLayers`, `catalogFecUnavailable`), the transport endpoint
6
- * selection (`selectEndpointPacketIds`) and a player's repair inventory all
7
- * need to agree on. They live here, in the leaf package every one of those
8
- * depends on, so there is one copy of each rule instead of copies pinned
9
- * against each other by tests.
10
- *
11
- * - `locateCatalogFecSource`: which catalog entry declares a source's `fec`
12
- * block. hang `video`/`audio` rendition blocks are authoritative over an MSF
13
- * `tracks[]` entry of the same name.
14
- * - `catalogFecAvailable`: draft-ramadan-moq-fec §5.1, whether a block's FEC
15
- * is usable at all (implemented `blockProfile`, usable span).
16
- * - `catalogFecDeclaresUnconfigurableInstance`: a declared FEC instance whose
17
- * geometry a decoder cannot configure, which is a malformed catalog rather
18
- * than "no FEC".
19
- *
20
- * Every function is total: it never throws, whatever the input.
21
- */
22
- import { isFecBlockProfile } from './fec-block-profile.js'
23
-
24
- /** The catalog media roles that carry hang renditions. */
25
- export type CatalogFecRole = 'video' | 'audio'
26
-
27
- /** One media source's `fec` block, as `locateCatalogFecSource` found it. */
28
- export type CatalogFecSource =
29
- | {
30
- readonly dialect: 'hang'
31
- readonly role: CatalogFecRole
32
- /** The rendition object. */
33
- readonly entry: Record<string, unknown>
34
- /** The rendition's `fec` value, unvalidated (may be undefined). */
35
- readonly fec: unknown
36
- /** JSON path of that `fec` block. */
37
- readonly fecPath: string
38
- }
39
- | {
40
- readonly dialect: 'msf'
41
- /** Index of the entry in `tracks[]`. */
42
- readonly index: number
43
- /** The `tracks[]` entry (an empty object when the entry is not an object). */
44
- readonly entry: Record<string, unknown>
45
- /** The entry's `fec` value, unvalidated (may be undefined). */
46
- readonly fec: unknown
47
- /** JSON path of that `fec` block. */
48
- readonly fecPath: string
49
- }
50
-
51
- const ALL_ROLES: readonly CatalogFecRole[] = Object.freeze(['video', 'audio'])
52
-
53
- function recordOf(value: unknown): Record<string, unknown> | undefined {
54
- return value !== null && typeof value === 'object' && !Array.isArray(value)
55
- ? (value as Record<string, unknown>)
56
- : undefined
57
- }
58
-
59
- /**
60
- * Locate the catalog entry that declares one media source's `fec` block, in
61
- * either catalog dialect.
62
- *
63
- * A hang `video`/`audio` rendition named `source` wins, in `roles` order, over
64
- * a `tracks[]` entry of the same name: when a catalog carries rendition blocks
65
- * beside a `tracks[]` switching-set index (the unified ABR ladder catalog),
66
- * the rendition blocks are authoritative, exactly as they are for hang's own
67
- * catalog decode. The precedence is keyed on the rendition EXISTING as an
68
- * object, not on it carrying `fec`: a rendition without `fec` locates with
69
- * `fec: undefined` and never falls through to `tracks[]`.
70
- *
71
- * Otherwise the first `tracks[]` entry named `source` locates. Returns
72
- * undefined when neither dialect names it, or when `catalog` is not an object.
73
- *
74
- * @param roles the hang roles to search, in order (both by default). A typed
75
- * track reference passes its own role only.
76
- */
77
- export function locateCatalogFecSource(
78
- catalog: unknown,
79
- source: string,
80
- roles: readonly CatalogFecRole[] = ALL_ROLES,
81
- ): CatalogFecSource | undefined {
82
- const root = recordOf(catalog)
83
- if (root === undefined) return undefined
84
- for (const role of roles) {
85
- const renditions = recordOf(recordOf(root[role])?.['renditions'])
86
- if (renditions === undefined || !Object.hasOwn(renditions, source)) continue
87
- const entry = recordOf(renditions[source])
88
- if (entry === undefined) continue
89
- return Object.freeze({
90
- dialect: 'hang' as const,
91
- role,
92
- entry,
93
- fec: entry['fec'],
94
- fecPath: `$.${role}.renditions[${JSON.stringify(source)}].fec`,
95
- })
96
- }
97
- const tracks = root['tracks']
98
- if (!Array.isArray(tracks)) return undefined
99
- const index = tracks.findIndex((track) => recordOf(track)?.['name'] === source)
100
- if (index < 0) return undefined
101
- const entry = recordOf(tracks[index]) ?? {}
102
- return Object.freeze({
103
- dialect: 'msf' as const,
104
- index,
105
- entry,
106
- fec: entry['fec'],
107
- fecPath: `$.tracks[${index}].fec`,
108
- })
109
- }
110
-
111
- /**
112
- * Whether an `iso-ssbg1-v1` block's optional `interleaveDepthMs` span is
113
- * usable: absent, or a non-negative safe integer. Zero or absence supplies no
114
- * elapsed deadline and still permits in-band FEC. True for every block that
115
- * names another profile (the span is not read) and for a non-object.
116
- */
117
- export function isoBlockSpanUsable(fec: unknown): boolean {
118
- const block = recordOf(fec)
119
- if (block === undefined || block['blockProfile'] !== 'iso-ssbg1-v1') return true
120
- const ms = block['interleaveDepthMs']
121
- return ms === undefined || (typeof ms === 'number' && Number.isSafeInteger(ms) && ms >= 0)
122
- }
123
-
124
- /**
125
- * Whether one catalog `fec` block leaves its FEC available
126
- * (draft-ramadan-moq-fec §5.1): the decision the container's
127
- * `catalogFecUnavailable` explains with a typed reason.
128
- *
129
- * False when the block's `algorithm` is a token this receiver does not
130
- * implement (`fecAlgorithmUnimplemented`); when it declares an FEC instance
131
- * (any `algorithm` but `"none"`) and names no implemented `blockProfile` (the retired `k-padded-v1`
132
- * included), or carries an `iso-ssbg1-v1` span it cannot use; and when a block
133
- * declaring no FEC instance carries a profile token that is not implemented.
134
- * True for a non-object and for every other block. It reads only the profile
135
- * and the span: malformed geometry (`sourceSymbols`, `symbolSize`) is
136
- * `catalogFecDeclaresUnconfigurableInstance`'s.
137
- *
138
- * A receiver applies no FEC to a source whose block is unavailable and joins
139
- * none of its repair tracks, without failing the session.
140
- */
141
- export function catalogFecAvailable(fec: unknown): boolean {
142
- const block = recordOf(fec)
143
- if (block === undefined) return true
144
- if (fecAlgorithmUnimplemented(block['algorithm'])) return false
145
- const declaresFecInstance = block['algorithm'] !== 'none'
146
- const profile = block['blockProfile']
147
- const profileOk = isFecBlockProfile(profile) || (profile === undefined && !declaresFecInstance)
148
- return profileOk && (!declaresFecInstance || isoBlockSpanUsable(block))
149
- }
150
-
151
- /**
152
- * Whether `algorithm` is a token this receiver does not implement
153
- * (draft-ramadan-moq-fec-01 4): any string but `none`, `raptorq` and
154
- * `reed-solomon`. Such a track is consumed without FEC and its repair tracks
155
- * are not joined; the catalog is not in error. An absent algorithm is not a
156
- * token (the hang dialect omits it) and stays implemented.
157
- */
158
- export function fecAlgorithmUnimplemented(algorithm: unknown): boolean {
159
- return typeof algorithm === 'string' && algorithm !== 'none' && algorithm !== 'raptorq' && algorithm !== 'reed-solomon'
160
- }
161
-
162
- function isPositiveSafeInteger(value: unknown): boolean {
163
- return typeof value === 'number' && Number.isSafeInteger(value) && value > 0
164
- }
165
-
166
- /** Smallest `symbolSize` under `iso-ssbg1-v1` (draft-ramadan-moq-fec-01 5.1, 6.3.4 rule 13). */
167
- export const ISO_SSBG1_MIN_SYMBOL_SIZE = 14
168
-
169
- /**
170
- * Whether a source's `fec` block declares an FEC instance (any `algorithm`
171
- * but `"none"`) whose `sourceSymbols` or `symbolSize` is not a positive
172
- * integer, or whose `iso-ssbg1-v1` `symbolSize` is below
173
- * `ISO_SSBG1_MIN_SYMBOL_SIZE` (rule 13: such a symbol carries no protected
174
- * MMTP packet). Geometry a decoder cannot configure is a malformed catalog, not
175
- * "no FEC": the container's per-track resolver throws `track_fec` for exactly
176
- * this block, whatever its profile or span.
177
- */
178
- export function catalogFecDeclaresUnconfigurableInstance(fec: unknown): boolean {
179
- const block = recordOf(fec)
180
- if (block === undefined || block['algorithm'] === 'none' || fecAlgorithmUnimplemented(block['algorithm'])) return false
181
- if (!(isPositiveSafeInteger(block['sourceSymbols']) && isPositiveSafeInteger(block['symbolSize']))) return true
182
- return block['blockProfile'] === 'iso-ssbg1-v1' && (block['symbolSize'] as number) < ISO_SSBG1_MIN_SYMBOL_SIZE
183
- }