UNPKG

rtp.js

Version:

RTP stack for Node.js and browser written in TypeScript

204 lines (203 loc) 6.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExtendedReport = exports.ExtendedReportType = exports.COMMON_HEADER_LENGTH = void 0; exports.getExtendedReportType = getExtendedReportType; exports.getExtendedReportLength = getExtendedReportLength; exports.setExtendedReportLength = setExtendedReportLength; const Serializable_1 = require("../../Serializable"); const helpers_1 = require("../../../utils/helpers"); exports.COMMON_HEADER_LENGTH = 4; /** * Extended Report types. * * @category RTCP Extended Reports */ var ExtendedReportType; (function (ExtendedReportType) { /** * Loss RLE Report. */ ExtendedReportType[ExtendedReportType["LRLE"] = 1] = "LRLE"; /** * Duplicate RLE Report. */ ExtendedReportType[ExtendedReportType["DRLE"] = 2] = "DRLE"; /** * Packet Receipt Times Report. */ ExtendedReportType[ExtendedReportType["PRT"] = 3] = "PRT"; /** * Receiver Reference Time Report. */ ExtendedReportType[ExtendedReportType["RRT"] = 4] = "RRT"; /** * DLRR Report. */ ExtendedReportType[ExtendedReportType["DLRR"] = 5] = "DLRR"; /** * Statistics Summary Report. */ ExtendedReportType[ExtendedReportType["SS"] = 6] = "SS"; /** * VoIP Metrics Report. */ ExtendedReportType[ExtendedReportType["VM"] = 7] = "VM"; /** * ECN Summary Report. */ ExtendedReportType[ExtendedReportType["ECN"] = 13] = "ECN"; })(ExtendedReportType || (exports.ExtendedReportType = ExtendedReportType = {})); /** * Get the RTCP packet type. * * @hidden */ function getExtendedReportType(view) { return view.getUint8(0); } /** * Read the report length value of an Extended Report and compute its size in * bytes (including first octet). * * @hidden */ function getExtendedReportLength(view) { // As per RFC 3611, this is the length of this Extended Report in 32-bit words // minus one, including the header and any padding. const length = view.getUint16(2); const byteLength = (length + 1) * 4; return byteLength; } /** * Writes given length (in bytes) in the report length field of an Extended * Report. * * @hidden */ function setExtendedReportLength(view, byteLength) { // Report byte length must be multiple of 4. if (byteLength % 4 !== 0) { throw new RangeError(`Extended Report byte length must be multiple of 4 but given byte length is ${byteLength} bytes`); } const length = byteLength / 4 - 1; view.setUint16(2, length); } /** * Parent class of all {@link XrPacket} Extended Reports. * * ```text * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | BT | type-specific | block length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * : type-specific block contents : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * ``` * * @category RTCP Extended Reports * * @see * - [RFC 3611 section 3](https://datatracker.ietf.org/doc/html/rfc3611#section-3) */ class ExtendedReport extends Serializable_1.Serializable { #reportType; constructor(reportType, view) { super(view); this.#reportType = reportType; if (this.view) { if (this.view.byteLength < exports.COMMON_HEADER_LENGTH) { throw new TypeError('too small buffer'); } // Extended Report byte length must be multiple of 4. else if (this.view.byteLength % 4 !== 0) { throw new RangeError(`Extended Report byte length must be multiple of 4 but given buffer view is ${this.view.byteLength} bytes`); } else if (getExtendedReportType(this.view) !== reportType) { throw new TypeError(`not a ${reportTypeToString(reportType)} Extended Report`); } else if (getExtendedReportLength(this.view) !== this.view.byteLength) { throw new RangeError(`length in the RTCP header (${getExtendedReportLength(this.view)} bytes) does not match view length (${this.view.byteLength} bytes)`); } } } /** * Base Extended Report dump. * * @remarks * - Read the info dump type of each Extended Report instead. */ dump() { return { ...super.dump(), reportType: this.getReportType(), }; } /** * Get the Extended Report type. */ getReportType() { return this.view.getUint8(0); } writeCommonHeader() { this.setReportType(this.#reportType); // Update the report length field in the report header. setExtendedReportLength(this.view, this.view.byteLength); } /** * Serialize base RTCP packet into a new buffer. */ serializeBase(buffer, byteOffset) { const bufferData = this.getSerializationBuffer(buffer, byteOffset); // Create new DataView with new buffer. const view = new DataView(bufferData.buffer, bufferData.byteOffset, bufferData.byteLength); const uint8Array = new Uint8Array(view.buffer, view.byteOffset, view.byteLength); // Copy the common header into the new buffer. uint8Array.set(new Uint8Array(this.view.buffer, this.view.byteOffset, exports.COMMON_HEADER_LENGTH), 0); // Update the report length field in the report header. setExtendedReportLength(view, view.byteLength); return view; } /** * Set the Extended Report type. * * @privateRemarks * - This method is not public since users should not manipulate this field * directly. */ setReportType(reportType) { this.view.setUint8(0, reportType); } } exports.ExtendedReport = ExtendedReport; function reportTypeToString(reportType) { switch (reportType) { case ExtendedReportType.LRLE: { return 'Loss RLE'; } case ExtendedReportType.DRLE: { return 'Duplicate RLE'; } case ExtendedReportType.PRT: { return 'Packet Receipt Times'; } case ExtendedReportType.RRT: { return 'Receiver Reference Time'; } case ExtendedReportType.DLRR: { return 'DLRR'; } case ExtendedReportType.SS: { return 'Statistics Summary'; } case ExtendedReportType.VM: { return 'VoIP Metrics'; } case ExtendedReportType.ECN: { return 'ECN Summary'; } default: { (0, helpers_1.assertUnreachable)(reportType); } } }