@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/draft19/messages.ts
|
|
10
12
|
var MSG_REQUEST_UPDATE = 0x02n;
|
|
@@ -252,99 +254,108 @@ function encodeFetchStream(stream) {
|
|
|
252
254
|
void prevObjectId;
|
|
253
255
|
return w.finish();
|
|
254
256
|
}
|
|
257
|
+
function readSubgroupHeader(r) {
|
|
258
|
+
const streamType = r.readUint8();
|
|
259
|
+
if (!isValidSubgroupType(streamType)) {
|
|
260
|
+
throw new DecodeError(
|
|
261
|
+
"CONSTRAINT_VIOLATION",
|
|
262
|
+
`Invalid subgroup stream type 0x${streamType.toString(16)}`,
|
|
263
|
+
0
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
const propertiesPresent = (streamType & 1) !== 0;
|
|
267
|
+
const subgroupMode = (streamType & 6) >> 1;
|
|
268
|
+
const hasSubgroupField = subgroupMode === 2;
|
|
269
|
+
const subgroupIsFirstObjId = subgroupMode === 1;
|
|
270
|
+
const endOfGroup = (streamType & 8) !== 0;
|
|
271
|
+
const hasPriority = (streamType & 32) === 0;
|
|
272
|
+
const firstObjectFlag = (streamType & 64) !== 0;
|
|
273
|
+
const trackAlias = r.readVarInt();
|
|
274
|
+
const groupId = r.readVarInt();
|
|
275
|
+
let subgroupId = 0n;
|
|
276
|
+
if (hasSubgroupField) {
|
|
277
|
+
subgroupId = r.readVarInt();
|
|
278
|
+
}
|
|
279
|
+
let publisherPriority = 128;
|
|
280
|
+
if (hasPriority) {
|
|
281
|
+
publisherPriority = r.readUint8();
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
streamType,
|
|
285
|
+
propertiesPresent,
|
|
286
|
+
subgroupIsFirstObjId,
|
|
287
|
+
endOfGroup,
|
|
288
|
+
firstObjectFlag,
|
|
289
|
+
trackAlias,
|
|
290
|
+
groupId,
|
|
291
|
+
subgroupId,
|
|
292
|
+
publisherPriority
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function readSubgroupObject(r, propertiesPresent, isFirst, prevObjectId, base) {
|
|
296
|
+
const byteOffset = base + r.offset;
|
|
297
|
+
const delta = r.readVarInt();
|
|
298
|
+
const objectId = isFirst ? delta : prevObjectId + 1n + delta;
|
|
299
|
+
const extensionData = new Uint8Array(0);
|
|
300
|
+
let objectProperties;
|
|
301
|
+
if (propertiesPresent) {
|
|
302
|
+
const propsLen = Number(r.readVarInt());
|
|
303
|
+
if (propsLen > 0) {
|
|
304
|
+
objectProperties = decodeObjectProperties(r, propsLen);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
const payloadLength = Number(r.readVarInt());
|
|
308
|
+
let payload;
|
|
309
|
+
let status;
|
|
310
|
+
let payloadByteOffset;
|
|
311
|
+
if (payloadLength === 0) {
|
|
312
|
+
status = r.readVarInt();
|
|
313
|
+
payloadByteOffset = base + r.offset;
|
|
314
|
+
payload = new Uint8Array(0);
|
|
315
|
+
} else {
|
|
316
|
+
payloadByteOffset = base + r.offset;
|
|
317
|
+
payload = r.readBytesView(payloadLength);
|
|
318
|
+
}
|
|
319
|
+
const obj = {
|
|
320
|
+
type: "object",
|
|
321
|
+
byteOffset,
|
|
322
|
+
payloadByteOffset,
|
|
323
|
+
objectId,
|
|
324
|
+
payloadLength,
|
|
325
|
+
payload,
|
|
326
|
+
extensionData
|
|
327
|
+
};
|
|
328
|
+
if (status !== void 0) obj.status = status;
|
|
329
|
+
if (objectProperties !== void 0)
|
|
330
|
+
obj.objectProperties = objectProperties;
|
|
331
|
+
return obj;
|
|
332
|
+
}
|
|
255
333
|
function decodeSubgroupStream(bytes) {
|
|
256
334
|
try {
|
|
257
335
|
const r = new MoqtBufferReader(bytes);
|
|
258
|
-
const
|
|
259
|
-
if (!isValidSubgroupType(streamType)) {
|
|
260
|
-
return {
|
|
261
|
-
ok: false,
|
|
262
|
-
error: new DecodeError(
|
|
263
|
-
"CONSTRAINT_VIOLATION",
|
|
264
|
-
`Invalid subgroup stream type 0x${streamType.toString(16)}`,
|
|
265
|
-
0
|
|
266
|
-
)
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
const propertiesPresent = (streamType & 1) !== 0;
|
|
270
|
-
const subgroupMode = (streamType & 6) >> 1;
|
|
271
|
-
const hasSubgroupField = subgroupMode === 2;
|
|
272
|
-
const subgroupIsFirstObjId = subgroupMode === 1;
|
|
273
|
-
const endOfGroup = (streamType & 8) !== 0;
|
|
274
|
-
const hasPriority = (streamType & 32) === 0;
|
|
275
|
-
const firstObject = (streamType & 64) !== 0;
|
|
276
|
-
const trackAlias = r.readVarInt();
|
|
277
|
-
const groupId = r.readVarInt();
|
|
278
|
-
let subgroupId = 0n;
|
|
279
|
-
if (hasSubgroupField) {
|
|
280
|
-
subgroupId = r.readVarInt();
|
|
281
|
-
}
|
|
282
|
-
let publisherPriority = 128;
|
|
283
|
-
if (hasPriority) {
|
|
284
|
-
publisherPriority = r.readUint8();
|
|
285
|
-
}
|
|
336
|
+
const h = readSubgroupHeader(r);
|
|
286
337
|
const objects = [];
|
|
287
338
|
let prevObjectId = -1n;
|
|
288
339
|
let isFirst = true;
|
|
340
|
+
let subgroupId = h.subgroupId;
|
|
289
341
|
while (r.remaining > 0) {
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
if (isFirst) {
|
|
294
|
-
objectId = delta;
|
|
295
|
-
if (subgroupIsFirstObjId) {
|
|
296
|
-
subgroupId = objectId;
|
|
297
|
-
}
|
|
298
|
-
isFirst = false;
|
|
299
|
-
} else {
|
|
300
|
-
objectId = prevObjectId + 1n + delta;
|
|
301
|
-
}
|
|
302
|
-
const extensionData = new Uint8Array(0);
|
|
303
|
-
let objectProperties;
|
|
304
|
-
if (propertiesPresent) {
|
|
305
|
-
const propsLen = Number(r.readVarInt());
|
|
306
|
-
if (propsLen > 0) {
|
|
307
|
-
objectProperties = decodeObjectProperties(r, propsLen);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
const payloadLength = Number(r.readVarInt());
|
|
311
|
-
let payload;
|
|
312
|
-
let status;
|
|
313
|
-
let payloadByteOffset;
|
|
314
|
-
if (payloadLength === 0) {
|
|
315
|
-
status = r.readVarInt();
|
|
316
|
-
payloadByteOffset = r.offset;
|
|
317
|
-
payload = new Uint8Array(0);
|
|
318
|
-
} else {
|
|
319
|
-
payloadByteOffset = r.offset;
|
|
320
|
-
payload = r.readBytesView(payloadLength);
|
|
321
|
-
}
|
|
322
|
-
const obj = {
|
|
323
|
-
type: "object",
|
|
324
|
-
byteOffset,
|
|
325
|
-
payloadByteOffset,
|
|
326
|
-
objectId,
|
|
327
|
-
payloadLength,
|
|
328
|
-
payload,
|
|
329
|
-
extensionData
|
|
330
|
-
};
|
|
331
|
-
if (status !== void 0) obj.status = status;
|
|
332
|
-
if (objectProperties !== void 0)
|
|
333
|
-
obj.objectProperties = objectProperties;
|
|
342
|
+
const obj = readSubgroupObject(r, h.propertiesPresent, isFirst, prevObjectId, 0);
|
|
343
|
+
if (isFirst && h.subgroupIsFirstObjId) subgroupId = obj.objectId;
|
|
344
|
+
isFirst = false;
|
|
334
345
|
objects.push(obj);
|
|
335
|
-
prevObjectId = objectId;
|
|
346
|
+
prevObjectId = obj.objectId;
|
|
336
347
|
}
|
|
337
348
|
const result = {
|
|
338
349
|
type: "subgroup",
|
|
339
|
-
headerType: streamType,
|
|
340
|
-
trackAlias,
|
|
341
|
-
groupId,
|
|
350
|
+
headerType: h.streamType,
|
|
351
|
+
trackAlias: h.trackAlias,
|
|
352
|
+
groupId: h.groupId,
|
|
342
353
|
subgroupId,
|
|
343
|
-
publisherPriority,
|
|
344
|
-
objects
|
|
354
|
+
publisherPriority: h.publisherPriority,
|
|
355
|
+
objects,
|
|
356
|
+
...h.endOfGroup ? { endOfGroup: true } : {},
|
|
357
|
+
...h.firstObjectFlag ? { firstObject: true } : {}
|
|
345
358
|
};
|
|
346
|
-
if (endOfGroup) result.endOfGroup = true;
|
|
347
|
-
if (firstObject) result.firstObject = true;
|
|
348
359
|
return {
|
|
349
360
|
ok: true,
|
|
350
361
|
value: result,
|
|
@@ -411,6 +422,178 @@ function decodeDatagram(bytes) {
|
|
|
411
422
|
throw e;
|
|
412
423
|
}
|
|
413
424
|
}
|
|
425
|
+
function newFetchObjectState() {
|
|
426
|
+
return { prevGroupId: 0n, prevSubgroupId: 0n, prevObjectId: 0n, prevPriority: 128, first: true };
|
|
427
|
+
}
|
|
428
|
+
function readFetchObject(r, base, st) {
|
|
429
|
+
const byteOffset = base + r.offset;
|
|
430
|
+
const flags = Number(r.readVarInt());
|
|
431
|
+
let groupId = st.prevGroupId;
|
|
432
|
+
let subgroupId = st.prevSubgroupId;
|
|
433
|
+
let objectId = st.prevObjectId + 1n;
|
|
434
|
+
let payloadLength;
|
|
435
|
+
let payload;
|
|
436
|
+
let payloadByteOffset;
|
|
437
|
+
const extensionData = new Uint8Array(0);
|
|
438
|
+
if (flags >= 128) {
|
|
439
|
+
if (flags !== 140 && flags !== 268) {
|
|
440
|
+
throw new DecodeError(
|
|
441
|
+
"CONSTRAINT_VIOLATION",
|
|
442
|
+
`Unknown serialization flags value: 0x${flags.toString(16)}`,
|
|
443
|
+
r.offset
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
groupId = r.readVarInt();
|
|
447
|
+
objectId = r.readVarInt();
|
|
448
|
+
payloadLength = Number(r.readVarInt());
|
|
449
|
+
payloadByteOffset = base + r.offset;
|
|
450
|
+
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
451
|
+
} else if (flags & 64) {
|
|
452
|
+
const objectIdPresent = (flags & 4) !== 0;
|
|
453
|
+
const groupIdPresent = (flags & 8) !== 0;
|
|
454
|
+
const priorityPresent = (flags & 16) !== 0;
|
|
455
|
+
const propsPresent = (flags & 32) !== 0;
|
|
456
|
+
if (groupIdPresent) {
|
|
457
|
+
const groupDelta = r.readVarInt();
|
|
458
|
+
groupId = st.first ? groupDelta : st.prevGroupId + groupDelta + 1n;
|
|
459
|
+
}
|
|
460
|
+
if (objectIdPresent) {
|
|
461
|
+
objectId = r.readVarInt();
|
|
462
|
+
}
|
|
463
|
+
if (priorityPresent) {
|
|
464
|
+
st.prevPriority = r.readUint8();
|
|
465
|
+
}
|
|
466
|
+
let objectProperties;
|
|
467
|
+
if (propsPresent) {
|
|
468
|
+
const propsLen = Number(r.readVarInt());
|
|
469
|
+
if (propsLen > 0) {
|
|
470
|
+
objectProperties = decodeObjectProperties(r, propsLen);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
payloadLength = Number(r.readVarInt());
|
|
474
|
+
payloadByteOffset = base + r.offset;
|
|
475
|
+
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
476
|
+
const obj2 = {
|
|
477
|
+
type: "object",
|
|
478
|
+
byteOffset,
|
|
479
|
+
payloadByteOffset,
|
|
480
|
+
serializationFlags: flags,
|
|
481
|
+
groupId,
|
|
482
|
+
subgroupId: 0n,
|
|
483
|
+
objectId,
|
|
484
|
+
publisherPriority: st.prevPriority,
|
|
485
|
+
payloadLength,
|
|
486
|
+
payload,
|
|
487
|
+
extensionData
|
|
488
|
+
};
|
|
489
|
+
if (objectProperties)
|
|
490
|
+
obj2.objectProperties = objectProperties;
|
|
491
|
+
st.prevGroupId = groupId;
|
|
492
|
+
st.prevObjectId = objectId;
|
|
493
|
+
st.first = false;
|
|
494
|
+
return obj2;
|
|
495
|
+
} else {
|
|
496
|
+
const subgroupEncoding = flags & 3;
|
|
497
|
+
const objectIdPresent = (flags & 4) !== 0;
|
|
498
|
+
const groupIdPresent = (flags & 8) !== 0;
|
|
499
|
+
const priorityPresent = (flags & 16) !== 0;
|
|
500
|
+
const propsPresent = (flags & 32) !== 0;
|
|
501
|
+
if (groupIdPresent) {
|
|
502
|
+
const groupDelta = r.readVarInt();
|
|
503
|
+
groupId = st.first ? groupDelta : st.prevGroupId + groupDelta + 1n;
|
|
504
|
+
} else if (st.first) {
|
|
505
|
+
throw new DecodeError(
|
|
506
|
+
"CONSTRAINT_VIOLATION",
|
|
507
|
+
"First fetch object must include groupId",
|
|
508
|
+
r.offset
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
if (subgroupEncoding === 0) {
|
|
512
|
+
subgroupId = 0n;
|
|
513
|
+
} else if (subgroupEncoding === 1) {
|
|
514
|
+
if (st.first) {
|
|
515
|
+
throw new DecodeError(
|
|
516
|
+
"CONSTRAINT_VIOLATION",
|
|
517
|
+
"First fetch object cannot reference prior subgroupId",
|
|
518
|
+
r.offset
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
subgroupId = st.prevSubgroupId;
|
|
522
|
+
} else if (subgroupEncoding === 2) {
|
|
523
|
+
if (st.first) {
|
|
524
|
+
throw new DecodeError(
|
|
525
|
+
"CONSTRAINT_VIOLATION",
|
|
526
|
+
"First fetch object cannot reference prior subgroupId",
|
|
527
|
+
r.offset
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
subgroupId = st.prevSubgroupId + 1n;
|
|
531
|
+
} else if (subgroupEncoding === 3) {
|
|
532
|
+
subgroupId = r.readVarInt();
|
|
533
|
+
}
|
|
534
|
+
if (objectIdPresent) {
|
|
535
|
+
objectId = r.readVarInt();
|
|
536
|
+
} else if (st.first) {
|
|
537
|
+
throw new DecodeError(
|
|
538
|
+
"CONSTRAINT_VIOLATION",
|
|
539
|
+
"First fetch object must include objectId",
|
|
540
|
+
r.offset
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
if (priorityPresent) {
|
|
544
|
+
st.prevPriority = r.readUint8();
|
|
545
|
+
}
|
|
546
|
+
let objectProperties;
|
|
547
|
+
if (propsPresent) {
|
|
548
|
+
const propsLen = Number(r.readVarInt());
|
|
549
|
+
if (propsLen > 0) {
|
|
550
|
+
objectProperties = decodeObjectProperties(r, propsLen);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
payloadLength = Number(r.readVarInt());
|
|
554
|
+
payloadByteOffset = base + r.offset;
|
|
555
|
+
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
556
|
+
if (objectProperties) {
|
|
557
|
+
const obj2 = {
|
|
558
|
+
type: "object",
|
|
559
|
+
byteOffset,
|
|
560
|
+
payloadByteOffset,
|
|
561
|
+
serializationFlags: flags,
|
|
562
|
+
groupId,
|
|
563
|
+
subgroupId,
|
|
564
|
+
objectId,
|
|
565
|
+
publisherPriority: st.prevPriority,
|
|
566
|
+
payloadLength,
|
|
567
|
+
payload,
|
|
568
|
+
extensionData
|
|
569
|
+
};
|
|
570
|
+
obj2.objectProperties = objectProperties;
|
|
571
|
+
st.prevGroupId = groupId;
|
|
572
|
+
st.prevSubgroupId = subgroupId;
|
|
573
|
+
st.prevObjectId = objectId;
|
|
574
|
+
st.first = false;
|
|
575
|
+
return obj2;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
const obj = {
|
|
579
|
+
type: "object",
|
|
580
|
+
byteOffset,
|
|
581
|
+
payloadByteOffset,
|
|
582
|
+
serializationFlags: flags,
|
|
583
|
+
groupId,
|
|
584
|
+
subgroupId,
|
|
585
|
+
objectId,
|
|
586
|
+
publisherPriority: st.prevPriority,
|
|
587
|
+
payloadLength,
|
|
588
|
+
payload,
|
|
589
|
+
extensionData
|
|
590
|
+
};
|
|
591
|
+
st.prevGroupId = groupId;
|
|
592
|
+
st.prevSubgroupId = subgroupId;
|
|
593
|
+
st.prevObjectId = objectId;
|
|
594
|
+
st.first = false;
|
|
595
|
+
return obj;
|
|
596
|
+
}
|
|
414
597
|
function decodeFetchStream(bytes) {
|
|
415
598
|
try {
|
|
416
599
|
const r = new MoqtBufferReader(bytes);
|
|
@@ -427,196 +610,9 @@ function decodeFetchStream(bytes) {
|
|
|
427
610
|
}
|
|
428
611
|
const requestId = r.readVarInt();
|
|
429
612
|
const objects = [];
|
|
430
|
-
|
|
431
|
-
let prevSubgroupId = 0n;
|
|
432
|
-
let prevObjectId = 0n;
|
|
433
|
-
let prevPriority = 128;
|
|
434
|
-
let first = true;
|
|
613
|
+
const st = newFetchObjectState();
|
|
435
614
|
while (r.remaining > 0) {
|
|
436
|
-
|
|
437
|
-
const flags = Number(r.readVarInt());
|
|
438
|
-
let groupId = prevGroupId;
|
|
439
|
-
let subgroupId = prevSubgroupId;
|
|
440
|
-
let objectId = prevObjectId + 1n;
|
|
441
|
-
let payloadLength;
|
|
442
|
-
let payload;
|
|
443
|
-
let payloadByteOffset;
|
|
444
|
-
const extensionData = new Uint8Array(0);
|
|
445
|
-
if (flags >= 128) {
|
|
446
|
-
if (flags !== 140 && flags !== 268) {
|
|
447
|
-
return {
|
|
448
|
-
ok: false,
|
|
449
|
-
error: new DecodeError(
|
|
450
|
-
"CONSTRAINT_VIOLATION",
|
|
451
|
-
`Unknown serialization flags value: 0x${flags.toString(16)}`,
|
|
452
|
-
r.offset
|
|
453
|
-
)
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
groupId = r.readVarInt();
|
|
457
|
-
objectId = r.readVarInt();
|
|
458
|
-
payloadLength = Number(r.readVarInt());
|
|
459
|
-
payloadByteOffset = r.offset;
|
|
460
|
-
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
461
|
-
} else if (flags & 64) {
|
|
462
|
-
const objectIdPresent = (flags & 4) !== 0;
|
|
463
|
-
const groupIdPresent = (flags & 8) !== 0;
|
|
464
|
-
const priorityPresent = (flags & 16) !== 0;
|
|
465
|
-
const propsPresent = (flags & 32) !== 0;
|
|
466
|
-
if (groupIdPresent) {
|
|
467
|
-
const groupDelta = r.readVarInt();
|
|
468
|
-
groupId = first ? groupDelta : prevGroupId + groupDelta + 1n;
|
|
469
|
-
}
|
|
470
|
-
if (objectIdPresent) {
|
|
471
|
-
objectId = r.readVarInt();
|
|
472
|
-
}
|
|
473
|
-
if (priorityPresent) {
|
|
474
|
-
prevPriority = r.readUint8();
|
|
475
|
-
}
|
|
476
|
-
let objectProperties;
|
|
477
|
-
if (propsPresent) {
|
|
478
|
-
const propsLen = Number(r.readVarInt());
|
|
479
|
-
if (propsLen > 0) {
|
|
480
|
-
objectProperties = decodeObjectProperties(r, propsLen);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
payloadLength = Number(r.readVarInt());
|
|
484
|
-
payloadByteOffset = r.offset;
|
|
485
|
-
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
486
|
-
const obj2 = {
|
|
487
|
-
type: "object",
|
|
488
|
-
byteOffset,
|
|
489
|
-
payloadByteOffset,
|
|
490
|
-
serializationFlags: flags,
|
|
491
|
-
groupId,
|
|
492
|
-
subgroupId: 0n,
|
|
493
|
-
objectId,
|
|
494
|
-
publisherPriority: prevPriority,
|
|
495
|
-
payloadLength,
|
|
496
|
-
payload,
|
|
497
|
-
extensionData
|
|
498
|
-
};
|
|
499
|
-
if (objectProperties)
|
|
500
|
-
obj2.objectProperties = objectProperties;
|
|
501
|
-
objects.push(obj2);
|
|
502
|
-
prevGroupId = groupId;
|
|
503
|
-
prevObjectId = objectId;
|
|
504
|
-
first = false;
|
|
505
|
-
continue;
|
|
506
|
-
} else {
|
|
507
|
-
const subgroupEncoding = flags & 3;
|
|
508
|
-
const objectIdPresent = (flags & 4) !== 0;
|
|
509
|
-
const groupIdPresent = (flags & 8) !== 0;
|
|
510
|
-
const priorityPresent = (flags & 16) !== 0;
|
|
511
|
-
const propsPresent = (flags & 32) !== 0;
|
|
512
|
-
if (groupIdPresent) {
|
|
513
|
-
const groupDelta = r.readVarInt();
|
|
514
|
-
groupId = first ? groupDelta : prevGroupId + groupDelta + 1n;
|
|
515
|
-
} else if (first) {
|
|
516
|
-
return {
|
|
517
|
-
ok: false,
|
|
518
|
-
error: new DecodeError(
|
|
519
|
-
"CONSTRAINT_VIOLATION",
|
|
520
|
-
"First fetch object must include groupId",
|
|
521
|
-
r.offset
|
|
522
|
-
)
|
|
523
|
-
};
|
|
524
|
-
}
|
|
525
|
-
if (subgroupEncoding === 0) {
|
|
526
|
-
subgroupId = 0n;
|
|
527
|
-
} else if (subgroupEncoding === 1) {
|
|
528
|
-
if (first) {
|
|
529
|
-
return {
|
|
530
|
-
ok: false,
|
|
531
|
-
error: new DecodeError(
|
|
532
|
-
"CONSTRAINT_VIOLATION",
|
|
533
|
-
"First fetch object cannot reference prior subgroupId",
|
|
534
|
-
r.offset
|
|
535
|
-
)
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
subgroupId = prevSubgroupId;
|
|
539
|
-
} else if (subgroupEncoding === 2) {
|
|
540
|
-
if (first) {
|
|
541
|
-
return {
|
|
542
|
-
ok: false,
|
|
543
|
-
error: new DecodeError(
|
|
544
|
-
"CONSTRAINT_VIOLATION",
|
|
545
|
-
"First fetch object cannot reference prior subgroupId",
|
|
546
|
-
r.offset
|
|
547
|
-
)
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
subgroupId = prevSubgroupId + 1n;
|
|
551
|
-
} else if (subgroupEncoding === 3) {
|
|
552
|
-
subgroupId = r.readVarInt();
|
|
553
|
-
}
|
|
554
|
-
if (objectIdPresent) {
|
|
555
|
-
objectId = r.readVarInt();
|
|
556
|
-
} else if (first) {
|
|
557
|
-
return {
|
|
558
|
-
ok: false,
|
|
559
|
-
error: new DecodeError(
|
|
560
|
-
"CONSTRAINT_VIOLATION",
|
|
561
|
-
"First fetch object must include objectId",
|
|
562
|
-
r.offset
|
|
563
|
-
)
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
if (priorityPresent) {
|
|
567
|
-
prevPriority = r.readUint8();
|
|
568
|
-
}
|
|
569
|
-
let objectProperties;
|
|
570
|
-
if (propsPresent) {
|
|
571
|
-
const propsLen = Number(r.readVarInt());
|
|
572
|
-
if (propsLen > 0) {
|
|
573
|
-
objectProperties = decodeObjectProperties(r, propsLen);
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
payloadLength = Number(r.readVarInt());
|
|
577
|
-
payloadByteOffset = r.offset;
|
|
578
|
-
payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
579
|
-
if (objectProperties) {
|
|
580
|
-
const obj2 = {
|
|
581
|
-
type: "object",
|
|
582
|
-
byteOffset,
|
|
583
|
-
payloadByteOffset,
|
|
584
|
-
serializationFlags: flags,
|
|
585
|
-
groupId,
|
|
586
|
-
subgroupId,
|
|
587
|
-
objectId,
|
|
588
|
-
publisherPriority: prevPriority,
|
|
589
|
-
payloadLength,
|
|
590
|
-
payload,
|
|
591
|
-
extensionData
|
|
592
|
-
};
|
|
593
|
-
obj2.objectProperties = objectProperties;
|
|
594
|
-
objects.push(obj2);
|
|
595
|
-
prevGroupId = groupId;
|
|
596
|
-
prevSubgroupId = subgroupId;
|
|
597
|
-
prevObjectId = objectId;
|
|
598
|
-
first = false;
|
|
599
|
-
continue;
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
const obj = {
|
|
603
|
-
type: "object",
|
|
604
|
-
byteOffset,
|
|
605
|
-
payloadByteOffset,
|
|
606
|
-
serializationFlags: flags,
|
|
607
|
-
groupId,
|
|
608
|
-
subgroupId,
|
|
609
|
-
objectId,
|
|
610
|
-
publisherPriority: prevPriority,
|
|
611
|
-
payloadLength,
|
|
612
|
-
payload,
|
|
613
|
-
extensionData
|
|
614
|
-
};
|
|
615
|
-
objects.push(obj);
|
|
616
|
-
prevGroupId = groupId;
|
|
617
|
-
prevSubgroupId = subgroupId;
|
|
618
|
-
prevObjectId = objectId;
|
|
619
|
-
first = false;
|
|
615
|
+
objects.push(readFetchObject(r, 0, st));
|
|
620
616
|
}
|
|
621
617
|
return {
|
|
622
618
|
ok: true,
|
|
@@ -642,60 +638,70 @@ function decodeDataStream(streamType, bytes) {
|
|
|
642
638
|
}
|
|
643
639
|
}
|
|
644
640
|
}
|
|
641
|
+
var StreamBuffer = class {
|
|
642
|
+
buf = new Uint8Array(0);
|
|
643
|
+
/** Bytes written into `buf`. */
|
|
644
|
+
len = 0;
|
|
645
|
+
/** Consumed prefix of `buf`; `base + offset` is the position in the stream. */
|
|
646
|
+
offset = 0;
|
|
647
|
+
/** Absolute position of `buf[0]` within the stream. */
|
|
648
|
+
base = 0;
|
|
649
|
+
get unread() {
|
|
650
|
+
return this.len - this.offset;
|
|
651
|
+
}
|
|
652
|
+
append(chunk) {
|
|
653
|
+
if (this.len + chunk.length > this.buf.length) {
|
|
654
|
+
const live = this.len - this.offset;
|
|
655
|
+
const needed = live + chunk.length;
|
|
656
|
+
let cap = Math.max(4096, this.buf.length);
|
|
657
|
+
while (cap < needed * 2) cap *= 2;
|
|
658
|
+
const next = new Uint8Array(cap);
|
|
659
|
+
next.set(this.buf.subarray(this.offset, this.len), 0);
|
|
660
|
+
this.buf = next;
|
|
661
|
+
this.base += this.offset;
|
|
662
|
+
this.len = live;
|
|
663
|
+
this.offset = 0;
|
|
664
|
+
}
|
|
665
|
+
this.buf.set(chunk, this.len);
|
|
666
|
+
this.len += chunk.length;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* The written bytes, for a reader positioned at `offset`. Bounded by `len`
|
|
670
|
+
* rather than by capacity, so `BufferReader.remaining` counts real bytes and
|
|
671
|
+
* not the spare room after them.
|
|
672
|
+
*/
|
|
673
|
+
written() {
|
|
674
|
+
return this.buf.subarray(0, this.len);
|
|
675
|
+
}
|
|
676
|
+
};
|
|
645
677
|
function createSubgroupStreamDecoder() {
|
|
646
|
-
|
|
647
|
-
let
|
|
678
|
+
const b = new StreamBuffer();
|
|
679
|
+
let header = null;
|
|
648
680
|
let headerEmitted = false;
|
|
649
681
|
let prevObjectId = -1n;
|
|
650
|
-
let
|
|
651
|
-
|
|
682
|
+
let isFirst = true;
|
|
683
|
+
function emitHeader(controller, h, subgroupId) {
|
|
684
|
+
controller.enqueue({
|
|
685
|
+
type: "subgroup_header",
|
|
686
|
+
headerType: h.streamType,
|
|
687
|
+
trackAlias: h.trackAlias,
|
|
688
|
+
groupId: h.groupId,
|
|
689
|
+
subgroupId,
|
|
690
|
+
publisherPriority: h.publisherPriority,
|
|
691
|
+
...h.endOfGroup ? { endOfGroup: true } : {},
|
|
692
|
+
...h.firstObjectFlag ? { firstObject: true } : {}
|
|
693
|
+
});
|
|
694
|
+
headerEmitted = true;
|
|
695
|
+
}
|
|
652
696
|
return new TransformStream({
|
|
653
697
|
transform(chunk, controller) {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
}
|
|
658
|
-
const newBuffer = new Uint8Array(buffer.length + chunk.length);
|
|
659
|
-
newBuffer.set(buffer, 0);
|
|
660
|
-
newBuffer.set(chunk, buffer.length);
|
|
661
|
-
buffer = newBuffer;
|
|
662
|
-
if (!headerEmitted) {
|
|
698
|
+
b.append(chunk);
|
|
699
|
+
const view = b.written();
|
|
700
|
+
if (header === null) {
|
|
663
701
|
try {
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
controller.error(
|
|
668
|
-
new DecodeError(
|
|
669
|
-
"CONSTRAINT_VIOLATION",
|
|
670
|
-
`Invalid subgroup stream type 0x${streamType.toString(16)}`,
|
|
671
|
-
0
|
|
672
|
-
)
|
|
673
|
-
);
|
|
674
|
-
return;
|
|
675
|
-
}
|
|
676
|
-
_propertiesPresent = (streamType & 1) !== 0;
|
|
677
|
-
const subgroupMode = (streamType & 6) >> 1;
|
|
678
|
-
const hasSubgroupField = subgroupMode === 2;
|
|
679
|
-
const hasPriority = (streamType & 32) === 0;
|
|
680
|
-
const trackAlias = r.readVarInt();
|
|
681
|
-
const groupId = r.readVarInt();
|
|
682
|
-
let subgroupId = 0n;
|
|
683
|
-
if (hasSubgroupField) {
|
|
684
|
-
subgroupId = r.readVarInt();
|
|
685
|
-
}
|
|
686
|
-
let publisherPriority = 128;
|
|
687
|
-
if (hasPriority) {
|
|
688
|
-
publisherPriority = r.readUint8();
|
|
689
|
-
}
|
|
690
|
-
controller.enqueue({
|
|
691
|
-
type: "subgroup_header",
|
|
692
|
-
trackAlias,
|
|
693
|
-
groupId,
|
|
694
|
-
subgroupId,
|
|
695
|
-
publisherPriority
|
|
696
|
-
});
|
|
697
|
-
headerEmitted = true;
|
|
698
|
-
offset += r.offset;
|
|
702
|
+
const hr = new MoqtBufferReader(view, b.offset);
|
|
703
|
+
header = readSubgroupHeader(hr);
|
|
704
|
+
b.offset = hr.offset;
|
|
699
705
|
} catch (e) {
|
|
700
706
|
if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
|
|
701
707
|
return;
|
|
@@ -703,71 +709,51 @@ function createSubgroupStreamDecoder() {
|
|
|
703
709
|
controller.error(e);
|
|
704
710
|
return;
|
|
705
711
|
}
|
|
712
|
+
if (!header.subgroupIsFirstObjId) emitHeader(controller, header, header.subgroupId);
|
|
706
713
|
}
|
|
707
|
-
|
|
714
|
+
const h = header;
|
|
715
|
+
if (h === null) return;
|
|
716
|
+
const r = new MoqtBufferReader(view, b.offset);
|
|
717
|
+
while (r.remaining > 0) {
|
|
718
|
+
const start = r.offset;
|
|
719
|
+
let obj;
|
|
708
720
|
try {
|
|
709
|
-
|
|
710
|
-
const delta = r.readVarInt();
|
|
711
|
-
let objectId;
|
|
712
|
-
if (firstObject) {
|
|
713
|
-
objectId = delta;
|
|
714
|
-
firstObject = false;
|
|
715
|
-
} else {
|
|
716
|
-
objectId = prevObjectId + 1n + delta;
|
|
717
|
-
}
|
|
718
|
-
let extensionData = new Uint8Array(0);
|
|
719
|
-
if (_propertiesPresent) {
|
|
720
|
-
const extLen = Number(r.readVarInt());
|
|
721
|
-
extensionData = extLen > 0 ? r.readBytesView(extLen) : new Uint8Array(0);
|
|
722
|
-
}
|
|
723
|
-
const payloadLength = Number(r.readVarInt());
|
|
724
|
-
const payloadByteOffset = r.offset;
|
|
725
|
-
const payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
726
|
-
controller.enqueue({
|
|
727
|
-
type: "object",
|
|
728
|
-
objectId,
|
|
729
|
-
payloadLength,
|
|
730
|
-
payload,
|
|
731
|
-
extensionData,
|
|
732
|
-
byteOffset: 0,
|
|
733
|
-
payloadByteOffset
|
|
734
|
-
});
|
|
735
|
-
offset += r.offset;
|
|
736
|
-
prevObjectId = objectId;
|
|
721
|
+
obj = readSubgroupObject(r, h.propertiesPresent, isFirst, prevObjectId, b.base);
|
|
737
722
|
} catch (e) {
|
|
738
723
|
if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
|
|
739
|
-
|
|
724
|
+
b.offset = start;
|
|
725
|
+
return;
|
|
740
726
|
}
|
|
741
727
|
controller.error(e);
|
|
742
728
|
return;
|
|
743
729
|
}
|
|
730
|
+
if (!headerEmitted) emitHeader(controller, h, obj.objectId);
|
|
731
|
+
isFirst = false;
|
|
732
|
+
b.offset = r.offset;
|
|
733
|
+
prevObjectId = obj.objectId;
|
|
734
|
+
controller.enqueue(obj);
|
|
744
735
|
}
|
|
745
736
|
},
|
|
746
737
|
flush(controller) {
|
|
747
|
-
if (
|
|
738
|
+
if (header !== null && !headerEmitted) emitHeader(controller, header, 0n);
|
|
739
|
+
if (b.unread > 0) {
|
|
748
740
|
controller.error(new DecodeError("UNEXPECTED_END", "Stream ended with incomplete data", 0));
|
|
749
741
|
}
|
|
750
742
|
}
|
|
751
743
|
});
|
|
752
744
|
}
|
|
753
745
|
function createFetchStreamDecoder() {
|
|
754
|
-
|
|
755
|
-
let offset = 0;
|
|
746
|
+
const b = new StreamBuffer();
|
|
756
747
|
let headerEmitted = false;
|
|
748
|
+
const st = newFetchObjectState();
|
|
757
749
|
return new TransformStream({
|
|
758
750
|
transform(chunk, controller) {
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
offset = 0;
|
|
762
|
-
}
|
|
763
|
-
const newBuffer = new Uint8Array(buffer.length + chunk.length);
|
|
764
|
-
newBuffer.set(buffer, 0);
|
|
765
|
-
newBuffer.set(chunk, buffer.length);
|
|
766
|
-
buffer = newBuffer;
|
|
751
|
+
b.append(chunk);
|
|
752
|
+
const view = b.written();
|
|
767
753
|
if (!headerEmitted) {
|
|
768
754
|
try {
|
|
769
|
-
const
|
|
770
|
-
const streamType =
|
|
755
|
+
const r2 = new MoqtBufferReader(view, b.offset);
|
|
756
|
+
const streamType = r2.readVarInt();
|
|
771
757
|
if (streamType !== FETCH_STREAM_TYPE) {
|
|
772
758
|
controller.error(
|
|
773
759
|
new DecodeError(
|
|
@@ -778,10 +764,10 @@ function createFetchStreamDecoder() {
|
|
|
778
764
|
);
|
|
779
765
|
return;
|
|
780
766
|
}
|
|
781
|
-
const requestId =
|
|
767
|
+
const requestId = r2.readVarInt();
|
|
782
768
|
controller.enqueue({ type: "fetch_header", requestId });
|
|
783
769
|
headerEmitted = true;
|
|
784
|
-
offset
|
|
770
|
+
b.offset = r2.offset;
|
|
785
771
|
} catch (e) {
|
|
786
772
|
if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
|
|
787
773
|
return;
|
|
@@ -790,99 +776,82 @@ function createFetchStreamDecoder() {
|
|
|
790
776
|
return;
|
|
791
777
|
}
|
|
792
778
|
}
|
|
793
|
-
|
|
779
|
+
const r = new MoqtBufferReader(view, b.offset);
|
|
780
|
+
while (r.remaining > 0) {
|
|
781
|
+
const start = r.offset;
|
|
782
|
+
let obj;
|
|
794
783
|
try {
|
|
795
|
-
|
|
796
|
-
const flags = Number(r.readVarInt());
|
|
797
|
-
const objectIdPresent = (flags & 4) !== 0;
|
|
798
|
-
const groupIdPresent = (flags & 8) !== 0;
|
|
799
|
-
const priorityPresent = (flags & 16) !== 0;
|
|
800
|
-
const extensionsPresent = (flags & 32) !== 0;
|
|
801
|
-
const subgroupEncoding = flags & 3;
|
|
802
|
-
if (groupIdPresent) r.readVarInt();
|
|
803
|
-
if (subgroupEncoding === 3) r.readVarInt();
|
|
804
|
-
let objectId = 0n;
|
|
805
|
-
if (objectIdPresent) objectId = r.readVarInt();
|
|
806
|
-
if (priorityPresent) r.readUint8();
|
|
807
|
-
let extensionData = new Uint8Array(0);
|
|
808
|
-
if (extensionsPresent) {
|
|
809
|
-
const extLen = Number(r.readVarInt());
|
|
810
|
-
extensionData = extLen > 0 ? r.readBytesView(extLen) : new Uint8Array(0);
|
|
811
|
-
}
|
|
812
|
-
const payloadLength = Number(r.readVarInt());
|
|
813
|
-
const payloadByteOffset = r.offset;
|
|
814
|
-
const payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
|
|
815
|
-
controller.enqueue({
|
|
816
|
-
type: "object",
|
|
817
|
-
objectId,
|
|
818
|
-
payloadLength,
|
|
819
|
-
payload,
|
|
820
|
-
extensionData,
|
|
821
|
-
byteOffset: 0,
|
|
822
|
-
payloadByteOffset
|
|
823
|
-
});
|
|
824
|
-
offset += r.offset;
|
|
784
|
+
obj = readFetchObject(r, b.base, st);
|
|
825
785
|
} catch (e) {
|
|
826
786
|
if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
|
|
827
|
-
|
|
787
|
+
b.offset = start;
|
|
788
|
+
return;
|
|
828
789
|
}
|
|
829
790
|
controller.error(e);
|
|
830
791
|
return;
|
|
831
792
|
}
|
|
793
|
+
b.offset = r.offset;
|
|
794
|
+
controller.enqueue(obj);
|
|
832
795
|
}
|
|
833
796
|
},
|
|
834
797
|
flush(controller) {
|
|
835
|
-
if (
|
|
798
|
+
if (b.unread > 0) {
|
|
836
799
|
controller.error(new DecodeError("UNEXPECTED_END", "Stream ended with incomplete data", 0));
|
|
837
800
|
}
|
|
838
801
|
}
|
|
839
802
|
});
|
|
840
803
|
}
|
|
841
804
|
function createDataStreamDecoder() {
|
|
842
|
-
let
|
|
843
|
-
let
|
|
844
|
-
let
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
if (
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
const decoder = createSubgroupStreamDecoder();
|
|
860
|
-
inner = decoder;
|
|
861
|
-
} else if (firstByte === 5) {
|
|
862
|
-
const decoder = createFetchStreamDecoder();
|
|
863
|
-
inner = decoder;
|
|
864
|
-
} else {
|
|
865
|
-
controller.error(
|
|
866
|
-
new DecodeError(
|
|
867
|
-
"CONSTRAINT_VIOLATION",
|
|
868
|
-
`Unknown data stream type: 0x${firstByte.toString(16)}`,
|
|
869
|
-
0
|
|
870
|
-
)
|
|
871
|
-
);
|
|
872
|
-
return;
|
|
805
|
+
let writer = null;
|
|
806
|
+
let pump = Promise.resolve();
|
|
807
|
+
let broken = false;
|
|
808
|
+
function attach(inner, controller) {
|
|
809
|
+
writer = inner.writable.getWriter();
|
|
810
|
+
const reader = inner.readable.getReader();
|
|
811
|
+
pump = (async () => {
|
|
812
|
+
try {
|
|
813
|
+
for (; ; ) {
|
|
814
|
+
const { done, value } = await reader.read();
|
|
815
|
+
if (done) break;
|
|
816
|
+
controller.enqueue(value);
|
|
817
|
+
}
|
|
818
|
+
} catch (e) {
|
|
819
|
+
if (!broken) {
|
|
820
|
+
broken = true;
|
|
821
|
+
controller.error(e);
|
|
873
822
|
}
|
|
874
823
|
}
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
824
|
+
})();
|
|
825
|
+
}
|
|
826
|
+
async function feed(bytes) {
|
|
827
|
+
if (writer === null || broken || bytes.length === 0) return;
|
|
828
|
+
try {
|
|
829
|
+
await writer.write(bytes);
|
|
830
|
+
} catch {
|
|
831
|
+
broken = true;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return new TransformStream({
|
|
835
|
+
async transform(chunk, controller) {
|
|
836
|
+
if (broken) return;
|
|
837
|
+
if (writer !== null) {
|
|
838
|
+
await feed(chunk);
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
if (chunk.length === 0) return;
|
|
842
|
+
const firstByte = chunk[0];
|
|
881
843
|
if (isValidSubgroupType(firstByte)) {
|
|
882
|
-
|
|
844
|
+
attach(
|
|
845
|
+
createSubgroupStreamDecoder(),
|
|
846
|
+
controller
|
|
847
|
+
);
|
|
883
848
|
} else if (firstByte === 5) {
|
|
884
|
-
|
|
849
|
+
attach(
|
|
850
|
+
createFetchStreamDecoder(),
|
|
851
|
+
controller
|
|
852
|
+
);
|
|
885
853
|
} else {
|
|
854
|
+
broken = true;
|
|
886
855
|
controller.error(
|
|
887
856
|
new DecodeError(
|
|
888
857
|
"CONSTRAINT_VIOLATION",
|
|
@@ -892,31 +861,15 @@ function createDataStreamDecoder() {
|
|
|
892
861
|
);
|
|
893
862
|
return;
|
|
894
863
|
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
type: "subgroup_header",
|
|
903
|
-
trackAlias: stream.trackAlias,
|
|
904
|
-
groupId: stream.groupId,
|
|
905
|
-
subgroupId: stream.subgroupId,
|
|
906
|
-
publisherPriority: stream.publisherPriority
|
|
907
|
-
});
|
|
908
|
-
for (const obj of stream.objects) {
|
|
909
|
-
controller.enqueue(obj);
|
|
910
|
-
}
|
|
911
|
-
} else if (stream.type === "fetch") {
|
|
912
|
-
controller.enqueue({
|
|
913
|
-
type: "fetch_header",
|
|
914
|
-
requestId: stream.requestId
|
|
915
|
-
});
|
|
916
|
-
for (const obj of stream.objects) {
|
|
917
|
-
controller.enqueue(obj);
|
|
918
|
-
}
|
|
864
|
+
await feed(chunk);
|
|
865
|
+
},
|
|
866
|
+
async flush() {
|
|
867
|
+
if (writer === null) return;
|
|
868
|
+
try {
|
|
869
|
+
await writer.close();
|
|
870
|
+
} catch {
|
|
919
871
|
}
|
|
872
|
+
await pump;
|
|
920
873
|
}
|
|
921
874
|
});
|
|
922
875
|
}
|
|
@@ -1046,10 +999,9 @@ function decodeSetupOptions(reader, payloadEnd) {
|
|
|
1046
999
|
if (optType === SETUP_OPT_PATH) {
|
|
1047
1000
|
result.path = textDecoder.decode(bytes);
|
|
1048
1001
|
} else if (optType === SETUP_OPT_AUTHORIZATION_TOKEN) {
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
];
|
|
1002
|
+
const token = decodeAuthorizationToken(new MoqtBufferReader(bytes));
|
|
1003
|
+
noteAuthTokenValue(reader.offset - length, length, token);
|
|
1004
|
+
result.authorization_token = [...result.authorization_token ?? [], token];
|
|
1053
1005
|
} else if (optType === SETUP_OPT_AUTHORITY) {
|
|
1054
1006
|
result.authority = textDecoder.decode(bytes);
|
|
1055
1007
|
} else if (optType === SETUP_OPT_MOQT_IMPLEMENTATION) {
|
|
@@ -1078,6 +1030,11 @@ function encodeAuthorizationToken(token, w) {
|
|
|
1078
1030
|
w.writeBytes(tv);
|
|
1079
1031
|
}
|
|
1080
1032
|
}
|
|
1033
|
+
function noteAuthTokenValue(valueStart, valueLength, token) {
|
|
1034
|
+
const value = token.token_value;
|
|
1035
|
+
if (value === void 0 || value.byteLength === 0) return;
|
|
1036
|
+
recordAuthValueSpan(valueStart + valueLength - value.byteLength, value.byteLength);
|
|
1037
|
+
}
|
|
1081
1038
|
function decodeAuthorizationToken(r) {
|
|
1082
1039
|
const alias_type = r.readVarInt();
|
|
1083
1040
|
const aliasType = Number(alias_type);
|
|
@@ -1391,10 +1348,9 @@ function decodeParams(reader, messageType) {
|
|
|
1391
1348
|
} else if (paramType === PARAM_AUTHORIZATION_TOKEN) {
|
|
1392
1349
|
const length = Number(reader.readVarInt());
|
|
1393
1350
|
const bytes = reader.readBytes(length);
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
];
|
|
1351
|
+
const token = decodeAuthorizationToken(new MoqtBufferReader(bytes));
|
|
1352
|
+
noteAuthTokenValue(reader.offset - length, length, token);
|
|
1353
|
+
result.authorization_token = [...result.authorization_token ?? [], token];
|
|
1398
1354
|
} else if (paramType === PARAM_RENDEZVOUS_TIMEOUT) {
|
|
1399
1355
|
result.rendezvous_timeout = reader.readVarInt();
|
|
1400
1356
|
} else if (paramType === PARAM_SUBGROUP_DELIVERY_TIMEOUT) {
|
|
@@ -2078,6 +2034,19 @@ function createDraft19Codec() {
|
|
|
2078
2034
|
createDataStreamDecoder
|
|
2079
2035
|
};
|
|
2080
2036
|
}
|
|
2037
|
+
function redactAuthTokens(bytes) {
|
|
2038
|
+
let payloadStart;
|
|
2039
|
+
try {
|
|
2040
|
+
const probe = new MoqtBufferReader(bytes);
|
|
2041
|
+
probe.readVarInt();
|
|
2042
|
+
probe.readUint8();
|
|
2043
|
+
probe.readUint8();
|
|
2044
|
+
payloadStart = probe.offset;
|
|
2045
|
+
} catch {
|
|
2046
|
+
return { bytes, redacted: 0, incomplete: false, decoded: false };
|
|
2047
|
+
}
|
|
2048
|
+
return redactWith(bytes, payloadStart, () => decodeMessage(bytes).ok);
|
|
2049
|
+
}
|
|
2081
2050
|
|
|
2082
2051
|
export {
|
|
2083
2052
|
MSG_REQUEST_UPDATE,
|
|
@@ -2121,5 +2090,6 @@ export {
|
|
|
2121
2090
|
encodeMessage,
|
|
2122
2091
|
decodeMessage,
|
|
2123
2092
|
createStreamDecoder,
|
|
2124
|
-
createDraft19Codec
|
|
2093
|
+
createDraft19Codec,
|
|
2094
|
+
redactAuthTokens
|
|
2125
2095
|
};
|