summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/tests/mochitests/parser_rtp.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/media/webrtc/tests/mochitests/parser_rtp.js
parentInitial commit. (diff)
downloadfirefox-esr-upstream.tar.xz
firefox-esr-upstream.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/webrtc/tests/mochitests/parser_rtp.js')
-rw-r--r--dom/media/webrtc/tests/mochitests/parser_rtp.js131
1 files changed, 131 insertions, 0 deletions
diff --git a/dom/media/webrtc/tests/mochitests/parser_rtp.js b/dom/media/webrtc/tests/mochitests/parser_rtp.js
new file mode 100644
index 0000000000..2275c1f787
--- /dev/null
+++ b/dom/media/webrtc/tests/mochitests/parser_rtp.js
@@ -0,0 +1,131 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+/*
+ * Parses an RTP packet
+ * @param buffer an ArrayBuffer that contains the packet
+ * @return { type: "rtp", header: {...}, payload: a DataView }
+ */
+var ParseRtpPacket = buffer => {
+ // DataView.getFooInt returns big endian numbers by default
+ let view = new DataView(buffer);
+
+ // Standard Header Fields
+ // https://tools.ietf.org/html/rfc3550#section-5.1
+ // 0 1 2 3
+ // 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
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // |V=2|P|X| CC |M| PT | sequence number |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | timestamp |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | synchronization source (SSRC) identifier |
+ // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+ // | contributing source (CSRC) identifiers |
+ // | .... |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ let header = {};
+ let offset = 0;
+ // Note that incrementing the offset happens as close to reading the data as
+ // possible. This simplifies ensuring that the number of read bytes and the
+ // offset increment match. Data may be manipulated between when the offset is
+ // incremented and before the next read.
+ let byte = view.getUint8(offset);
+ offset++;
+ // Version 2 Bit
+ header.version = (0xc0 & byte) >> 6;
+ // Padding 1 Bit
+ header.padding = (0x30 & byte) >> 5;
+ // Extension 1 Bit
+ header.extensionsPresent = (0x10 & byte) >> 4 == 1;
+ // CSRC count 4 Bit
+ header.csrcCount = 0xf & byte;
+
+ byte = view.getUint8(offset);
+ offset++;
+ // Marker 1 Bit
+ header.marker = (0x80 & byte) >> 7;
+ // Payload Type 7 Bit
+ header.payloadType = 0x7f & byte;
+ // Sequence Number 16 Bit
+ header.sequenceNumber = view.getUint16(offset);
+ offset += 2;
+ // Timestamp 32 Bit
+ header.timestamp = view.getUint32(offset);
+ offset += 4;
+ // SSRC 32 Bit
+ header.ssrc = view.getUint32(offset);
+ offset += 4;
+
+ // CSRC 32 Bit
+ header.csrcs = [];
+ for (let c = 0; c < header.csrcCount; c++) {
+ header.csrcs.push(view.getUint32(offset));
+ offset += 4;
+ }
+
+ // Extensions
+ header.extensions = [];
+ header.extensionPaddingBytes = 0;
+ header.extensionsTotalLength = 0;
+ if (header.extensionsPresent) {
+ // https://tools.ietf.org/html/rfc3550#section-5.3.1
+ // 0 1 2 3
+ // 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
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | defined by profile | length |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | header extension |
+ // | .... |
+ let addExtension = (id, len) =>
+ header.extensions.push({
+ id,
+ data: new DataView(buffer, offset, len),
+ });
+ let extensionId = view.getUint16(offset);
+ offset += 2;
+ // len is in 32 bit units, not bytes
+ header.extensionsTotalLength = view.getUint16(offset) * 4;
+ offset += 2;
+ // Check for https://tools.ietf.org/html/rfc5285
+ if (extensionId != 0xbede) {
+ // No rfc5285
+ addExtension(extensionId, header.extensionsTotalLength);
+ offset += header.extensionsTotalLength;
+ } else {
+ let expectedEnd = offset + header.extensionsTotalLength;
+ while (offset < expectedEnd) {
+ // We only support "one-byte" extension headers ATM
+ // https://tools.ietf.org/html/rfc5285#section-4.2
+ // 0
+ // 0 1 2 3 4 5 6 7
+ // +-+-+-+-+-+-+-+-+
+ // | ID | len |
+ // +-+-+-+-+-+-+-+-+
+ byte = view.getUint8(offset);
+ offset++;
+ // Check for padding which can occur between extensions or at the end
+ if (byte == 0) {
+ header.extensionPaddingBytes++;
+ continue;
+ }
+ let id = (byte & 0xf0) >> 4;
+ // Check for the FORBIDDEN id (15), dun dun dun
+ if (id == 15) {
+ // Ignore bytes until until the end of extensions
+ offset = expectedEnd;
+ break;
+ }
+ // the length of the extention is len + 1
+ let len = (byte & 0x0f) + 1;
+ addExtension(id, len);
+ offset += len;
+ }
+ }
+ }
+ return { type: "rtp", header, payload: new DataView(buffer, offset) };
+};