@moqtap/codec 0.10.0 → 0.11.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/CHANGELOG.md +147 -0
- package/dist/auth-redaction-DsdLq4Qs.d.cts +102 -0
- package/dist/auth-redaction-DsdLq4Qs.d.ts +102 -0
- package/dist/{chunk-RYKQXBG6.cjs → chunk-27K5BUAG.cjs} +481 -517
- package/dist/{chunk-WCPENYNE.js → chunk-3RNQMGKA.js} +359 -390
- package/dist/{chunk-TSUZ6GJV.js → chunk-5AWIXOLB.js} +438 -469
- package/dist/{chunk-4XLYCT5Q.cjs → chunk-5IMHJIAZ.cjs} +52 -2
- package/dist/{chunk-KTNERCTZ.cjs → chunk-5JGZCKJO.cjs} +488 -518
- package/dist/{chunk-WCTMPDUX.cjs → chunk-73K4OSAN.cjs} +401 -432
- package/dist/{chunk-N2V7Z37J.js → chunk-7VQKRGRD.js} +19 -3
- package/dist/{chunk-BIBMDTU5.cjs → chunk-A3UCQOIB.cjs} +486 -517
- package/dist/{chunk-K2B3OVFK.js → chunk-A7PDMVXM.js} +24 -3
- package/dist/{chunk-VZHL2U2N.cjs → chunk-A7VQO6YC.cjs} +54 -38
- package/dist/{chunk-AQ445VV7.cjs → chunk-ACQHZLRZ.cjs} +66 -46
- package/dist/{chunk-L5DRACXS.js → chunk-BBICOMW6.js} +25 -3
- package/dist/{chunk-T4VWPKDG.cjs → chunk-BNIUVOCJ.cjs} +529 -599
- package/dist/{chunk-UKKDOOUO.cjs → chunk-CNC6ANS4.cjs} +58 -37
- package/dist/{chunk-OZRK73NQ.js → chunk-FDLQSWHK.js} +433 -469
- package/dist/{chunk-IJAF6PAY.js → chunk-FFNOE4UR.js} +19 -3
- package/dist/{chunk-CZNW3R5E.cjs → chunk-GMENT63T.cjs} +54 -38
- package/dist/{chunk-XCRCAUGI.cjs → chunk-HM7BLRVP.cjs} +291 -297
- package/dist/{chunk-XHAP2YST.js → chunk-HZONHFNO.js} +19 -3
- package/dist/{chunk-SDJTSMOW.cjs → chunk-ILYABWDK.cjs} +60 -38
- package/dist/{chunk-IDV2JYJ6.cjs → chunk-KRSFTZVO.cjs} +56 -40
- package/dist/{chunk-RIIA4ALQ.cjs → chunk-KSPH6KMH.cjs} +54 -38
- package/dist/{chunk-OUNN4IQB.cjs → chunk-KTY4LAUV.cjs} +482 -497
- package/dist/{chunk-RZTLQAKF.js → chunk-OJNLJT5D.js} +0 -1
- package/dist/{chunk-FT3HDNIB.js → chunk-PJK2ZS3I.js} +467 -537
- package/dist/{chunk-G53WYUXL.js → chunk-PSMZKHOC.js} +441 -456
- package/dist/{chunk-7RE6KSIY.cjs → chunk-Q5JQGHWY.cjs} +0 -1
- package/dist/{chunk-BX2N7TZM.js → chunk-SQTUQY5E.js} +31 -11
- package/dist/{chunk-CF5DDD3Q.js → chunk-WCRLAKDW.js} +239 -245
- package/dist/{chunk-KYVTM5VI.js → chunk-WL2YUEXH.js} +19 -3
- package/dist/{chunk-KGDVC4O6.js → chunk-YCNIVZS7.js} +439 -469
- package/dist/{chunk-KLPWJU6W.js → chunk-YRZQVNZO.js} +50 -0
- package/dist/{codec-CFWu5KVT.d.cts → codec-76xzrLTL.d.cts} +21 -2
- package/dist/{codec-gl4_QEva.d.ts → codec-8p40WdLg.d.ts} +20 -1
- package/dist/{codec-Dl_QIXMz.d.ts → codec-BN2Bu0KI.d.ts} +20 -1
- package/dist/{codec-Bux_Q40X.d.ts → codec-Bb6GKTrv.d.ts} +21 -2
- package/dist/{codec-EvybrBuY.d.cts → codec-BgpfHoAd.d.cts} +20 -1
- package/dist/{codec-alVA27Uc.d.ts → codec-BkheTXO7.d.ts} +20 -1
- package/dist/{codec-Czejcmxr.d.cts → codec-BwVDkokh.d.cts} +21 -2
- package/dist/{codec-BrTi4K7r.d.cts → codec-C5s1eBJX.d.cts} +21 -2
- package/dist/codec-CM5yd6n3.d.ts +38 -0
- package/dist/{codec-CWnf8mn_.d.cts → codec-Cb8HC3XV.d.cts} +21 -2
- package/dist/codec-Clu_skx8.d.cts +38 -0
- package/dist/{codec-DzkdW4kO.d.cts → codec-CpOpemR8.d.cts} +20 -1
- package/dist/{codec-CXCjya_G.d.cts → codec-Cshdl9Tt.d.cts} +20 -1
- package/dist/{codec-f7vxeVIS.d.cts → codec-DELe00w_.d.cts} +21 -2
- package/dist/{codec-DNmiG2e0.d.cts → codec-DHzKAUCa.d.cts} +20 -1
- package/dist/{codec--CVeqGQv.d.ts → codec-DdVBtvx7.d.ts} +20 -1
- package/dist/{codec-CBdOIfMY.d.ts → codec-DlxGuYMv.d.ts} +21 -2
- package/dist/{codec-BNy5syCU.d.ts → codec-DxtgPxJS.d.ts} +20 -1
- package/dist/{codec-guzqtfMk.d.cts → codec-GAY4lybi.d.cts} +20 -1
- package/dist/{codec-Cfo_z5ET.d.cts → codec-I8u2pfS4.d.cts} +20 -1
- package/dist/{codec-BxQTybUX.d.cts → codec-XLrnreeu.d.cts} +21 -2
- package/dist/{codec-DOmAmFkI.d.ts → codec-c0YEwwWn.d.ts} +20 -1
- package/dist/{codec-DaXjRrOV.d.ts → codec-ejDu-va6.d.ts} +21 -2
- package/dist/{codec-C3mdsGx3.d.ts → codec-kaBUzdpV.d.ts} +21 -2
- package/dist/{codec-CwZ6OCPP.d.ts → codec-mVYqkIUF.d.ts} +21 -2
- package/dist/{codec-08ZOr5wI.d.ts → codec-qSbO5nOa.d.ts} +21 -2
- package/dist/{codec-Cm3D261p.d.ts → codec-yYKGOipj.d.ts} +20 -1
- package/dist/{codec-Bd60SGKH.d.cts → codec-zfzg9uiy.d.cts} +20 -1
- package/dist/draft07.cjs +48 -4
- package/dist/draft07.d.cts +42 -2
- package/dist/draft07.d.ts +42 -2
- package/dist/draft07.js +49 -5
- package/dist/draft08.cjs +76 -3
- package/dist/draft08.d.cts +70 -2
- package/dist/draft08.d.ts +70 -2
- package/dist/draft08.js +77 -4
- package/dist/draft09.cjs +76 -3
- package/dist/draft09.d.cts +70 -2
- package/dist/draft09.d.ts +70 -2
- package/dist/draft09.js +77 -4
- package/dist/draft10.cjs +76 -3
- package/dist/draft10.d.cts +70 -2
- package/dist/draft10.d.ts +70 -2
- package/dist/draft10.js +77 -4
- package/dist/draft11.cjs +104 -3
- package/dist/draft11.d.cts +98 -2
- package/dist/draft11.d.ts +98 -2
- package/dist/draft11.js +105 -4
- package/dist/draft12.cjs +113 -3
- package/dist/draft12.d.cts +107 -2
- package/dist/draft12.d.ts +107 -2
- package/dist/draft12.js +114 -4
- package/dist/draft13.cjs +105 -3
- package/dist/draft13.d.cts +99 -2
- package/dist/draft13.d.ts +99 -2
- package/dist/draft13.js +106 -4
- package/dist/draft14.cjs +107 -3
- package/dist/draft14.d.cts +101 -28
- package/dist/draft14.d.ts +101 -28
- package/dist/draft14.js +108 -4
- package/dist/draft15-session.d.cts +1 -1
- package/dist/draft15-session.d.ts +1 -1
- package/dist/draft15.cjs +69 -3
- package/dist/draft15.d.cts +65 -22
- package/dist/draft15.d.ts +65 -22
- package/dist/draft15.js +70 -4
- package/dist/draft16-session.cjs +2 -2
- package/dist/draft16-session.d.cts +1 -1
- package/dist/draft16-session.d.ts +1 -1
- package/dist/draft16-session.js +1 -1
- package/dist/draft16.cjs +76 -8
- package/dist/draft16.d.cts +67 -13
- package/dist/draft16.d.ts +67 -13
- package/dist/draft16.js +73 -5
- package/dist/draft17-session.d.cts +1 -1
- package/dist/draft17-session.d.ts +1 -1
- package/dist/draft17.cjs +77 -3
- package/dist/draft17.d.cts +73 -4
- package/dist/draft17.d.ts +73 -4
- package/dist/draft17.js +78 -4
- package/dist/draft18-session.d.cts +1 -1
- package/dist/draft18-session.d.ts +1 -1
- package/dist/draft18.cjs +8 -3
- package/dist/draft18.d.cts +4 -3
- package/dist/draft18.d.ts +4 -3
- package/dist/draft18.js +9 -4
- package/dist/draft19-session.d.cts +1 -1
- package/dist/draft19-session.d.ts +1 -1
- package/dist/draft19.cjs +11 -4
- package/dist/draft19.d.cts +4 -3
- package/dist/draft19.d.ts +4 -3
- package/dist/draft19.js +12 -5
- package/dist/draft20-session.d.cts +1 -1
- package/dist/draft20-session.d.ts +1 -1
- package/dist/draft20.cjs +8 -3
- package/dist/draft20.d.cts +4 -3
- package/dist/draft20.d.ts +4 -3
- package/dist/draft20.js +9 -4
- package/dist/index.cjs +30 -30
- package/dist/index.d.cts +21 -20
- package/dist/index.d.ts +21 -20
- package/dist/index.js +15 -15
- package/dist/session.cjs +2 -2
- package/dist/session.d.cts +6 -6
- package/dist/session.d.ts +6 -6
- package/dist/session.js +1 -1
- package/dist/{types-C1rxh-id.d.cts → types-Btp416jt.d.cts} +8 -0
- package/dist/{types-C1rxh-id.d.ts → types-Btp416jt.d.ts} +8 -0
- package/dist/{types-CZTzbIzQ.d.cts → types-BxTL1NXw.d.cts} +7 -0
- package/dist/{types-CZTzbIzQ.d.ts → types-BxTL1NXw.d.ts} +7 -0
- package/dist/{types-pShrs3fN.d.cts → types-CuibHYcf.d.cts} +7 -0
- package/dist/{types-pShrs3fN.d.ts → types-CuibHYcf.d.ts} +7 -0
- package/dist/{types-CY-QWxd-.d.cts → types-CwN7AEoL.d.cts} +13 -1
- package/dist/{types-CY-QWxd-.d.ts → types-CwN7AEoL.d.ts} +13 -1
- package/dist/{types-D4bmW8rY.d.cts → types-DAnalt5K.d.cts} +7 -0
- package/dist/{types-D4bmW8rY.d.ts → types-DAnalt5K.d.ts} +7 -0
- package/dist/{types-Bg86GGVZ.d.cts → types-DxXNP32l.d.cts} +8 -0
- package/dist/{types-Bg86GGVZ.d.ts → types-DxXNP32l.d.ts} +8 -0
- package/package.json +3 -3
- package/src/core/auth-redaction.ts +192 -0
- package/src/drafts/draft07/codec.ts +40 -0
- package/src/drafts/draft07/error-codes.ts +44 -0
- package/src/drafts/draft07/index.ts +15 -0
- package/src/drafts/draft08/codec.ts +40 -0
- package/src/drafts/draft08/error-codes.ts +76 -0
- package/src/drafts/draft08/index.ts +21 -0
- package/src/drafts/draft09/codec.ts +40 -0
- package/src/drafts/draft09/error-codes.ts +76 -0
- package/src/drafts/draft09/index.ts +21 -0
- package/src/drafts/draft10/codec.ts +40 -0
- package/src/drafts/draft10/error-codes.ts +76 -0
- package/src/drafts/draft10/index.ts +21 -0
- package/src/drafts/draft11/codec.ts +60 -0
- package/src/drafts/draft11/error-codes.ts +106 -0
- package/src/drafts/draft11/index.ts +23 -0
- package/src/drafts/draft12/codec.ts +61 -0
- package/src/drafts/draft12/error-codes.ts +116 -0
- package/src/drafts/draft12/index.ts +25 -0
- package/src/drafts/draft13/codec.ts +69 -11
- package/src/drafts/draft13/error-codes.ts +107 -0
- package/src/drafts/draft13/index.ts +23 -0
- package/src/drafts/draft13/types.ts +1 -1
- package/src/drafts/draft14/codec.ts +65 -4
- package/src/drafts/draft14/data-streams.ts +331 -259
- package/src/drafts/draft14/error-codes.ts +109 -0
- package/src/drafts/draft14/index.ts +23 -0
- package/src/drafts/draft15/codec.ts +65 -8
- package/src/drafts/draft15/data-streams.ts +489 -444
- package/src/drafts/draft15/error-codes.ts +66 -0
- package/src/drafts/draft15/index.ts +15 -0
- package/src/drafts/draft15/types.ts +7 -0
- package/src/drafts/draft16/codec.ts +146 -52
- package/src/drafts/draft16/data-streams.ts +513 -442
- package/src/drafts/draft16/error-codes.ts +68 -0
- package/src/drafts/draft16/index.ts +15 -0
- package/src/drafts/draft16/messages.ts +4 -4
- package/src/drafts/draft16/session-fsm.ts +0 -1
- package/src/drafts/draft16/types.ts +22 -8
- package/src/drafts/draft17/codec.ts +73 -12
- package/src/drafts/draft17/data-streams.ts +567 -488
- package/src/drafts/draft17/index.ts +15 -0
- package/src/drafts/draft17/types.ts +7 -0
- package/src/drafts/draft18/codec.ts +66 -9
- package/src/drafts/draft18/data-streams.ts +570 -482
- package/src/drafts/draft18/index.ts +3 -0
- package/src/drafts/draft18/types.ts +16 -8
- package/src/drafts/draft19/codec.ts +70 -10
- package/src/drafts/draft19/data-streams.ts +570 -482
- package/src/drafts/draft19/error-codes.ts +3 -1
- package/src/drafts/draft19/index.ts +3 -0
- package/src/drafts/draft19/messages.ts +3 -1
- package/src/drafts/draft19/types.ts +22 -11
- package/src/drafts/draft20/codec.ts +90 -23
- package/src/drafts/draft20/data-streams.ts +610 -563
- package/src/drafts/draft20/index.ts +3 -0
- package/src/drafts/draft20/types.ts +14 -2
- package/dist/codec-BJ7BHuiZ.d.ts +0 -18
- package/dist/codec-C6Mx4bwz.d.cts +0 -18
|
@@ -3,8 +3,10 @@ import {
|
|
|
3
3
|
MoqtBufferReader,
|
|
4
4
|
MoqtBufferWriter,
|
|
5
5
|
bytesToHex,
|
|
6
|
-
hexToBytes
|
|
7
|
-
|
|
6
|
+
hexToBytes,
|
|
7
|
+
recordAuthValueSpan,
|
|
8
|
+
redactWith
|
|
9
|
+
} from "./chunk-YRZQVNZO.js";
|
|
8
10
|
|
|
9
11
|
// src/drafts/draft18/messages.ts
|
|
10
12
|
var MSG_REQUEST_UPDATE = 0x02n;
|
|
@@ -250,99 +252,108 @@ function encodeFetchStream(stream) {
|
|
|
250
252
|
void prevObjectId;
|
|
251
253
|
return w.finish();
|
|
252
254
|
}
|
|
255
|
+
function readSubgroupHeader(r) {
|
|
256
|
+
const streamType = r.readUint8();
|
|
257
|
+
if (!isValidSubgroupType(streamType)) {
|
|
258
|
+
throw new DecodeError(
|
|
259
|
+
"CONSTRAINT_VIOLATION",
|
|
260
|
+
`Invalid subgroup stream type 0x${streamType.toString(16)}`,
|
|
261
|
+
0
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
const propertiesPresent = (streamType & 1) !== 0;
|
|
265
|
+
const subgroupMode = (streamType & 6) >> 1;
|
|
266
|
+
const hasSubgroupField = subgroupMode === 2;
|
|
267
|
+
const subgroupIsFirstObjId = subgroupMode === 1;
|
|
268
|
+
const endOfGroup = (streamType & 8) !== 0;
|
|
269
|
+
const hasPriority = (streamType & 32) === 0;
|
|
270
|
+
const firstObjectFlag = (streamType & 64) !== 0;
|
|
271
|
+
const trackAlias = r.readVarInt();
|
|
272
|
+
const groupId = r.readVarInt();
|
|
273
|
+
let subgroupId = 0n;
|
|
274
|
+
if (hasSubgroupField) {
|
|
275
|
+
subgroupId = r.readVarInt();
|
|
276
|
+
}
|
|
277
|
+
let publisherPriority = 128;
|
|
278
|
+
if (hasPriority) {
|
|
279
|
+
publisherPriority = r.readUint8();
|
|
280
|
+
}
|
|
281
|
+
return {
|
|
282
|
+
streamType,
|
|
283
|
+
propertiesPresent,
|
|
284
|
+
subgroupIsFirstObjId,
|
|
285
|
+
endOfGroup,
|
|
286
|
+
firstObjectFlag,
|
|
287
|
+
trackAlias,
|
|
288
|
+
groupId,
|
|
289
|
+
subgroupId,
|
|
290
|
+
publisherPriority
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function readSubgroupObject(r, propertiesPresent, isFirst, prevObjectId, base) {
|
|
294
|
+
const byteOffset = base + r.offset;
|
|
295
|
+
const delta = r.readVarInt();
|
|
296
|
+
const objectId = isFirst ? delta : prevObjectId + 1n + delta;
|
|
297
|
+
const extensionData = new Uint8Array(0);
|
|
298
|
+
let objectProperties;
|
|
299
|
+
if (propertiesPresent) {
|
|
300
|
+
const propsLen = Number(r.readVarInt());
|
|
301
|
+
if (propsLen > 0) {
|
|
302
|
+
objectProperties = decodeObjectProperties(r, propsLen);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
const payloadLength = Number(r.readVarInt());
|
|
306
|
+
let payload;
|
|
307
|
+
let status;
|
|
308
|
+
let payloadByteOffset;
|
|
309
|
+
if (payloadLength === 0) {
|
|
310
|
+
status = r.readVarInt();
|
|
311
|
+
payloadByteOffset = base + r.offset;
|
|
312
|
+
payload = new Uint8Array(0);
|
|
313
|
+
} else {
|
|
314
|
+
payloadByteOffset = base + r.offset;
|
|
315
|
+
payload = r.readBytesView(payloadLength);
|
|
316
|
+
}
|
|
317
|
+
const obj = {
|
|
318
|
+
type: "object",
|
|
319
|
+
byteOffset,
|
|
320
|
+
payloadByteOffset,
|
|
321
|
+
objectId,
|
|
322
|
+
payloadLength,
|
|
323
|
+
payload,
|
|
324
|
+
extensionData
|
|
325
|
+
};
|
|
326
|
+
if (status !== void 0) obj.status = status;
|
|
327
|
+
if (objectProperties !== void 0)
|
|
328
|
+
obj.objectProperties = objectProperties;
|
|
329
|
+
return obj;
|
|
330
|
+
}
|
|
253
331
|
function decodeSubgroupStream(bytes) {
|
|
254
332
|
try {
|
|
255
333
|
const r = new MoqtBufferReader(bytes);
|
|
256
|
-
const
|
|
257
|
-
if (!isValidSubgroupType(streamType)) {
|
|
258
|
-
return {
|
|
259
|
-
ok: false,
|
|
260
|
-
error: new DecodeError(
|
|
261
|
-
"CONSTRAINT_VIOLATION",
|
|
262
|
-
`Invalid subgroup stream type 0x${streamType.toString(16)}`,
|
|
263
|
-
0
|
|
264
|
-
)
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
const propertiesPresent = (streamType & 1) !== 0;
|
|
268
|
-
const subgroupMode = (streamType & 6) >> 1;
|
|
269
|
-
const hasSubgroupField = subgroupMode === 2;
|
|
270
|
-
const subgroupIsFirstObjId = subgroupMode === 1;
|
|
271
|
-
const endOfGroup = (streamType & 8) !== 0;
|
|
272
|
-
const hasPriority = (streamType & 32) === 0;
|
|
273
|
-
const firstObject = (streamType & 64) !== 0;
|
|
274
|
-
const trackAlias = r.readVarInt();
|
|
275
|
-
const groupId = r.readVarInt();
|
|
276
|
-
let subgroupId = 0n;
|
|
277
|
-
if (hasSubgroupField) {
|
|
278
|
-
subgroupId = r.readVarInt();
|
|
279
|
-
}
|
|
280
|
-
let publisherPriority = 128;
|
|
281
|
-
if (hasPriority) {
|
|
282
|
-
publisherPriority = r.readUint8();
|
|
283
|
-
}
|
|
334
|
+
const h = readSubgroupHeader(r);
|
|
284
335
|
const objects = [];
|
|
285
336
|
let prevObjectId = -1n;
|
|
286
337
|
let isFirst = true;
|
|
338
|
+
let subgroupId = h.subgroupId;
|
|
287
339
|
while (r.remaining > 0) {
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
if (isFirst) {
|
|
292
|
-
objectId = delta;
|
|
293
|
-
if (subgroupIsFirstObjId) {
|
|
294
|
-
subgroupId = objectId;
|
|
295
|
-
}
|
|
296
|
-
isFirst = false;
|
|
297
|
-
} else {
|
|
298
|
-
objectId = prevObjectId + 1n + delta;
|
|
299
|
-
}
|
|
300
|
-
const extensionData = new Uint8Array(0);
|
|
301
|
-
let objectProperties;
|
|
302
|
-
if (propertiesPresent) {
|
|
303
|
-
const propsLen = Number(r.readVarInt());
|
|
304
|
-
if (propsLen > 0) {
|
|
305
|
-
objectProperties = decodeObjectProperties(r, propsLen);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
const payloadLength = Number(r.readVarInt());
|
|
309
|
-
let payload;
|
|
310
|
-
let status;
|
|
311
|
-
let payloadByteOffset;
|
|
312
|
-
if (payloadLength === 0) {
|
|
313
|
-
status = r.readVarInt();
|
|
314
|
-
payloadByteOffset = r.offset;
|
|
315
|
-
payload = new Uint8Array(0);
|
|
316
|
-
} else {
|
|
317
|
-
payloadByteOffset = r.offset;
|
|
318
|
-
payload = r.readBytesView(payloadLength);
|
|
319
|
-
}
|
|
320
|
-
const obj = {
|
|
321
|
-
type: "object",
|
|
322
|
-
byteOffset,
|
|
323
|
-
payloadByteOffset,
|
|
324
|
-
objectId,
|
|
325
|
-
payloadLength,
|
|
326
|
-
payload,
|
|
327
|
-
extensionData
|
|
328
|
-
};
|
|
329
|
-
if (status !== void 0) obj.status = status;
|
|
330
|
-
if (objectProperties !== void 0)
|
|
331
|
-
obj.objectProperties = objectProperties;
|
|
340
|
+
const obj = readSubgroupObject(r, h.propertiesPresent, isFirst, prevObjectId, 0);
|
|
341
|
+
if (isFirst && h.subgroupIsFirstObjId) subgroupId = obj.objectId;
|
|
342
|
+
isFirst = false;
|
|
332
343
|
objects.push(obj);
|
|
333
|
-
prevObjectId = objectId;
|
|
344
|
+
prevObjectId = obj.objectId;
|
|
334
345
|
}
|
|
335
346
|
const result = {
|
|
336
347
|
type: "subgroup",
|
|
337
|
-
headerType: streamType,
|
|
338
|
-
trackAlias,
|
|
339
|
-
groupId,
|
|
348
|
+
headerType: h.streamType,
|
|
349
|
+
trackAlias: h.trackAlias,
|
|
350
|
+
groupId: h.groupId,
|
|
340
351
|
subgroupId,
|
|
341
|
-
publisherPriority,
|
|
342
|
-
objects
|
|
352
|
+
publisherPriority: h.publisherPriority,
|
|
353
|
+
objects,
|
|
354
|
+
...h.endOfGroup ? { endOfGroup: true } : {},
|
|
355
|
+
...h.firstObjectFlag ? { firstObject: true } : {}
|
|
343
356
|
};
|
|
344
|
-
if (endOfGroup) result.endOfGroup = true;
|
|
345
|
-
if (firstObject) result.firstObject = true;
|
|
346
357
|
return {
|
|
347
358
|
ok: true,
|
|
348
359
|
value: result,
|
|
@@ -409,6 +420,178 @@ function decodeDatagram(bytes) {
|
|
|
409
420
|
throw e;
|
|
410
421
|
}
|
|
411
422
|
}
|
|
423
|
+
function newFetchObjectState() {
|
|
424
|
+
return { prevGroupId: 0n, prevSubgroupId: 0n, prevObjectId: 0n, prevPriority: 128, first: true };
|
|
425
|
+
}
|
|
426
|
+
function readFetchObject(r, base, st) {
|
|
427
|
+
const byteOffset = base + r.offset;
|
|
428
|
+
const flags = Number(r.readVarInt());
|
|
429
|
+
let groupId = st.prevGroupId;
|
|
430
|
+
let subgroupId = st.prevSubgroupId;
|
|
431
|
+
let objectId = st.prevObjectId + 1n;
|
|
432
|
+
let payloadLength;
|
|
433
|
+
let payload;
|
|
434
|
+
let payloadByteOffset;
|
|
435
|
+
const extensionData = new Uint8Array(0);
|
|
436
|
+
if (flags >= 128) {
|
|
437
|
+
if (flags !== 140 && flags !== 268) {
|
|
438
|
+
throw new DecodeError(
|
|
439
|
+
"CONSTRAINT_VIOLATION",
|
|
440
|
+
`Unknown serialization flags value: 0x${flags.toString(16)}`,
|
|
441
|
+
r.offset
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
groupId = r.readVarInt();
|
|
445
|
+
objectId = r.readVarInt();
|
|
446
|
+
payloadLength = Number(r.readVarInt());
|
|
447
|
+
payloadByteOffset = base + r.offset;
|
|
448
|
+
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
449
|
+
} else if (flags & 64) {
|
|
450
|
+
const objectIdPresent = (flags & 4) !== 0;
|
|
451
|
+
const groupIdPresent = (flags & 8) !== 0;
|
|
452
|
+
const priorityPresent = (flags & 16) !== 0;
|
|
453
|
+
const propsPresent = (flags & 32) !== 0;
|
|
454
|
+
if (groupIdPresent) {
|
|
455
|
+
const groupDelta = r.readVarInt();
|
|
456
|
+
groupId = st.first ? groupDelta : st.prevGroupId + groupDelta + 1n;
|
|
457
|
+
}
|
|
458
|
+
if (objectIdPresent) {
|
|
459
|
+
objectId = r.readVarInt();
|
|
460
|
+
}
|
|
461
|
+
if (priorityPresent) {
|
|
462
|
+
st.prevPriority = r.readUint8();
|
|
463
|
+
}
|
|
464
|
+
let objectProperties;
|
|
465
|
+
if (propsPresent) {
|
|
466
|
+
const propsLen = Number(r.readVarInt());
|
|
467
|
+
if (propsLen > 0) {
|
|
468
|
+
objectProperties = decodeObjectProperties(r, propsLen);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
payloadLength = Number(r.readVarInt());
|
|
472
|
+
payloadByteOffset = base + r.offset;
|
|
473
|
+
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
474
|
+
const obj2 = {
|
|
475
|
+
type: "object",
|
|
476
|
+
byteOffset,
|
|
477
|
+
payloadByteOffset,
|
|
478
|
+
serializationFlags: flags,
|
|
479
|
+
groupId,
|
|
480
|
+
subgroupId: 0n,
|
|
481
|
+
objectId,
|
|
482
|
+
publisherPriority: st.prevPriority,
|
|
483
|
+
payloadLength,
|
|
484
|
+
payload,
|
|
485
|
+
extensionData
|
|
486
|
+
};
|
|
487
|
+
if (objectProperties)
|
|
488
|
+
obj2.objectProperties = objectProperties;
|
|
489
|
+
st.prevGroupId = groupId;
|
|
490
|
+
st.prevObjectId = objectId;
|
|
491
|
+
st.first = false;
|
|
492
|
+
return obj2;
|
|
493
|
+
} else {
|
|
494
|
+
const subgroupEncoding = flags & 3;
|
|
495
|
+
const objectIdPresent = (flags & 4) !== 0;
|
|
496
|
+
const groupIdPresent = (flags & 8) !== 0;
|
|
497
|
+
const priorityPresent = (flags & 16) !== 0;
|
|
498
|
+
const propsPresent = (flags & 32) !== 0;
|
|
499
|
+
if (groupIdPresent) {
|
|
500
|
+
const groupDelta = r.readVarInt();
|
|
501
|
+
groupId = st.first ? groupDelta : st.prevGroupId + groupDelta + 1n;
|
|
502
|
+
} else if (st.first) {
|
|
503
|
+
throw new DecodeError(
|
|
504
|
+
"CONSTRAINT_VIOLATION",
|
|
505
|
+
"First fetch object must include groupId",
|
|
506
|
+
r.offset
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
if (subgroupEncoding === 0) {
|
|
510
|
+
subgroupId = 0n;
|
|
511
|
+
} else if (subgroupEncoding === 1) {
|
|
512
|
+
if (st.first) {
|
|
513
|
+
throw new DecodeError(
|
|
514
|
+
"CONSTRAINT_VIOLATION",
|
|
515
|
+
"First fetch object cannot reference prior subgroupId",
|
|
516
|
+
r.offset
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
subgroupId = st.prevSubgroupId;
|
|
520
|
+
} else if (subgroupEncoding === 2) {
|
|
521
|
+
if (st.first) {
|
|
522
|
+
throw new DecodeError(
|
|
523
|
+
"CONSTRAINT_VIOLATION",
|
|
524
|
+
"First fetch object cannot reference prior subgroupId",
|
|
525
|
+
r.offset
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
subgroupId = st.prevSubgroupId + 1n;
|
|
529
|
+
} else if (subgroupEncoding === 3) {
|
|
530
|
+
subgroupId = r.readVarInt();
|
|
531
|
+
}
|
|
532
|
+
if (objectIdPresent) {
|
|
533
|
+
objectId = r.readVarInt();
|
|
534
|
+
} else if (st.first) {
|
|
535
|
+
throw new DecodeError(
|
|
536
|
+
"CONSTRAINT_VIOLATION",
|
|
537
|
+
"First fetch object must include objectId",
|
|
538
|
+
r.offset
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
if (priorityPresent) {
|
|
542
|
+
st.prevPriority = r.readUint8();
|
|
543
|
+
}
|
|
544
|
+
let objectProperties;
|
|
545
|
+
if (propsPresent) {
|
|
546
|
+
const propsLen = Number(r.readVarInt());
|
|
547
|
+
if (propsLen > 0) {
|
|
548
|
+
objectProperties = decodeObjectProperties(r, propsLen);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
payloadLength = Number(r.readVarInt());
|
|
552
|
+
payloadByteOffset = base + r.offset;
|
|
553
|
+
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
554
|
+
if (objectProperties) {
|
|
555
|
+
const obj2 = {
|
|
556
|
+
type: "object",
|
|
557
|
+
byteOffset,
|
|
558
|
+
payloadByteOffset,
|
|
559
|
+
serializationFlags: flags,
|
|
560
|
+
groupId,
|
|
561
|
+
subgroupId,
|
|
562
|
+
objectId,
|
|
563
|
+
publisherPriority: st.prevPriority,
|
|
564
|
+
payloadLength,
|
|
565
|
+
payload,
|
|
566
|
+
extensionData
|
|
567
|
+
};
|
|
568
|
+
obj2.objectProperties = objectProperties;
|
|
569
|
+
st.prevGroupId = groupId;
|
|
570
|
+
st.prevSubgroupId = subgroupId;
|
|
571
|
+
st.prevObjectId = objectId;
|
|
572
|
+
st.first = false;
|
|
573
|
+
return obj2;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
const obj = {
|
|
577
|
+
type: "object",
|
|
578
|
+
byteOffset,
|
|
579
|
+
payloadByteOffset,
|
|
580
|
+
serializationFlags: flags,
|
|
581
|
+
groupId,
|
|
582
|
+
subgroupId,
|
|
583
|
+
objectId,
|
|
584
|
+
publisherPriority: st.prevPriority,
|
|
585
|
+
payloadLength,
|
|
586
|
+
payload,
|
|
587
|
+
extensionData
|
|
588
|
+
};
|
|
589
|
+
st.prevGroupId = groupId;
|
|
590
|
+
st.prevSubgroupId = subgroupId;
|
|
591
|
+
st.prevObjectId = objectId;
|
|
592
|
+
st.first = false;
|
|
593
|
+
return obj;
|
|
594
|
+
}
|
|
412
595
|
function decodeFetchStream(bytes) {
|
|
413
596
|
try {
|
|
414
597
|
const r = new MoqtBufferReader(bytes);
|
|
@@ -425,196 +608,9 @@ function decodeFetchStream(bytes) {
|
|
|
425
608
|
}
|
|
426
609
|
const requestId = r.readVarInt();
|
|
427
610
|
const objects = [];
|
|
428
|
-
|
|
429
|
-
let prevSubgroupId = 0n;
|
|
430
|
-
let prevObjectId = 0n;
|
|
431
|
-
let prevPriority = 128;
|
|
432
|
-
let first = true;
|
|
611
|
+
const st = newFetchObjectState();
|
|
433
612
|
while (r.remaining > 0) {
|
|
434
|
-
|
|
435
|
-
const flags = Number(r.readVarInt());
|
|
436
|
-
let groupId = prevGroupId;
|
|
437
|
-
let subgroupId = prevSubgroupId;
|
|
438
|
-
let objectId = prevObjectId + 1n;
|
|
439
|
-
let payloadLength;
|
|
440
|
-
let payload;
|
|
441
|
-
let payloadByteOffset;
|
|
442
|
-
const extensionData = new Uint8Array(0);
|
|
443
|
-
if (flags >= 128) {
|
|
444
|
-
if (flags !== 140 && flags !== 268) {
|
|
445
|
-
return {
|
|
446
|
-
ok: false,
|
|
447
|
-
error: new DecodeError(
|
|
448
|
-
"CONSTRAINT_VIOLATION",
|
|
449
|
-
`Unknown serialization flags value: 0x${flags.toString(16)}`,
|
|
450
|
-
r.offset
|
|
451
|
-
)
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
groupId = r.readVarInt();
|
|
455
|
-
objectId = r.readVarInt();
|
|
456
|
-
payloadLength = Number(r.readVarInt());
|
|
457
|
-
payloadByteOffset = r.offset;
|
|
458
|
-
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
459
|
-
} else if (flags & 64) {
|
|
460
|
-
const objectIdPresent = (flags & 4) !== 0;
|
|
461
|
-
const groupIdPresent = (flags & 8) !== 0;
|
|
462
|
-
const priorityPresent = (flags & 16) !== 0;
|
|
463
|
-
const propsPresent = (flags & 32) !== 0;
|
|
464
|
-
if (groupIdPresent) {
|
|
465
|
-
const groupDelta = r.readVarInt();
|
|
466
|
-
groupId = first ? groupDelta : prevGroupId + groupDelta + 1n;
|
|
467
|
-
}
|
|
468
|
-
if (objectIdPresent) {
|
|
469
|
-
objectId = r.readVarInt();
|
|
470
|
-
}
|
|
471
|
-
if (priorityPresent) {
|
|
472
|
-
prevPriority = r.readUint8();
|
|
473
|
-
}
|
|
474
|
-
let objectProperties;
|
|
475
|
-
if (propsPresent) {
|
|
476
|
-
const propsLen = Number(r.readVarInt());
|
|
477
|
-
if (propsLen > 0) {
|
|
478
|
-
objectProperties = decodeObjectProperties(r, propsLen);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
payloadLength = Number(r.readVarInt());
|
|
482
|
-
payloadByteOffset = r.offset;
|
|
483
|
-
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
484
|
-
const obj2 = {
|
|
485
|
-
type: "object",
|
|
486
|
-
byteOffset,
|
|
487
|
-
payloadByteOffset,
|
|
488
|
-
serializationFlags: flags,
|
|
489
|
-
groupId,
|
|
490
|
-
subgroupId: 0n,
|
|
491
|
-
objectId,
|
|
492
|
-
publisherPriority: prevPriority,
|
|
493
|
-
payloadLength,
|
|
494
|
-
payload,
|
|
495
|
-
extensionData
|
|
496
|
-
};
|
|
497
|
-
if (objectProperties)
|
|
498
|
-
obj2.objectProperties = objectProperties;
|
|
499
|
-
objects.push(obj2);
|
|
500
|
-
prevGroupId = groupId;
|
|
501
|
-
prevObjectId = objectId;
|
|
502
|
-
first = false;
|
|
503
|
-
continue;
|
|
504
|
-
} else {
|
|
505
|
-
const subgroupEncoding = flags & 3;
|
|
506
|
-
const objectIdPresent = (flags & 4) !== 0;
|
|
507
|
-
const groupIdPresent = (flags & 8) !== 0;
|
|
508
|
-
const priorityPresent = (flags & 16) !== 0;
|
|
509
|
-
const propsPresent = (flags & 32) !== 0;
|
|
510
|
-
if (groupIdPresent) {
|
|
511
|
-
const groupDelta = r.readVarInt();
|
|
512
|
-
groupId = first ? groupDelta : prevGroupId + groupDelta + 1n;
|
|
513
|
-
} else if (first) {
|
|
514
|
-
return {
|
|
515
|
-
ok: false,
|
|
516
|
-
error: new DecodeError(
|
|
517
|
-
"CONSTRAINT_VIOLATION",
|
|
518
|
-
"First fetch object must include groupId",
|
|
519
|
-
r.offset
|
|
520
|
-
)
|
|
521
|
-
};
|
|
522
|
-
}
|
|
523
|
-
if (subgroupEncoding === 0) {
|
|
524
|
-
subgroupId = 0n;
|
|
525
|
-
} else if (subgroupEncoding === 1) {
|
|
526
|
-
if (first) {
|
|
527
|
-
return {
|
|
528
|
-
ok: false,
|
|
529
|
-
error: new DecodeError(
|
|
530
|
-
"CONSTRAINT_VIOLATION",
|
|
531
|
-
"First fetch object cannot reference prior subgroupId",
|
|
532
|
-
r.offset
|
|
533
|
-
)
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
subgroupId = prevSubgroupId;
|
|
537
|
-
} else if (subgroupEncoding === 2) {
|
|
538
|
-
if (first) {
|
|
539
|
-
return {
|
|
540
|
-
ok: false,
|
|
541
|
-
error: new DecodeError(
|
|
542
|
-
"CONSTRAINT_VIOLATION",
|
|
543
|
-
"First fetch object cannot reference prior subgroupId",
|
|
544
|
-
r.offset
|
|
545
|
-
)
|
|
546
|
-
};
|
|
547
|
-
}
|
|
548
|
-
subgroupId = prevSubgroupId + 1n;
|
|
549
|
-
} else if (subgroupEncoding === 3) {
|
|
550
|
-
subgroupId = r.readVarInt();
|
|
551
|
-
}
|
|
552
|
-
if (objectIdPresent) {
|
|
553
|
-
objectId = r.readVarInt();
|
|
554
|
-
} else if (first) {
|
|
555
|
-
return {
|
|
556
|
-
ok: false,
|
|
557
|
-
error: new DecodeError(
|
|
558
|
-
"CONSTRAINT_VIOLATION",
|
|
559
|
-
"First fetch object must include objectId",
|
|
560
|
-
r.offset
|
|
561
|
-
)
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
if (priorityPresent) {
|
|
565
|
-
prevPriority = r.readUint8();
|
|
566
|
-
}
|
|
567
|
-
let objectProperties;
|
|
568
|
-
if (propsPresent) {
|
|
569
|
-
const propsLen = Number(r.readVarInt());
|
|
570
|
-
if (propsLen > 0) {
|
|
571
|
-
objectProperties = decodeObjectProperties(r, propsLen);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
payloadLength = Number(r.readVarInt());
|
|
575
|
-
payloadByteOffset = r.offset;
|
|
576
|
-
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
577
|
-
if (objectProperties) {
|
|
578
|
-
const obj2 = {
|
|
579
|
-
type: "object",
|
|
580
|
-
byteOffset,
|
|
581
|
-
payloadByteOffset,
|
|
582
|
-
serializationFlags: flags,
|
|
583
|
-
groupId,
|
|
584
|
-
subgroupId,
|
|
585
|
-
objectId,
|
|
586
|
-
publisherPriority: prevPriority,
|
|
587
|
-
payloadLength,
|
|
588
|
-
payload,
|
|
589
|
-
extensionData
|
|
590
|
-
};
|
|
591
|
-
obj2.objectProperties = objectProperties;
|
|
592
|
-
objects.push(obj2);
|
|
593
|
-
prevGroupId = groupId;
|
|
594
|
-
prevSubgroupId = subgroupId;
|
|
595
|
-
prevObjectId = objectId;
|
|
596
|
-
first = false;
|
|
597
|
-
continue;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
const obj = {
|
|
601
|
-
type: "object",
|
|
602
|
-
byteOffset,
|
|
603
|
-
payloadByteOffset,
|
|
604
|
-
serializationFlags: flags,
|
|
605
|
-
groupId,
|
|
606
|
-
subgroupId,
|
|
607
|
-
objectId,
|
|
608
|
-
publisherPriority: prevPriority,
|
|
609
|
-
payloadLength,
|
|
610
|
-
payload,
|
|
611
|
-
extensionData
|
|
612
|
-
};
|
|
613
|
-
objects.push(obj);
|
|
614
|
-
prevGroupId = groupId;
|
|
615
|
-
prevSubgroupId = subgroupId;
|
|
616
|
-
prevObjectId = objectId;
|
|
617
|
-
first = false;
|
|
613
|
+
objects.push(readFetchObject(r, 0, st));
|
|
618
614
|
}
|
|
619
615
|
return {
|
|
620
616
|
ok: true,
|
|
@@ -640,60 +636,70 @@ function decodeDataStream(streamType, bytes) {
|
|
|
640
636
|
}
|
|
641
637
|
}
|
|
642
638
|
}
|
|
639
|
+
var StreamBuffer = class {
|
|
640
|
+
buf = new Uint8Array(0);
|
|
641
|
+
/** Bytes written into `buf`. */
|
|
642
|
+
len = 0;
|
|
643
|
+
/** Consumed prefix of `buf`; `base + offset` is the position in the stream. */
|
|
644
|
+
offset = 0;
|
|
645
|
+
/** Absolute position of `buf[0]` within the stream. */
|
|
646
|
+
base = 0;
|
|
647
|
+
get unread() {
|
|
648
|
+
return this.len - this.offset;
|
|
649
|
+
}
|
|
650
|
+
append(chunk) {
|
|
651
|
+
if (this.len + chunk.length > this.buf.length) {
|
|
652
|
+
const live = this.len - this.offset;
|
|
653
|
+
const needed = live + chunk.length;
|
|
654
|
+
let cap = Math.max(4096, this.buf.length);
|
|
655
|
+
while (cap < needed * 2) cap *= 2;
|
|
656
|
+
const next = new Uint8Array(cap);
|
|
657
|
+
next.set(this.buf.subarray(this.offset, this.len), 0);
|
|
658
|
+
this.buf = next;
|
|
659
|
+
this.base += this.offset;
|
|
660
|
+
this.len = live;
|
|
661
|
+
this.offset = 0;
|
|
662
|
+
}
|
|
663
|
+
this.buf.set(chunk, this.len);
|
|
664
|
+
this.len += chunk.length;
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* The written bytes, for a reader positioned at `offset`. Bounded by `len`
|
|
668
|
+
* rather than by capacity, so `BufferReader.remaining` counts real bytes and
|
|
669
|
+
* not the spare room after them.
|
|
670
|
+
*/
|
|
671
|
+
written() {
|
|
672
|
+
return this.buf.subarray(0, this.len);
|
|
673
|
+
}
|
|
674
|
+
};
|
|
643
675
|
function createSubgroupStreamDecoder() {
|
|
644
|
-
|
|
645
|
-
let
|
|
676
|
+
const b = new StreamBuffer();
|
|
677
|
+
let header = null;
|
|
646
678
|
let headerEmitted = false;
|
|
647
679
|
let prevObjectId = -1n;
|
|
648
|
-
let
|
|
649
|
-
|
|
680
|
+
let isFirst = true;
|
|
681
|
+
function emitHeader(controller, h, subgroupId) {
|
|
682
|
+
controller.enqueue({
|
|
683
|
+
type: "subgroup_header",
|
|
684
|
+
headerType: h.streamType,
|
|
685
|
+
trackAlias: h.trackAlias,
|
|
686
|
+
groupId: h.groupId,
|
|
687
|
+
subgroupId,
|
|
688
|
+
publisherPriority: h.publisherPriority,
|
|
689
|
+
...h.endOfGroup ? { endOfGroup: true } : {},
|
|
690
|
+
...h.firstObjectFlag ? { firstObject: true } : {}
|
|
691
|
+
});
|
|
692
|
+
headerEmitted = true;
|
|
693
|
+
}
|
|
650
694
|
return new TransformStream({
|
|
651
695
|
transform(chunk, controller) {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
}
|
|
656
|
-
const newBuffer = new Uint8Array(buffer.length + chunk.length);
|
|
657
|
-
newBuffer.set(buffer, 0);
|
|
658
|
-
newBuffer.set(chunk, buffer.length);
|
|
659
|
-
buffer = newBuffer;
|
|
660
|
-
if (!headerEmitted) {
|
|
696
|
+
b.append(chunk);
|
|
697
|
+
const view = b.written();
|
|
698
|
+
if (header === null) {
|
|
661
699
|
try {
|
|
662
|
-
const
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
controller.error(
|
|
666
|
-
new DecodeError(
|
|
667
|
-
"CONSTRAINT_VIOLATION",
|
|
668
|
-
`Invalid subgroup stream type 0x${streamType.toString(16)}`,
|
|
669
|
-
0
|
|
670
|
-
)
|
|
671
|
-
);
|
|
672
|
-
return;
|
|
673
|
-
}
|
|
674
|
-
_propertiesPresent = (streamType & 1) !== 0;
|
|
675
|
-
const subgroupMode = (streamType & 6) >> 1;
|
|
676
|
-
const hasSubgroupField = subgroupMode === 2;
|
|
677
|
-
const hasPriority = (streamType & 32) === 0;
|
|
678
|
-
const trackAlias = r.readVarInt();
|
|
679
|
-
const groupId = r.readVarInt();
|
|
680
|
-
let subgroupId = 0n;
|
|
681
|
-
if (hasSubgroupField) {
|
|
682
|
-
subgroupId = r.readVarInt();
|
|
683
|
-
}
|
|
684
|
-
let publisherPriority = 128;
|
|
685
|
-
if (hasPriority) {
|
|
686
|
-
publisherPriority = r.readUint8();
|
|
687
|
-
}
|
|
688
|
-
controller.enqueue({
|
|
689
|
-
type: "subgroup_header",
|
|
690
|
-
trackAlias,
|
|
691
|
-
groupId,
|
|
692
|
-
subgroupId,
|
|
693
|
-
publisherPriority
|
|
694
|
-
});
|
|
695
|
-
headerEmitted = true;
|
|
696
|
-
offset += r.offset;
|
|
700
|
+
const hr = new MoqtBufferReader(view, b.offset);
|
|
701
|
+
header = readSubgroupHeader(hr);
|
|
702
|
+
b.offset = hr.offset;
|
|
697
703
|
} catch (e) {
|
|
698
704
|
if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
|
|
699
705
|
return;
|
|
@@ -701,71 +707,51 @@ function createSubgroupStreamDecoder() {
|
|
|
701
707
|
controller.error(e);
|
|
702
708
|
return;
|
|
703
709
|
}
|
|
710
|
+
if (!header.subgroupIsFirstObjId) emitHeader(controller, header, header.subgroupId);
|
|
704
711
|
}
|
|
705
|
-
|
|
712
|
+
const h = header;
|
|
713
|
+
if (h === null) return;
|
|
714
|
+
const r = new MoqtBufferReader(view, b.offset);
|
|
715
|
+
while (r.remaining > 0) {
|
|
716
|
+
const start = r.offset;
|
|
717
|
+
let obj;
|
|
706
718
|
try {
|
|
707
|
-
|
|
708
|
-
const delta = r.readVarInt();
|
|
709
|
-
let objectId;
|
|
710
|
-
if (firstObject) {
|
|
711
|
-
objectId = delta;
|
|
712
|
-
firstObject = false;
|
|
713
|
-
} else {
|
|
714
|
-
objectId = prevObjectId + 1n + delta;
|
|
715
|
-
}
|
|
716
|
-
let extensionData = new Uint8Array(0);
|
|
717
|
-
if (_propertiesPresent) {
|
|
718
|
-
const extLen = Number(r.readVarInt());
|
|
719
|
-
extensionData = extLen > 0 ? r.readBytesView(extLen) : new Uint8Array(0);
|
|
720
|
-
}
|
|
721
|
-
const payloadLength = Number(r.readVarInt());
|
|
722
|
-
const payloadByteOffset = r.offset;
|
|
723
|
-
const payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
724
|
-
controller.enqueue({
|
|
725
|
-
type: "object",
|
|
726
|
-
objectId,
|
|
727
|
-
payloadLength,
|
|
728
|
-
payload,
|
|
729
|
-
extensionData,
|
|
730
|
-
byteOffset: 0,
|
|
731
|
-
payloadByteOffset
|
|
732
|
-
});
|
|
733
|
-
offset += r.offset;
|
|
734
|
-
prevObjectId = objectId;
|
|
719
|
+
obj = readSubgroupObject(r, h.propertiesPresent, isFirst, prevObjectId, b.base);
|
|
735
720
|
} catch (e) {
|
|
736
721
|
if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
|
|
737
|
-
|
|
722
|
+
b.offset = start;
|
|
723
|
+
return;
|
|
738
724
|
}
|
|
739
725
|
controller.error(e);
|
|
740
726
|
return;
|
|
741
727
|
}
|
|
728
|
+
if (!headerEmitted) emitHeader(controller, h, obj.objectId);
|
|
729
|
+
isFirst = false;
|
|
730
|
+
b.offset = r.offset;
|
|
731
|
+
prevObjectId = obj.objectId;
|
|
732
|
+
controller.enqueue(obj);
|
|
742
733
|
}
|
|
743
734
|
},
|
|
744
735
|
flush(controller) {
|
|
745
|
-
if (
|
|
736
|
+
if (header !== null && !headerEmitted) emitHeader(controller, header, 0n);
|
|
737
|
+
if (b.unread > 0) {
|
|
746
738
|
controller.error(new DecodeError("UNEXPECTED_END", "Stream ended with incomplete data", 0));
|
|
747
739
|
}
|
|
748
740
|
}
|
|
749
741
|
});
|
|
750
742
|
}
|
|
751
743
|
function createFetchStreamDecoder() {
|
|
752
|
-
|
|
753
|
-
let offset = 0;
|
|
744
|
+
const b = new StreamBuffer();
|
|
754
745
|
let headerEmitted = false;
|
|
746
|
+
const st = newFetchObjectState();
|
|
755
747
|
return new TransformStream({
|
|
756
748
|
transform(chunk, controller) {
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
offset = 0;
|
|
760
|
-
}
|
|
761
|
-
const newBuffer = new Uint8Array(buffer.length + chunk.length);
|
|
762
|
-
newBuffer.set(buffer, 0);
|
|
763
|
-
newBuffer.set(chunk, buffer.length);
|
|
764
|
-
buffer = newBuffer;
|
|
749
|
+
b.append(chunk);
|
|
750
|
+
const view = b.written();
|
|
765
751
|
if (!headerEmitted) {
|
|
766
752
|
try {
|
|
767
|
-
const
|
|
768
|
-
const streamType =
|
|
753
|
+
const r2 = new MoqtBufferReader(view, b.offset);
|
|
754
|
+
const streamType = r2.readVarInt();
|
|
769
755
|
if (streamType !== FETCH_STREAM_TYPE) {
|
|
770
756
|
controller.error(
|
|
771
757
|
new DecodeError(
|
|
@@ -776,10 +762,10 @@ function createFetchStreamDecoder() {
|
|
|
776
762
|
);
|
|
777
763
|
return;
|
|
778
764
|
}
|
|
779
|
-
const requestId =
|
|
765
|
+
const requestId = r2.readVarInt();
|
|
780
766
|
controller.enqueue({ type: "fetch_header", requestId });
|
|
781
767
|
headerEmitted = true;
|
|
782
|
-
offset
|
|
768
|
+
b.offset = r2.offset;
|
|
783
769
|
} catch (e) {
|
|
784
770
|
if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
|
|
785
771
|
return;
|
|
@@ -788,99 +774,82 @@ function createFetchStreamDecoder() {
|
|
|
788
774
|
return;
|
|
789
775
|
}
|
|
790
776
|
}
|
|
791
|
-
|
|
777
|
+
const r = new MoqtBufferReader(view, b.offset);
|
|
778
|
+
while (r.remaining > 0) {
|
|
779
|
+
const start = r.offset;
|
|
780
|
+
let obj;
|
|
792
781
|
try {
|
|
793
|
-
|
|
794
|
-
const flags = Number(r.readVarInt());
|
|
795
|
-
const objectIdPresent = (flags & 4) !== 0;
|
|
796
|
-
const groupIdPresent = (flags & 8) !== 0;
|
|
797
|
-
const priorityPresent = (flags & 16) !== 0;
|
|
798
|
-
const extensionsPresent = (flags & 32) !== 0;
|
|
799
|
-
const subgroupEncoding = flags & 3;
|
|
800
|
-
if (groupIdPresent) r.readVarInt();
|
|
801
|
-
if (subgroupEncoding === 3) r.readVarInt();
|
|
802
|
-
let objectId = 0n;
|
|
803
|
-
if (objectIdPresent) objectId = r.readVarInt();
|
|
804
|
-
if (priorityPresent) r.readUint8();
|
|
805
|
-
let extensionData = new Uint8Array(0);
|
|
806
|
-
if (extensionsPresent) {
|
|
807
|
-
const extLen = Number(r.readVarInt());
|
|
808
|
-
extensionData = extLen > 0 ? r.readBytesView(extLen) : new Uint8Array(0);
|
|
809
|
-
}
|
|
810
|
-
const payloadLength = Number(r.readVarInt());
|
|
811
|
-
const payloadByteOffset = r.offset;
|
|
812
|
-
const payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
813
|
-
controller.enqueue({
|
|
814
|
-
type: "object",
|
|
815
|
-
objectId,
|
|
816
|
-
payloadLength,
|
|
817
|
-
payload,
|
|
818
|
-
extensionData,
|
|
819
|
-
byteOffset: 0,
|
|
820
|
-
payloadByteOffset
|
|
821
|
-
});
|
|
822
|
-
offset += r.offset;
|
|
782
|
+
obj = readFetchObject(r, b.base, st);
|
|
823
783
|
} catch (e) {
|
|
824
784
|
if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
|
|
825
|
-
|
|
785
|
+
b.offset = start;
|
|
786
|
+
return;
|
|
826
787
|
}
|
|
827
788
|
controller.error(e);
|
|
828
789
|
return;
|
|
829
790
|
}
|
|
791
|
+
b.offset = r.offset;
|
|
792
|
+
controller.enqueue(obj);
|
|
830
793
|
}
|
|
831
794
|
},
|
|
832
795
|
flush(controller) {
|
|
833
|
-
if (
|
|
796
|
+
if (b.unread > 0) {
|
|
834
797
|
controller.error(new DecodeError("UNEXPECTED_END", "Stream ended with incomplete data", 0));
|
|
835
798
|
}
|
|
836
799
|
}
|
|
837
800
|
});
|
|
838
801
|
}
|
|
839
802
|
function createDataStreamDecoder() {
|
|
840
|
-
let
|
|
841
|
-
let
|
|
842
|
-
let
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
if (
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
const decoder = createSubgroupStreamDecoder();
|
|
858
|
-
inner = decoder;
|
|
859
|
-
} else if (firstByte === 5) {
|
|
860
|
-
const decoder = createFetchStreamDecoder();
|
|
861
|
-
inner = decoder;
|
|
862
|
-
} else {
|
|
863
|
-
controller.error(
|
|
864
|
-
new DecodeError(
|
|
865
|
-
"CONSTRAINT_VIOLATION",
|
|
866
|
-
`Unknown data stream type: 0x${firstByte.toString(16)}`,
|
|
867
|
-
0
|
|
868
|
-
)
|
|
869
|
-
);
|
|
870
|
-
return;
|
|
803
|
+
let writer = null;
|
|
804
|
+
let pump = Promise.resolve();
|
|
805
|
+
let broken = false;
|
|
806
|
+
function attach(inner, controller) {
|
|
807
|
+
writer = inner.writable.getWriter();
|
|
808
|
+
const reader = inner.readable.getReader();
|
|
809
|
+
pump = (async () => {
|
|
810
|
+
try {
|
|
811
|
+
for (; ; ) {
|
|
812
|
+
const { done, value } = await reader.read();
|
|
813
|
+
if (done) break;
|
|
814
|
+
controller.enqueue(value);
|
|
815
|
+
}
|
|
816
|
+
} catch (e) {
|
|
817
|
+
if (!broken) {
|
|
818
|
+
broken = true;
|
|
819
|
+
controller.error(e);
|
|
871
820
|
}
|
|
872
821
|
}
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
822
|
+
})();
|
|
823
|
+
}
|
|
824
|
+
async function feed(bytes) {
|
|
825
|
+
if (writer === null || broken || bytes.length === 0) return;
|
|
826
|
+
try {
|
|
827
|
+
await writer.write(bytes);
|
|
828
|
+
} catch {
|
|
829
|
+
broken = true;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
return new TransformStream({
|
|
833
|
+
async transform(chunk, controller) {
|
|
834
|
+
if (broken) return;
|
|
835
|
+
if (writer !== null) {
|
|
836
|
+
await feed(chunk);
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
if (chunk.length === 0) return;
|
|
840
|
+
const firstByte = chunk[0];
|
|
879
841
|
if (isValidSubgroupType(firstByte)) {
|
|
880
|
-
|
|
842
|
+
attach(
|
|
843
|
+
createSubgroupStreamDecoder(),
|
|
844
|
+
controller
|
|
845
|
+
);
|
|
881
846
|
} else if (firstByte === 5) {
|
|
882
|
-
|
|
847
|
+
attach(
|
|
848
|
+
createFetchStreamDecoder(),
|
|
849
|
+
controller
|
|
850
|
+
);
|
|
883
851
|
} else {
|
|
852
|
+
broken = true;
|
|
884
853
|
controller.error(
|
|
885
854
|
new DecodeError(
|
|
886
855
|
"CONSTRAINT_VIOLATION",
|
|
@@ -890,31 +859,15 @@ function createDataStreamDecoder() {
|
|
|
890
859
|
);
|
|
891
860
|
return;
|
|
892
861
|
}
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
type: "subgroup_header",
|
|
901
|
-
trackAlias: stream.trackAlias,
|
|
902
|
-
groupId: stream.groupId,
|
|
903
|
-
subgroupId: stream.subgroupId,
|
|
904
|
-
publisherPriority: stream.publisherPriority
|
|
905
|
-
});
|
|
906
|
-
for (const obj of stream.objects) {
|
|
907
|
-
controller.enqueue(obj);
|
|
908
|
-
}
|
|
909
|
-
} else if (stream.type === "fetch") {
|
|
910
|
-
controller.enqueue({
|
|
911
|
-
type: "fetch_header",
|
|
912
|
-
requestId: stream.requestId
|
|
913
|
-
});
|
|
914
|
-
for (const obj of stream.objects) {
|
|
915
|
-
controller.enqueue(obj);
|
|
916
|
-
}
|
|
862
|
+
await feed(chunk);
|
|
863
|
+
},
|
|
864
|
+
async flush() {
|
|
865
|
+
if (writer === null) return;
|
|
866
|
+
try {
|
|
867
|
+
await writer.close();
|
|
868
|
+
} catch {
|
|
917
869
|
}
|
|
870
|
+
await pump;
|
|
918
871
|
}
|
|
919
872
|
});
|
|
920
873
|
}
|
|
@@ -1028,10 +981,9 @@ function decodeSetupOptions(reader, payloadEnd) {
|
|
|
1028
981
|
if (optType === SETUP_OPT_PATH) {
|
|
1029
982
|
result.path = textDecoder.decode(bytes);
|
|
1030
983
|
} else if (optType === SETUP_OPT_AUTHORIZATION_TOKEN) {
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
];
|
|
984
|
+
const token = decodeAuthorizationToken(new MoqtBufferReader(bytes));
|
|
985
|
+
noteAuthTokenValue(reader.offset - length, length, token.token_value);
|
|
986
|
+
result.authorization_token = [...result.authorization_token ?? [], token];
|
|
1035
987
|
} else if (optType === SETUP_OPT_AUTHORITY) {
|
|
1036
988
|
result.authority = textDecoder.decode(bytes);
|
|
1037
989
|
} else if (optType === SETUP_OPT_MOQT_IMPLEMENTATION) {
|
|
@@ -1286,10 +1238,9 @@ function decodeParams(reader, messageType) {
|
|
|
1286
1238
|
} else if (paramType === PARAM_AUTHORIZATION_TOKEN) {
|
|
1287
1239
|
const length = Number(reader.readVarInt());
|
|
1288
1240
|
const bytes = reader.readBytes(length);
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
];
|
|
1241
|
+
const token = decodeAuthorizationToken(new MoqtBufferReader(bytes));
|
|
1242
|
+
noteAuthTokenValue(reader.offset - length, length, token.token_value);
|
|
1243
|
+
result.authorization_token = [...result.authorization_token ?? [], token];
|
|
1293
1244
|
} else if (paramType === PARAM_RENDEZVOUS_TIMEOUT) {
|
|
1294
1245
|
result.rendezvous_timeout = reader.readVarInt();
|
|
1295
1246
|
} else if (paramType === PARAM_SUBGROUP_DELIVERY_TIMEOUT) {
|
|
@@ -1965,6 +1916,23 @@ function createDraft18Codec() {
|
|
|
1965
1916
|
createDataStreamDecoder
|
|
1966
1917
|
};
|
|
1967
1918
|
}
|
|
1919
|
+
function noteAuthTokenValue(valueStart, valueLength, value) {
|
|
1920
|
+
if (value === void 0 || value.byteLength === 0) return;
|
|
1921
|
+
recordAuthValueSpan(valueStart + valueLength - value.byteLength, value.byteLength);
|
|
1922
|
+
}
|
|
1923
|
+
function redactAuthTokens(bytes) {
|
|
1924
|
+
let payloadStart;
|
|
1925
|
+
try {
|
|
1926
|
+
const probe = new MoqtBufferReader(bytes);
|
|
1927
|
+
probe.readVarInt();
|
|
1928
|
+
probe.readUint8();
|
|
1929
|
+
probe.readUint8();
|
|
1930
|
+
payloadStart = probe.offset;
|
|
1931
|
+
} catch {
|
|
1932
|
+
return { bytes, redacted: 0, incomplete: false, decoded: false };
|
|
1933
|
+
}
|
|
1934
|
+
return redactWith(bytes, payloadStart, () => decodeMessage(bytes).ok);
|
|
1935
|
+
}
|
|
1968
1936
|
|
|
1969
1937
|
export {
|
|
1970
1938
|
MSG_REQUEST_UPDATE,
|
|
@@ -2006,5 +1974,6 @@ export {
|
|
|
2006
1974
|
encodeMessage,
|
|
2007
1975
|
decodeMessage,
|
|
2008
1976
|
createStreamDecoder,
|
|
2009
|
-
createDraft18Codec
|
|
1977
|
+
createDraft18Codec,
|
|
1978
|
+
redactAuthTokens
|
|
2010
1979
|
};
|