werift 0.24.0 → 0.24.1
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/lib/common/src/binary.js +2 -3
- package/lib/common/src/binary.js.map +1 -1
- package/lib/ice/src/ice.js +4 -9
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/internal/selectAddresses.d.ts +9 -0
- package/lib/ice/src/internal/selectAddresses.js +40 -0
- package/lib/ice/src/internal/selectAddresses.js.map +1 -0
- package/lib/ice/src/utils.js +2 -31
- package/lib/ice/src/utils.js.map +1 -1
- package/lib/ice-server/src/stun/attributes.js +9 -47
- package/lib/ice-server/src/stun/attributes.js.map +1 -1
- package/lib/ice-server/src/stun/ip.d.ts +12 -0
- package/lib/ice-server/src/stun/ip.js +88 -0
- package/lib/ice-server/src/stun/ip.js.map +1 -0
- package/lib/index.mjs +217 -130
- package/lib/nonstandard/index.mjs +121 -54
- package/lib/rtp/src/codec/av1.js +11 -5
- package/lib/rtp/src/codec/av1.js.map +1 -1
- package/lib/rtp/src/codec/leb128.d.ts +5 -0
- package/lib/rtp/src/codec/leb128.js +24 -0
- package/lib/rtp/src/codec/leb128.js.map +1 -0
- package/lib/rtp/src/rtp/rtx.js +4 -6
- package/lib/rtp/src/rtp/rtx.js.map +1 -1
- package/lib/rtp/src/srtp/context/context.d.ts +2 -0
- package/lib/rtp/src/srtp/context/context.js +12 -12
- package/lib/rtp/src/srtp/context/context.js.map +1 -1
- package/lib/sctp/src/param.js +31 -15
- package/lib/sctp/src/param.js.map +1 -1
- package/lib/sctp/src/sctp.js +10 -9
- package/lib/sctp/src/sctp.js.map +1 -1
- package/lib/webrtc/src/media/rtpSender.js +2 -3
- package/lib/webrtc/src/media/rtpSender.js.map +1 -1
- package/lib/webrtc/src/sdp.js +1 -35
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.js +17 -16
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/package.json +1 -7
|
@@ -10,12 +10,11 @@ import {
|
|
|
10
10
|
|
|
11
11
|
// ../common/src/binary.ts
|
|
12
12
|
import { randomBytes } from "crypto";
|
|
13
|
-
import { jspack } from "@shinyoshiaki/jspack";
|
|
14
13
|
function random16() {
|
|
15
|
-
return
|
|
14
|
+
return randomBytes(2).readUInt16BE(0);
|
|
16
15
|
}
|
|
17
16
|
function random32() {
|
|
18
|
-
return
|
|
17
|
+
return randomBytes(4).readUInt32BE(0);
|
|
19
18
|
}
|
|
20
19
|
function bufferXor(a, b) {
|
|
21
20
|
if (a.length !== b.length) {
|
|
@@ -1838,8 +1837,25 @@ var OggParser = class {
|
|
|
1838
1837
|
// ../rtp/src/extra/container/webm/container.ts
|
|
1839
1838
|
import { createCipheriv, randomBytes as randomBytes2, randomFillSync } from "crypto";
|
|
1840
1839
|
|
|
1840
|
+
// ../rtp/src/codec/leb128.ts
|
|
1841
|
+
function leb128encode(value) {
|
|
1842
|
+
if (!Number.isInteger(value) || value < 0 || !Number.isSafeInteger(value)) {
|
|
1843
|
+
throw new Error("LEB128 encode requires a non-negative safe integer");
|
|
1844
|
+
}
|
|
1845
|
+
const bytes2 = [];
|
|
1846
|
+
let remaining = value;
|
|
1847
|
+
do {
|
|
1848
|
+
let byte = remaining & 127;
|
|
1849
|
+
remaining = Math.floor(remaining / 128);
|
|
1850
|
+
if (remaining !== 0) {
|
|
1851
|
+
byte |= 128;
|
|
1852
|
+
}
|
|
1853
|
+
bytes2.push(byte);
|
|
1854
|
+
} while (remaining !== 0);
|
|
1855
|
+
return Buffer.from(bytes2);
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1841
1858
|
// ../rtp/src/codec/av1.ts
|
|
1842
|
-
import { LEB128 } from "@minhducsun2002/leb128";
|
|
1843
1859
|
var log2 = debug("werift-rtp : packages/rtp/src/codec/av1.ts");
|
|
1844
1860
|
var AV1RtpPayload = class _AV1RtpPayload {
|
|
1845
1861
|
/**
|
|
@@ -1969,7 +1985,7 @@ var AV1Obu = class _AV1Obu {
|
|
|
1969
1985
|
const header = new BitWriter2(8).set(this.obu_forbidden_bit).set(OBU_TYPE_IDS[this.obu_type], 4).set(this.obu_extension_flag).set(this.obu_has_size_field).set(this.obu_reserved_1bit).buffer;
|
|
1970
1986
|
let obuSize = Buffer.alloc(0);
|
|
1971
1987
|
if (this.obu_has_size_field) {
|
|
1972
|
-
obuSize =
|
|
1988
|
+
obuSize = leb128encode(this.payload.length);
|
|
1973
1989
|
}
|
|
1974
1990
|
return Buffer.concat([header, obuSize, this.payload]);
|
|
1975
1991
|
}
|
|
@@ -1978,14 +1994,20 @@ function leb128decode(buf) {
|
|
|
1978
1994
|
let value = 0;
|
|
1979
1995
|
let leb128bytes = 0;
|
|
1980
1996
|
for (let i = 0; i < 8; i++) {
|
|
1997
|
+
if (i >= buf.length) {
|
|
1998
|
+
throw new Error("LEB128 decode incomplete");
|
|
1999
|
+
}
|
|
1981
2000
|
const leb128byte = buf.readUInt8(i);
|
|
1982
|
-
value
|
|
2001
|
+
value += (leb128byte & 127) * 128 ** i;
|
|
1983
2002
|
leb128bytes++;
|
|
1984
2003
|
if (!(leb128byte & 128)) {
|
|
1985
|
-
|
|
2004
|
+
if (!Number.isSafeInteger(value)) {
|
|
2005
|
+
throw new Error("LEB128 value exceeds safe integer");
|
|
2006
|
+
}
|
|
2007
|
+
return [value, leb128bytes];
|
|
1986
2008
|
}
|
|
1987
2009
|
}
|
|
1988
|
-
|
|
2010
|
+
throw new Error("LEB128 decode incomplete");
|
|
1989
2011
|
}
|
|
1990
2012
|
var OBU_TYPES = {
|
|
1991
2013
|
0: "Reserved",
|
|
@@ -4665,13 +4687,12 @@ var RtpPacket = class _RtpPacket {
|
|
|
4665
4687
|
};
|
|
4666
4688
|
|
|
4667
4689
|
// ../rtp/src/rtp/rtx.ts
|
|
4668
|
-
import { jspack as jspack2 } from "@shinyoshiaki/jspack";
|
|
4669
4690
|
function unwrapRtx(rtx, payloadType, ssrc) {
|
|
4670
4691
|
const packet = new RtpPacket(
|
|
4671
4692
|
new RtpHeader({
|
|
4672
4693
|
payloadType,
|
|
4673
4694
|
marker: rtx.header.marker,
|
|
4674
|
-
sequenceNumber:
|
|
4695
|
+
sequenceNumber: rtx.payload.readUInt16BE(0),
|
|
4675
4696
|
timestamp: rtx.header.timestamp,
|
|
4676
4697
|
ssrc
|
|
4677
4698
|
}),
|
|
@@ -4680,6 +4701,8 @@ function unwrapRtx(rtx, payloadType, ssrc) {
|
|
|
4680
4701
|
return packet;
|
|
4681
4702
|
}
|
|
4682
4703
|
function wrapRtx(packet, payloadType, sequenceNumber, ssrc) {
|
|
4704
|
+
const originalSequence = Buffer.allocUnsafe(2);
|
|
4705
|
+
originalSequence.writeUInt16BE(packet.header.sequenceNumber, 0);
|
|
4683
4706
|
const rtx = new RtpPacket(
|
|
4684
4707
|
new RtpHeader({
|
|
4685
4708
|
payloadType,
|
|
@@ -4690,17 +4713,13 @@ function wrapRtx(packet, payloadType, sequenceNumber, ssrc) {
|
|
|
4690
4713
|
csrc: packet.header.csrc,
|
|
4691
4714
|
extensions: packet.header.extensions
|
|
4692
4715
|
}),
|
|
4693
|
-
Buffer.concat([
|
|
4694
|
-
Buffer.from(jspack2.Pack("!H", [packet.header.sequenceNumber])),
|
|
4695
|
-
packet.payload
|
|
4696
|
-
])
|
|
4716
|
+
Buffer.concat([originalSequence, packet.payload])
|
|
4697
4717
|
);
|
|
4698
4718
|
return rtx;
|
|
4699
4719
|
}
|
|
4700
4720
|
|
|
4701
4721
|
// ../rtp/src/srtp/context/context.ts
|
|
4702
|
-
import { createHmac as createHmac2 } from "crypto";
|
|
4703
|
-
import AES from "aes-js";
|
|
4722
|
+
import { createCipheriv as createCipheriv4, createHmac as createHmac2 } from "crypto";
|
|
4704
4723
|
|
|
4705
4724
|
// ../rtp/src/srtp/cipher/ctr.ts
|
|
4706
4725
|
import {
|
|
@@ -5088,6 +5107,11 @@ function finalizeAuthenticatedDecryption(decipher, packetType) {
|
|
|
5088
5107
|
}
|
|
5089
5108
|
|
|
5090
5109
|
// ../rtp/src/srtp/context/context.ts
|
|
5110
|
+
function aes128EcbEncrypt(key, plaintext) {
|
|
5111
|
+
const cipher = createCipheriv4("aes-128-ecb", key, null);
|
|
5112
|
+
cipher.setAutoPadding(false);
|
|
5113
|
+
return Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
5114
|
+
}
|
|
5091
5115
|
var Context = class {
|
|
5092
5116
|
constructor(masterKey, masterSalt, profile) {
|
|
5093
5117
|
this.masterKey = masterKey;
|
|
@@ -5154,8 +5178,7 @@ var Context = class {
|
|
|
5154
5178
|
sessionKey[j] = sessionKey[j] ^ labelAndIndexOverKdr[i];
|
|
5155
5179
|
}
|
|
5156
5180
|
sessionKey = Buffer.concat([sessionKey, Buffer.from([0, 0])]);
|
|
5157
|
-
|
|
5158
|
-
return Buffer.from(block.encrypt(sessionKey));
|
|
5181
|
+
return aes128EcbEncrypt(this.masterKey, sessionKey);
|
|
5159
5182
|
}
|
|
5160
5183
|
generateSessionSalt(label) {
|
|
5161
5184
|
let sessionSalt = Buffer.from(this.masterSalt);
|
|
@@ -5172,8 +5195,7 @@ var Context = class {
|
|
|
5172
5195
|
sessionSalt[j] = sessionSalt[j] ^ labelAndIndexOverKdr[i];
|
|
5173
5196
|
}
|
|
5174
5197
|
sessionSalt = Buffer.concat([sessionSalt, Buffer.from([0, 0])]);
|
|
5175
|
-
|
|
5176
|
-
sessionSalt = Buffer.from(block.encrypt(sessionSalt));
|
|
5198
|
+
sessionSalt = aes128EcbEncrypt(this.masterKey, sessionSalt);
|
|
5177
5199
|
return sessionSalt.subarray(0, 14);
|
|
5178
5200
|
}
|
|
5179
5201
|
generateSessionAuthTag(label) {
|
|
@@ -5198,9 +5220,8 @@ var Context = class {
|
|
|
5198
5220
|
sessionAuthTag,
|
|
5199
5221
|
Buffer.from([0, 1])
|
|
5200
5222
|
]);
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
secondRun = Buffer.from(block.encrypt(secondRun));
|
|
5223
|
+
firstRun = aes128EcbEncrypt(this.masterKey, firstRun);
|
|
5224
|
+
secondRun = aes128EcbEncrypt(this.masterKey, secondRun);
|
|
5204
5225
|
return Buffer.concat([firstRun, secondRun.subarray(0, 4)]);
|
|
5205
5226
|
}
|
|
5206
5227
|
getSrtpSsrcState(ssrc) {
|
|
@@ -7955,7 +7976,7 @@ function createECDHEPSKKeyExchange() {
|
|
|
7955
7976
|
}
|
|
7956
7977
|
|
|
7957
7978
|
// ../dtls/src/cipher/suites/aead.ts
|
|
7958
|
-
import { createCipheriv as
|
|
7979
|
+
import { createCipheriv as createCipheriv5, createDecipheriv as createDecipheriv3 } from "crypto";
|
|
7959
7980
|
var err2 = debug(
|
|
7960
7981
|
"werift-dtls : packages/dtls/src/cipher/suites/aead.ts : err"
|
|
7961
7982
|
);
|
|
@@ -8003,7 +8024,7 @@ var AEADCipher = class extends AbstractCipher {
|
|
|
8003
8024
|
iv.writeUIntBE(header.sequenceNumber, this.nonceImplicitLength + 2, 6);
|
|
8004
8025
|
const explicitNonce = iv.slice(this.nonceImplicitLength);
|
|
8005
8026
|
const additionalBuffer = this.encodeAdditionalBuffer(header, data.length);
|
|
8006
|
-
const cipher =
|
|
8027
|
+
const cipher = createCipheriv5(this.blockAlgorithm, writeKey, iv, {
|
|
8007
8028
|
authTagLength: this.authTagLength
|
|
8008
8029
|
});
|
|
8009
8030
|
cipher.setAAD(additionalBuffer, {
|
|
@@ -8956,17 +8977,82 @@ var COOKIE = 554869826;
|
|
|
8956
8977
|
var IPV4_PROTOCOL = 1;
|
|
8957
8978
|
var IPV6_PROTOCOL = 2;
|
|
8958
8979
|
|
|
8980
|
+
// ../ice-server/src/stun/ip.ts
|
|
8981
|
+
import { isIPv4, isIPv6 } from "node:net";
|
|
8982
|
+
function ipAddressToBuffer(address) {
|
|
8983
|
+
if (isIPv4(address)) {
|
|
8984
|
+
const buf = Buffer.allocUnsafe(4);
|
|
8985
|
+
const parts = address.split(".");
|
|
8986
|
+
for (let i = 0; i < 4; i++) {
|
|
8987
|
+
buf[i] = Number(parts[i]) & 255;
|
|
8988
|
+
}
|
|
8989
|
+
return buf;
|
|
8990
|
+
}
|
|
8991
|
+
if (!isIPv6(address)) {
|
|
8992
|
+
throw new Error(`Invalid ip address: ${address}`);
|
|
8993
|
+
}
|
|
8994
|
+
const sections = address.split(":", 8);
|
|
8995
|
+
for (let i = 0; i < sections.length; i++) {
|
|
8996
|
+
let v4Buffer;
|
|
8997
|
+
if (isIPv4(sections[i])) {
|
|
8998
|
+
v4Buffer = ipAddressToBuffer(sections[i]);
|
|
8999
|
+
sections[i] = v4Buffer.subarray(0, 2).toString("hex");
|
|
9000
|
+
}
|
|
9001
|
+
if (v4Buffer && ++i < 8) {
|
|
9002
|
+
sections.splice(i, 0, v4Buffer.subarray(2, 4).toString("hex"));
|
|
9003
|
+
}
|
|
9004
|
+
}
|
|
9005
|
+
if (sections[0] === "") {
|
|
9006
|
+
while (sections.length < 8) sections.unshift("0");
|
|
9007
|
+
} else if (sections[sections.length - 1] === "") {
|
|
9008
|
+
while (sections.length < 8) sections.push("0");
|
|
9009
|
+
} else if (sections.length < 8) {
|
|
9010
|
+
let emptyIndex = 0;
|
|
9011
|
+
for (; emptyIndex < sections.length && sections[emptyIndex] !== ""; emptyIndex++) ;
|
|
9012
|
+
const zeros = [];
|
|
9013
|
+
for (let n = 9 - sections.length; n > 0; n--) {
|
|
9014
|
+
zeros.push("0");
|
|
9015
|
+
}
|
|
9016
|
+
sections.splice(emptyIndex, 1, ...zeros);
|
|
9017
|
+
}
|
|
9018
|
+
const result = Buffer.allocUnsafe(16);
|
|
9019
|
+
let offset = 0;
|
|
9020
|
+
for (const section of sections) {
|
|
9021
|
+
const word = Number.parseInt(section, 16) || 0;
|
|
9022
|
+
result[offset++] = word >> 8 & 255;
|
|
9023
|
+
result[offset++] = word & 255;
|
|
9024
|
+
}
|
|
9025
|
+
return result;
|
|
9026
|
+
}
|
|
9027
|
+
function bufferToIpAddress(buf) {
|
|
9028
|
+
if (buf.length === 4) {
|
|
9029
|
+
return `${buf[0]}.${buf[1]}.${buf[2]}.${buf[3]}`;
|
|
9030
|
+
}
|
|
9031
|
+
if (buf.length !== 16) {
|
|
9032
|
+
throw new Error(`Invalid ip address buffer length: ${buf.length}`);
|
|
9033
|
+
}
|
|
9034
|
+
const hextets = [];
|
|
9035
|
+
for (let i = 0; i < 16; i += 2) {
|
|
9036
|
+
hextets.push(buf.readUInt16BE(i).toString(16));
|
|
9037
|
+
}
|
|
9038
|
+
let result = hextets.join(":");
|
|
9039
|
+
result = result.replace(/(^|:)0(:0)*:0(:|$)/, "$1::$3");
|
|
9040
|
+
result = result.replace(/:{3,4}/, "::");
|
|
9041
|
+
return result;
|
|
9042
|
+
}
|
|
9043
|
+
function isIpV4Address(address) {
|
|
9044
|
+
return isIPv4(address);
|
|
9045
|
+
}
|
|
9046
|
+
|
|
8959
9047
|
// ../ice-server/src/stun/attributes.ts
|
|
8960
|
-
import * as Int64 from "int64-buffer";
|
|
8961
|
-
import nodeIp from "ip";
|
|
8962
9048
|
function packAddress(value) {
|
|
8963
9049
|
const [address] = value;
|
|
8964
|
-
const protocol =
|
|
9050
|
+
const protocol = isIpV4Address(address) ? IPV4_PROTOCOL : IPV6_PROTOCOL;
|
|
8965
9051
|
const buffer2 = Buffer.alloc(4);
|
|
8966
9052
|
buffer2.writeUInt8(0, 0);
|
|
8967
9053
|
buffer2.writeUInt8(protocol, 1);
|
|
8968
9054
|
buffer2.writeUInt16BE(value[1], 2);
|
|
8969
|
-
return Buffer.concat([buffer2,
|
|
9055
|
+
return Buffer.concat([buffer2, ipAddressToBuffer(address)]);
|
|
8970
9056
|
}
|
|
8971
9057
|
function unpackErrorCode(data) {
|
|
8972
9058
|
if (data.length < 4) {
|
|
@@ -8989,12 +9075,12 @@ function unpackAddress(data) {
|
|
|
8989
9075
|
if (address.length !== 4) {
|
|
8990
9076
|
throw new Error("STUN address has invalid length for IPv4");
|
|
8991
9077
|
}
|
|
8992
|
-
return [
|
|
9078
|
+
return [bufferToIpAddress(address), port];
|
|
8993
9079
|
case IPV6_PROTOCOL:
|
|
8994
9080
|
if (address.length !== 16) {
|
|
8995
9081
|
throw new Error("STUN address has invalid length for IPv6");
|
|
8996
9082
|
}
|
|
8997
|
-
return [
|
|
9083
|
+
return [bufferToIpAddress(address), port];
|
|
8998
9084
|
default:
|
|
8999
9085
|
throw new Error("STUN address has unknown protocol");
|
|
9000
9086
|
}
|
|
@@ -9057,12 +9143,11 @@ var packUnsignedShort = (value) => {
|
|
|
9057
9143
|
};
|
|
9058
9144
|
var unpackUnsignedShort = (data) => data.readUInt16BE(0);
|
|
9059
9145
|
var packUnsigned64 = (value) => {
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
const int2 = new Int64.Int64BE(data);
|
|
9064
|
-
return BigInt(int2.toString());
|
|
9146
|
+
const buffer2 = Buffer.allocUnsafe(8);
|
|
9147
|
+
buffer2.writeBigUInt64BE(value, 0);
|
|
9148
|
+
return buffer2;
|
|
9065
9149
|
};
|
|
9150
|
+
var unpackUnsigned64 = (data) => data.readBigUInt64BE(0);
|
|
9066
9151
|
var packString = (value) => Buffer.from(value, "utf8");
|
|
9067
9152
|
var unpackString = (data) => data.toString("utf8");
|
|
9068
9153
|
var packSoftware = (value) => {
|
|
@@ -9143,10 +9228,6 @@ var log22 = debug("werift-ice : packages/ice/src/stun/protocol.ts");
|
|
|
9143
9228
|
// ../ice/src/turn/protocol.ts
|
|
9144
9229
|
var log23 = debug("werift-ice:packages/ice/src/turn/protocol.ts");
|
|
9145
9230
|
|
|
9146
|
-
// ../ice/src/ice.ts
|
|
9147
|
-
import * as Int642 from "int64-buffer";
|
|
9148
|
-
import isEqual from "fast-deep-equal";
|
|
9149
|
-
|
|
9150
9231
|
// ../ice/src/dns/lookup.ts
|
|
9151
9232
|
import mdns from "multicast-dns";
|
|
9152
9233
|
|
|
@@ -9154,7 +9235,6 @@ import mdns from "multicast-dns";
|
|
|
9154
9235
|
var log24 = debug("werift-ice : packages/ice/src/ice.ts : log");
|
|
9155
9236
|
|
|
9156
9237
|
// ../ice/src/utils.ts
|
|
9157
|
-
import nodeIp2 from "ip";
|
|
9158
9238
|
var logger = debug("werift-ice : packages/ice/src/utils.ts");
|
|
9159
9239
|
|
|
9160
9240
|
// ../ice/src/ice.ts
|
|
@@ -9413,9 +9493,6 @@ var LOST_SIZE2 = 30 * 5;
|
|
|
9413
9493
|
// src/media/receiver/receiverTwcc.ts
|
|
9414
9494
|
var log29 = debug("werift:packages/webrtc/media/receiver/receiverTwcc");
|
|
9415
9495
|
|
|
9416
|
-
// src/sdp.ts
|
|
9417
|
-
import * as Int643 from "int64-buffer";
|
|
9418
|
-
|
|
9419
9496
|
// src/transport/dtls.ts
|
|
9420
9497
|
import { Certificate as Certificate3, PrivateKey as PrivateKey2 } from "@fidm/x509";
|
|
9421
9498
|
var log30 = debug("werift:packages/webrtc/src/transport/dtls.ts");
|
|
@@ -9423,12 +9500,6 @@ var log30 = debug("werift:packages/webrtc/src/transport/dtls.ts");
|
|
|
9423
9500
|
// src/transport/ice.ts
|
|
9424
9501
|
var log31 = debug("werift:packages/webrtc/src/transport/ice.ts");
|
|
9425
9502
|
|
|
9426
|
-
// src/transport/sctp.ts
|
|
9427
|
-
import { jspack as jspack5 } from "@shinyoshiaki/jspack";
|
|
9428
|
-
|
|
9429
|
-
// ../sctp/src/sctp.ts
|
|
9430
|
-
import { jspack as jspack4 } from "@shinyoshiaki/jspack";
|
|
9431
|
-
|
|
9432
9503
|
// ../sctp/src/chunk.ts
|
|
9433
9504
|
var Chunk = class _Chunk {
|
|
9434
9505
|
constructor(flags = 0, _body = Buffer.from("")) {
|
|
@@ -9816,9 +9887,6 @@ function decodeParams(body) {
|
|
|
9816
9887
|
return params;
|
|
9817
9888
|
}
|
|
9818
9889
|
|
|
9819
|
-
// ../sctp/src/param.ts
|
|
9820
|
-
import { jspack as jspack3 } from "@shinyoshiaki/jspack";
|
|
9821
|
-
|
|
9822
9890
|
// ../sctp/src/sctp.ts
|
|
9823
9891
|
var log32 = debug("werift/sctp/sctp");
|
|
9824
9892
|
var SCTP_RTO_ALPHA = 1 / 8;
|
|
@@ -9857,7 +9925,6 @@ var log34 = debug("werift:packages/webrtc/src/media/rtpReceiver.ts");
|
|
|
9857
9925
|
var log35 = debug("werift:packages/webrtc/src/media/router.ts");
|
|
9858
9926
|
|
|
9859
9927
|
// src/media/rtpSender.ts
|
|
9860
|
-
import { jspack as jspack6 } from "@shinyoshiaki/jspack";
|
|
9861
9928
|
var log36 = debug("werift:packages/webrtc/src/media/rtpSender.ts");
|
|
9862
9929
|
|
|
9863
9930
|
// src/sctpManager.ts
|
package/lib/rtp/src/codec/av1.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.AV1Obu = exports.AV1RtpPayload = void 0;
|
|
5
5
|
exports.leb128decode = leb128decode;
|
|
6
|
-
const leb128_1 = require("@minhducsun2002/leb128");
|
|
7
6
|
const common_1 = require("../imports/common");
|
|
7
|
+
const leb128_1 = require("./leb128");
|
|
8
8
|
const log = (0, common_1.debug)("werift-rtp : packages/rtp/src/codec/av1.ts");
|
|
9
9
|
// 4.4 AV1 Aggregation Header
|
|
10
10
|
// 0 1 2 3 4 5 6 7
|
|
@@ -254,7 +254,7 @@ class AV1Obu {
|
|
|
254
254
|
.set(this.obu_reserved_1bit).buffer;
|
|
255
255
|
let obuSize = Buffer.alloc(0);
|
|
256
256
|
if (this.obu_has_size_field) {
|
|
257
|
-
obuSize = leb128_1.
|
|
257
|
+
obuSize = (0, leb128_1.leb128encode)(this.payload.length);
|
|
258
258
|
}
|
|
259
259
|
return Buffer.concat([header, obuSize, this.payload]);
|
|
260
260
|
}
|
|
@@ -264,14 +264,20 @@ function leb128decode(buf) {
|
|
|
264
264
|
let value = 0;
|
|
265
265
|
let leb128bytes = 0;
|
|
266
266
|
for (let i = 0; i < 8; i++) {
|
|
267
|
+
if (i >= buf.length) {
|
|
268
|
+
throw new Error("LEB128 decode incomplete");
|
|
269
|
+
}
|
|
267
270
|
const leb128byte = buf.readUInt8(i);
|
|
268
|
-
value
|
|
271
|
+
value += (leb128byte & 0x7f) * 128 ** i;
|
|
269
272
|
leb128bytes++;
|
|
270
273
|
if (!(leb128byte & 0x80)) {
|
|
271
|
-
|
|
274
|
+
if (!Number.isSafeInteger(value)) {
|
|
275
|
+
throw new Error("LEB128 value exceeds safe integer");
|
|
276
|
+
}
|
|
277
|
+
return [value, leb128bytes];
|
|
272
278
|
}
|
|
273
279
|
}
|
|
274
|
-
|
|
280
|
+
throw new Error("LEB128 decode incomplete");
|
|
275
281
|
}
|
|
276
282
|
const OBU_TYPES = {
|
|
277
283
|
0: "Reserved",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"av1.js","sourceRoot":"","sources":["../../../../../rtp/src/codec/av1.ts"],"names":[],"mappings":"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","sourcesContent":["// RTP Payload Format For AV1 https://aomediacodec.github.io/av1-rtp-spec/\n\nimport { LEB128 } from \"@minhducsun2002/leb128\";\n\nimport type { RtpHeader } from \"..\";\nimport { BitWriter2, debug, getBit } from \"../imports/common\";\n\nconst log = debug(\"werift-rtp : packages/rtp/src/codec/av1.ts\");\n\n// 4.4 AV1 Aggregation Header\n// 0 1 2 3 4 5 6 7\n// +-+-+-+-+-+-+-+-+\n// |Z|Y| W |N|-|-|-|\n// +-+-+-+-+-+-+-+-+\n\n// RTP payload syntax:\n// 0 1 2 3\n// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |Z|Y|0 0|N|-|-|-| OBU element 1 size (leb128) | |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |\n// : :\n// : OBU element 1 data :\n// : :\n// | |\n// | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// | | OBU element 2 size (leb128) |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// : :\n// : OBU element 2 data :\n// : :\n// | |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// : :\n// : ... :\n// : :\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |OBU e... N size| |\n// +-+-+-+-+-+-+-+-+ OBU element N data +-+-+-+-+-+-+-+-+\n// | |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n// OBU syntax:\n// 0 1 2 3 4 5 6 7\n// +-+-+-+-+-+-+-+-+\n// |0| type |X|S|-| (REQUIRED)\n// +-+-+-+-+-+-+-+-+\n// X: | TID |SID|-|-|-| (OPTIONAL)\n// +-+-+-+-+-+-+-+-+\n// |1| |\n// +-+ OBU payload |\n// S: |1| | (OPTIONAL, variable length leb128 encoded)\n// +-+ size |\n// |0| |\n// +-+-+-+-+-+-+-+-+\n// | OBU payload |\n// | ... |\n\nexport class AV1RtpPayload {\n /**\n * RtpStartsWithFragment\n * MUST be set to 1 if the first OBU element is an OBU fragment that is a continuation of an OBU fragment from the previous packet, and MUST be set to 0 otherwise.\n */\n zBit_RtpStartsWithFragment!: number;\n /**\n * RtpEndsWithFragment\n * MUST be set to 1 if the last OBU element is an OBU fragment that will continue in the next packet, and MUST be set to 0 otherwise.\n */\n yBit_RtpEndsWithFragment!: number;\n /**\n * RtpNumObus\n * two bit field that describes the number of OBU elements in the packet. This field MUST be set equal to 0 or equal to the number of OBU elements contained in the packet. If set to 0, each OBU element MUST be preceded by a length field.\n */\n w_RtpNumObus!: number;\n /**\n * RtpStartsNewCodedVideoSequence\n * MUST be set to 1 if the packet is the first packet of a coded video sequence, and MUST be set to 0 otherwise.\n */\n nBit_RtpStartsNewCodedVideoSequence!: number;\n obu_or_fragment: { data: Buffer; isFragment: boolean }[] = [];\n\n static deSerialize = (buf: Buffer) => {\n const p = new AV1RtpPayload();\n\n let offset = 0;\n\n p.zBit_RtpStartsWithFragment = getBit(buf[offset], 0);\n p.yBit_RtpEndsWithFragment = getBit(buf[offset], 1);\n p.w_RtpNumObus = getBit(buf[offset], 2, 2);\n p.nBit_RtpStartsNewCodedVideoSequence = getBit(buf[offset], 4);\n offset++;\n\n if (p.nBit_RtpStartsNewCodedVideoSequence && p.zBit_RtpStartsWithFragment) {\n throw new Error();\n }\n\n [...Array(p.w_RtpNumObus - 1).keys()].forEach((i) => {\n const [elementSize, bytes] = leb128decode(buf.subarray(offset));\n\n const start = offset + bytes;\n const end = start + elementSize;\n\n let isFragment = false;\n if (p.zBit_RtpStartsWithFragment && i === 0) {\n isFragment = true;\n }\n p.obu_or_fragment.push({ data: buf.subarray(start, end), isFragment });\n\n offset += bytes + elementSize;\n });\n let isFragment = false;\n if (\n p.yBit_RtpEndsWithFragment ||\n (p.w_RtpNumObus === 1 && p.zBit_RtpStartsWithFragment)\n ) {\n isFragment = true;\n }\n p.obu_or_fragment.push({\n data: buf.subarray(offset),\n isFragment: isFragment,\n });\n\n return p;\n };\n\n static isDetectedFinalPacketInSequence(header: RtpHeader) {\n return header.marker;\n }\n\n get isKeyframe() {\n return this.nBit_RtpStartsNewCodedVideoSequence === 1;\n }\n\n static getFrame(payloads: AV1RtpPayload[]) {\n const frames: Buffer[] = [];\n const objects = payloads\n .flatMap((p) => p.obu_or_fragment)\n .reduce(\n (\n acc: Record<number, { data: Buffer; isFragment: boolean }>,\n cur,\n i,\n ) => {\n acc[i] = cur;\n return acc;\n },\n {},\n );\n const length = Object.keys(objects).length;\n\n for (const i of Object.keys(objects).map(Number)) {\n const exist = objects[i];\n if (!exist) continue;\n const { data, isFragment } = exist;\n if (isFragment) {\n let fragments: Buffer[] = [];\n for (let head = i; head < length; head++) {\n const target = objects[head];\n if (target.isFragment) {\n fragments.push(target.data);\n delete objects[head];\n } else {\n break;\n }\n }\n if (fragments.length <= 1) {\n log(\"fragment lost, maybe packet lost\");\n fragments = [];\n }\n frames.push(Buffer.concat(fragments));\n } else {\n frames.push(data);\n }\n }\n const obus = frames.map((f) => AV1Obu.deSerialize(f));\n const lastObu = obus.pop()!;\n return Buffer.concat([\n ...obus.map((o) => {\n o.obu_has_size_field = 1;\n return o.serialize();\n }),\n lastObu.serialize(),\n ]);\n }\n}\n\nexport class AV1Obu {\n obu_forbidden_bit!: number;\n obu_type!: OBU_TYPE;\n obu_extension_flag!: number;\n obu_has_size_field!: number;\n obu_reserved_1bit!: number;\n payload!: Buffer;\n\n static deSerialize(buf: Buffer) {\n const obu = new AV1Obu();\n let offset = 0;\n obu.obu_forbidden_bit = getBit(buf[offset], 0);\n obu.obu_type =\n OBU_TYPES[getBit(buf[offset], 1, 4) as keyof typeof OBU_TYPES];\n obu.obu_extension_flag = getBit(buf[offset], 5);\n obu.obu_has_size_field = getBit(buf[offset], 6);\n obu.obu_reserved_1bit = getBit(buf[offset], 7);\n offset++;\n\n obu.payload = buf.subarray(offset);\n\n return obu;\n }\n\n serialize() {\n const header = new BitWriter2(8)\n .set(this.obu_forbidden_bit)\n .set(OBU_TYPE_IDS[this.obu_type], 4)\n .set(this.obu_extension_flag)\n .set(this.obu_has_size_field)\n .set(this.obu_reserved_1bit).buffer;\n let obuSize: Uint8Array | Buffer = Buffer.alloc(0);\n if (this.obu_has_size_field) {\n obuSize = LEB128.encode(this.payload.length);\n }\n return Buffer.concat([header, obuSize, this.payload]);\n }\n}\n\nexport function leb128decode(buf: Buffer) {\n let value = 0;\n let leb128bytes = 0;\n for (let i = 0; i < 8; i++) {\n const leb128byte = buf.readUInt8(i);\n value |= (leb128byte & 0x7f) << (i * 7);\n leb128bytes++;\n if (!(leb128byte & 0x80)) {\n break;\n }\n }\n return [value, leb128bytes];\n}\n\nconst OBU_TYPES = {\n 0: \"Reserved\",\n 1: \"OBU_SEQUENCE_HEADER\",\n 2: \"OBU_TEMPORAL_DELIMITER\",\n 3: \"OBU_FRAME_HEADER\",\n 4: \"OBU_TILE_GROUP\",\n 5: \"OBU_METADATA\",\n 6: \"OBU_FRAME\",\n 7: \"OBU_REDUNDANT_FRAME_HEADER\",\n 8: \"OBU_TILE_LIST\",\n 15: \"OBU_PADDING\",\n} as const;\ntype OBU_TYPE = (typeof OBU_TYPES)[keyof typeof OBU_TYPES];\nconst OBU_TYPE_IDS: Record<OBU_TYPE, number> = Object.entries(OBU_TYPES).reduce(\n (acc: any, [key, value]) => {\n acc[value] = Number(key);\n return acc;\n },\n {},\n);\n"]}
|
|
1
|
+
{"version":3,"file":"av1.js","sourceRoot":"","sources":["../../../../../rtp/src/codec/av1.ts"],"names":[],"mappings":"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","sourcesContent":["// RTP Payload Format For AV1 https://aomediacodec.github.io/av1-rtp-spec/\n\nimport type { RtpHeader } from \"..\";\nimport { BitWriter2, debug, getBit } from \"../imports/common\";\nimport { leb128encode } from \"./leb128\";\n\nconst log = debug(\"werift-rtp : packages/rtp/src/codec/av1.ts\");\n\n// 4.4 AV1 Aggregation Header\n// 0 1 2 3 4 5 6 7\n// +-+-+-+-+-+-+-+-+\n// |Z|Y| W |N|-|-|-|\n// +-+-+-+-+-+-+-+-+\n\n// RTP payload syntax:\n// 0 1 2 3\n// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |Z|Y|0 0|N|-|-|-| OBU element 1 size (leb128) | |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |\n// : :\n// : OBU element 1 data :\n// : :\n// | |\n// | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// | | OBU element 2 size (leb128) |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// : :\n// : OBU element 2 data :\n// : :\n// | |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// : :\n// : ... :\n// : :\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |OBU e... N size| |\n// +-+-+-+-+-+-+-+-+ OBU element N data +-+-+-+-+-+-+-+-+\n// | |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n// OBU syntax:\n// 0 1 2 3 4 5 6 7\n// +-+-+-+-+-+-+-+-+\n// |0| type |X|S|-| (REQUIRED)\n// +-+-+-+-+-+-+-+-+\n// X: | TID |SID|-|-|-| (OPTIONAL)\n// +-+-+-+-+-+-+-+-+\n// |1| |\n// +-+ OBU payload |\n// S: |1| | (OPTIONAL, variable length leb128 encoded)\n// +-+ size |\n// |0| |\n// +-+-+-+-+-+-+-+-+\n// | OBU payload |\n// | ... |\n\nexport class AV1RtpPayload {\n /**\n * RtpStartsWithFragment\n * MUST be set to 1 if the first OBU element is an OBU fragment that is a continuation of an OBU fragment from the previous packet, and MUST be set to 0 otherwise.\n */\n zBit_RtpStartsWithFragment!: number;\n /**\n * RtpEndsWithFragment\n * MUST be set to 1 if the last OBU element is an OBU fragment that will continue in the next packet, and MUST be set to 0 otherwise.\n */\n yBit_RtpEndsWithFragment!: number;\n /**\n * RtpNumObus\n * two bit field that describes the number of OBU elements in the packet. This field MUST be set equal to 0 or equal to the number of OBU elements contained in the packet. If set to 0, each OBU element MUST be preceded by a length field.\n */\n w_RtpNumObus!: number;\n /**\n * RtpStartsNewCodedVideoSequence\n * MUST be set to 1 if the packet is the first packet of a coded video sequence, and MUST be set to 0 otherwise.\n */\n nBit_RtpStartsNewCodedVideoSequence!: number;\n obu_or_fragment: { data: Buffer; isFragment: boolean }[] = [];\n\n static deSerialize = (buf: Buffer) => {\n const p = new AV1RtpPayload();\n\n let offset = 0;\n\n p.zBit_RtpStartsWithFragment = getBit(buf[offset], 0);\n p.yBit_RtpEndsWithFragment = getBit(buf[offset], 1);\n p.w_RtpNumObus = getBit(buf[offset], 2, 2);\n p.nBit_RtpStartsNewCodedVideoSequence = getBit(buf[offset], 4);\n offset++;\n\n if (p.nBit_RtpStartsNewCodedVideoSequence && p.zBit_RtpStartsWithFragment) {\n throw new Error();\n }\n\n [...Array(p.w_RtpNumObus - 1).keys()].forEach((i) => {\n const [elementSize, bytes] = leb128decode(buf.subarray(offset));\n\n const start = offset + bytes;\n const end = start + elementSize;\n\n let isFragment = false;\n if (p.zBit_RtpStartsWithFragment && i === 0) {\n isFragment = true;\n }\n p.obu_or_fragment.push({ data: buf.subarray(start, end), isFragment });\n\n offset += bytes + elementSize;\n });\n let isFragment = false;\n if (\n p.yBit_RtpEndsWithFragment ||\n (p.w_RtpNumObus === 1 && p.zBit_RtpStartsWithFragment)\n ) {\n isFragment = true;\n }\n p.obu_or_fragment.push({\n data: buf.subarray(offset),\n isFragment: isFragment,\n });\n\n return p;\n };\n\n static isDetectedFinalPacketInSequence(header: RtpHeader) {\n return header.marker;\n }\n\n get isKeyframe() {\n return this.nBit_RtpStartsNewCodedVideoSequence === 1;\n }\n\n static getFrame(payloads: AV1RtpPayload[]) {\n const frames: Buffer[] = [];\n const objects = payloads\n .flatMap((p) => p.obu_or_fragment)\n .reduce(\n (\n acc: Record<number, { data: Buffer; isFragment: boolean }>,\n cur,\n i,\n ) => {\n acc[i] = cur;\n return acc;\n },\n {},\n );\n const length = Object.keys(objects).length;\n\n for (const i of Object.keys(objects).map(Number)) {\n const exist = objects[i];\n if (!exist) continue;\n const { data, isFragment } = exist;\n if (isFragment) {\n let fragments: Buffer[] = [];\n for (let head = i; head < length; head++) {\n const target = objects[head];\n if (target.isFragment) {\n fragments.push(target.data);\n delete objects[head];\n } else {\n break;\n }\n }\n if (fragments.length <= 1) {\n log(\"fragment lost, maybe packet lost\");\n fragments = [];\n }\n frames.push(Buffer.concat(fragments));\n } else {\n frames.push(data);\n }\n }\n const obus = frames.map((f) => AV1Obu.deSerialize(f));\n const lastObu = obus.pop()!;\n return Buffer.concat([\n ...obus.map((o) => {\n o.obu_has_size_field = 1;\n return o.serialize();\n }),\n lastObu.serialize(),\n ]);\n }\n}\n\nexport class AV1Obu {\n obu_forbidden_bit!: number;\n obu_type!: OBU_TYPE;\n obu_extension_flag!: number;\n obu_has_size_field!: number;\n obu_reserved_1bit!: number;\n payload!: Buffer;\n\n static deSerialize(buf: Buffer) {\n const obu = new AV1Obu();\n let offset = 0;\n obu.obu_forbidden_bit = getBit(buf[offset], 0);\n obu.obu_type =\n OBU_TYPES[getBit(buf[offset], 1, 4) as keyof typeof OBU_TYPES];\n obu.obu_extension_flag = getBit(buf[offset], 5);\n obu.obu_has_size_field = getBit(buf[offset], 6);\n obu.obu_reserved_1bit = getBit(buf[offset], 7);\n offset++;\n\n obu.payload = buf.subarray(offset);\n\n return obu;\n }\n\n serialize() {\n const header = new BitWriter2(8)\n .set(this.obu_forbidden_bit)\n .set(OBU_TYPE_IDS[this.obu_type], 4)\n .set(this.obu_extension_flag)\n .set(this.obu_has_size_field)\n .set(this.obu_reserved_1bit).buffer;\n let obuSize: Buffer = Buffer.alloc(0);\n if (this.obu_has_size_field) {\n obuSize = leb128encode(this.payload.length);\n }\n return Buffer.concat([header, obuSize, this.payload]);\n }\n}\n\nexport function leb128decode(buf: Buffer) {\n let value = 0;\n let leb128bytes = 0;\n for (let i = 0; i < 8; i++) {\n if (i >= buf.length) {\n throw new Error(\"LEB128 decode incomplete\");\n }\n const leb128byte = buf.readUInt8(i);\n value += (leb128byte & 0x7f) * 128 ** i;\n leb128bytes++;\n if (!(leb128byte & 0x80)) {\n if (!Number.isSafeInteger(value)) {\n throw new Error(\"LEB128 value exceeds safe integer\");\n }\n return [value, leb128bytes];\n }\n }\n throw new Error(\"LEB128 decode incomplete\");\n}\n\nconst OBU_TYPES = {\n 0: \"Reserved\",\n 1: \"OBU_SEQUENCE_HEADER\",\n 2: \"OBU_TEMPORAL_DELIMITER\",\n 3: \"OBU_FRAME_HEADER\",\n 4: \"OBU_TILE_GROUP\",\n 5: \"OBU_METADATA\",\n 6: \"OBU_FRAME\",\n 7: \"OBU_REDUNDANT_FRAME_HEADER\",\n 8: \"OBU_TILE_LIST\",\n 15: \"OBU_PADDING\",\n} as const;\ntype OBU_TYPE = (typeof OBU_TYPES)[keyof typeof OBU_TYPES];\nconst OBU_TYPE_IDS: Record<OBU_TYPE, number> = Object.entries(OBU_TYPES).reduce(\n (acc: any, [key, value]) => {\n acc[value] = Number(key);\n return acc;\n },\n {},\n);\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.leb128encode = leb128encode;
|
|
4
|
+
/**
|
|
5
|
+
* Unsigned LEB128 encoder(package-private)。
|
|
6
|
+
* `codec/index.ts` の public barrel からは re-export しない。decode は `av1.ts` 側の公開 API を維持する。
|
|
7
|
+
*/
|
|
8
|
+
function leb128encode(value) {
|
|
9
|
+
if (!Number.isInteger(value) || value < 0 || !Number.isSafeInteger(value)) {
|
|
10
|
+
throw new Error("LEB128 encode requires a non-negative safe integer");
|
|
11
|
+
}
|
|
12
|
+
const bytes = [];
|
|
13
|
+
let remaining = value;
|
|
14
|
+
do {
|
|
15
|
+
let byte = remaining & 0x7f;
|
|
16
|
+
remaining = Math.floor(remaining / 128);
|
|
17
|
+
if (remaining !== 0) {
|
|
18
|
+
byte |= 0x80;
|
|
19
|
+
}
|
|
20
|
+
bytes.push(byte);
|
|
21
|
+
} while (remaining !== 0);
|
|
22
|
+
return Buffer.from(bytes);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=leb128.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leb128.js","sourceRoot":"","sources":["../../../../../rtp/src/codec/leb128.ts"],"names":[],"mappings":";;AAIA,oCAiBC;AArBD;;;GAGG;AACH,SAAgB,YAAY,CAAC,KAAa;IACxC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,GAAG,CAAC;QACF,IAAI,IAAI,GAAG,SAAS,GAAG,IAAI,CAAC;QAC5B,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;QACxC,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpB,IAAI,IAAI,IAAI,CAAC;QACf,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,QAAQ,SAAS,KAAK,CAAC,EAAE;IAE1B,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC","sourcesContent":["/**\n * Unsigned LEB128 encoder(package-private)。\n * `codec/index.ts` の public barrel からは re-export しない。decode は `av1.ts` 側の公開 API を維持する。\n */\nexport function leb128encode(value: number): Buffer {\n if (!Number.isInteger(value) || value < 0 || !Number.isSafeInteger(value)) {\n throw new Error(\"LEB128 encode requires a non-negative safe integer\");\n }\n\n const bytes: number[] = [];\n let remaining = value;\n do {\n let byte = remaining & 0x7f;\n remaining = Math.floor(remaining / 128);\n if (remaining !== 0) {\n byte |= 0x80;\n }\n bytes.push(byte);\n } while (remaining !== 0);\n\n return Buffer.from(bytes);\n}\n"]}
|
package/lib/rtp/src/rtp/rtx.js
CHANGED
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.unwrapRtx = unwrapRtx;
|
|
4
4
|
exports.wrapRtx = wrapRtx;
|
|
5
|
-
const jspack_1 = require("@shinyoshiaki/jspack");
|
|
6
5
|
const rtp_1 = require("./rtp");
|
|
7
6
|
function unwrapRtx(rtx, payloadType, ssrc) {
|
|
8
7
|
const packet = new rtp_1.RtpPacket(new rtp_1.RtpHeader({
|
|
9
8
|
payloadType,
|
|
10
9
|
marker: rtx.header.marker,
|
|
11
|
-
sequenceNumber:
|
|
10
|
+
sequenceNumber: rtx.payload.readUInt16BE(0),
|
|
12
11
|
timestamp: rtx.header.timestamp,
|
|
13
12
|
ssrc,
|
|
14
13
|
}), rtx.payload.subarray(2));
|
|
15
14
|
return packet;
|
|
16
15
|
}
|
|
17
16
|
function wrapRtx(packet, payloadType, sequenceNumber, ssrc) {
|
|
17
|
+
const originalSequence = Buffer.allocUnsafe(2);
|
|
18
|
+
originalSequence.writeUInt16BE(packet.header.sequenceNumber, 0);
|
|
18
19
|
const rtx = new rtp_1.RtpPacket(new rtp_1.RtpHeader({
|
|
19
20
|
payloadType,
|
|
20
21
|
marker: packet.header.marker,
|
|
@@ -23,10 +24,7 @@ function wrapRtx(packet, payloadType, sequenceNumber, ssrc) {
|
|
|
23
24
|
ssrc,
|
|
24
25
|
csrc: packet.header.csrc,
|
|
25
26
|
extensions: packet.header.extensions,
|
|
26
|
-
}), Buffer.concat([
|
|
27
|
-
Buffer.from(jspack_1.jspack.Pack("!H", [packet.header.sequenceNumber])),
|
|
28
|
-
packet.payload,
|
|
29
|
-
]));
|
|
27
|
+
}), Buffer.concat([originalSequence, packet.payload]));
|
|
30
28
|
return rtx;
|
|
31
29
|
}
|
|
32
30
|
//# sourceMappingURL=rtx.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rtx.js","sourceRoot":"","sources":["../../../../../rtp/src/rtp/rtx.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"rtx.js","sourceRoot":"","sources":["../../../../../rtp/src/rtp/rtx.ts"],"names":[],"mappings":";;AAEA,8BAYC;AAED,0BAqBC;AArCD,+BAA6C;AAE7C,SAAgB,SAAS,CAAC,GAAc,EAAE,WAAmB,EAAE,IAAY;IACzE,MAAM,MAAM,GAAG,IAAI,eAAS,CAC1B,IAAI,eAAS,CAAC;QACZ,WAAW;QACX,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM;QACzB,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;QAC3C,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS;QAC/B,IAAI;KACL,CAAC,EACF,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CACxB,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,OAAO,CACrB,MAAiB,EACjB,WAAmB,EACnB,cAAsB,EACtB,IAAY;IAEZ,MAAM,gBAAgB,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/C,gBAAgB,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;IAChE,MAAM,GAAG,GAAG,IAAI,eAAS,CACvB,IAAI,eAAS,CAAC;QACZ,WAAW;QACX,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;QAC5B,cAAc;QACd,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS;QAClC,IAAI;QACJ,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI;QACxB,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU;KACrC,CAAC,EACF,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAClD,CAAC;IACF,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import { RtpHeader, RtpPacket } from \"./rtp\";\n\nexport function unwrapRtx(rtx: RtpPacket, payloadType: number, ssrc: number) {\n const packet = new RtpPacket(\n new RtpHeader({\n payloadType,\n marker: rtx.header.marker,\n sequenceNumber: rtx.payload.readUInt16BE(0),\n timestamp: rtx.header.timestamp,\n ssrc,\n }),\n rtx.payload.subarray(2),\n );\n return packet;\n}\n\nexport function wrapRtx(\n packet: RtpPacket,\n payloadType: number,\n sequenceNumber: number,\n ssrc: number,\n) {\n const originalSequence = Buffer.allocUnsafe(2);\n originalSequence.writeUInt16BE(packet.header.sequenceNumber, 0);\n const rtx = new RtpPacket(\n new RtpHeader({\n payloadType,\n marker: packet.header.marker,\n sequenceNumber,\n timestamp: packet.header.timestamp,\n ssrc,\n csrc: packet.header.csrc,\n extensions: packet.header.extensions,\n }),\n Buffer.concat([originalSequence, packet.payload]),\n );\n return rtx;\n}\n"]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createHmac } from "crypto";
|
|
2
2
|
import type { CipherAesBase } from "../cipher";
|
|
3
3
|
import { type SrtpProfile } from "../const";
|
|
4
|
+
/** AES-128-ECB single-block encrypt for SRTP KDF (no padding). */
|
|
5
|
+
export declare function aes128EcbEncrypt(key: Buffer, plaintext: Buffer): Buffer;
|
|
4
6
|
export declare class Context {
|
|
5
7
|
masterKey: Buffer;
|
|
6
8
|
masterSalt: Buffer;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.Context = void 0;
|
|
4
|
+
exports.aes128EcbEncrypt = aes128EcbEncrypt;
|
|
7
5
|
const crypto_1 = require("crypto");
|
|
8
|
-
const aes_js_1 = __importDefault(require("aes-js"));
|
|
9
6
|
const ctr_1 = require("../cipher/ctr");
|
|
10
7
|
const gcm_1 = require("../cipher/gcm");
|
|
11
8
|
const const_1 = require("../const");
|
|
9
|
+
/** AES-128-ECB single-block encrypt for SRTP KDF (no padding). */
|
|
10
|
+
function aes128EcbEncrypt(key, plaintext) {
|
|
11
|
+
const cipher = (0, crypto_1.createCipheriv)("aes-128-ecb", key, null);
|
|
12
|
+
cipher.setAutoPadding(false);
|
|
13
|
+
return Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
14
|
+
}
|
|
12
15
|
class Context {
|
|
13
16
|
constructor(masterKey, masterSalt, profile) {
|
|
14
17
|
Object.defineProperty(this, "masterKey", {
|
|
@@ -96,7 +99,7 @@ class Context {
|
|
|
96
99
|
value: void 0
|
|
97
100
|
});
|
|
98
101
|
{
|
|
99
|
-
//
|
|
102
|
+
// AES-ECB plaintext require 16byte
|
|
100
103
|
// so need to padding to 14 byte
|
|
101
104
|
const diff = 14 - masterSalt.length;
|
|
102
105
|
if (diff > 0) {
|
|
@@ -135,8 +138,7 @@ class Context {
|
|
|
135
138
|
sessionKey[j] = sessionKey[j] ^ labelAndIndexOverKdr[i];
|
|
136
139
|
}
|
|
137
140
|
sessionKey = Buffer.concat([sessionKey, Buffer.from([0x00, 0x00])]);
|
|
138
|
-
|
|
139
|
-
return Buffer.from(block.encrypt(sessionKey));
|
|
141
|
+
return aes128EcbEncrypt(this.masterKey, sessionKey);
|
|
140
142
|
}
|
|
141
143
|
generateSessionSalt(label) {
|
|
142
144
|
let sessionSalt = Buffer.from(this.masterSalt);
|
|
@@ -153,8 +155,7 @@ class Context {
|
|
|
153
155
|
sessionSalt[j] = sessionSalt[j] ^ labelAndIndexOverKdr[i];
|
|
154
156
|
}
|
|
155
157
|
sessionSalt = Buffer.concat([sessionSalt, Buffer.from([0x00, 0x00])]);
|
|
156
|
-
|
|
157
|
-
sessionSalt = Buffer.from(block.encrypt(sessionSalt));
|
|
158
|
+
sessionSalt = aes128EcbEncrypt(this.masterKey, sessionSalt);
|
|
158
159
|
return sessionSalt.subarray(0, 14);
|
|
159
160
|
}
|
|
160
161
|
generateSessionAuthTag(label) {
|
|
@@ -179,9 +180,8 @@ class Context {
|
|
|
179
180
|
sessionAuthTag,
|
|
180
181
|
Buffer.from([0x00, 0x01]),
|
|
181
182
|
]);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
secondRun = Buffer.from(block.encrypt(secondRun));
|
|
183
|
+
firstRun = aes128EcbEncrypt(this.masterKey, firstRun);
|
|
184
|
+
secondRun = aes128EcbEncrypt(this.masterKey, secondRun);
|
|
185
185
|
return Buffer.concat([firstRun, secondRun.subarray(0, 4)]);
|
|
186
186
|
}
|
|
187
187
|
getSrtpSsrcState(ssrc) {
|