UNPKG

rtp.js

Version:

RTP stack for Node.js and browser written in TypeScript

199 lines (198 loc) 6.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EcnPacket = void 0; const RtcpPacket_1 = require("./RtcpPacket"); const FeedbackPacket_1 = require("./FeedbackPacket"); const ECN_PACKET_LENGTH = FeedbackPacket_1.FIXED_HEADER_LENGTH + 20; /** * RTCP ECN packet (RTCP Transport Layer Feedback). * * ```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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |V=2|P| FMT=8 | PT=RTPFB=205 | length=7 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | SSRC of packet sender | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | SSRC of media source | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Extended Highest Sequence Number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ECT (0) Counter | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ECT (1) Counter | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ECN-CE Counter | not-ECT Counter | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Lost Packets Counter | Duplication Counter | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * ``` * * @category RTCP * * @see * - [RFC 6679 section 5.1](https://datatracker.ietf.org/doc/html/rfc6679#section-5.1) */ class EcnPacket extends FeedbackPacket_1.FeedbackPacket { /** * @param view - If given it will be parsed. Otherwise an empty RTCP ECN * packet will be created. * * @throws * - If given `view` does not contain a valid RTCP ECN packet. */ constructor(view) { super(RtcpPacket_1.RtcpPacketType.RTPFB, FeedbackPacket_1.RtpFeedbackMessageType.ECN, view); if (!this.view) { this.view = new DataView(new ArrayBuffer(ECN_PACKET_LENGTH)); // Write version, packet type and feedback message type. this.writeFixedHeader(); return; } // Position relative to the DataView byte offset. let pos = 0; // Move to the end. pos += ECN_PACKET_LENGTH; pos += this.padding; // Ensure that view length and parsed length match. if (pos !== this.view.byteLength) { throw new RangeError(`parsed length (${pos} bytes) does not match view length (${this.view.byteLength} bytes)`); } } /** * Dump RTCP ECN packet info. */ dump() { return { ...super.dump(), extendedHighestSequenceNumber: this.getExtendedHighestSequenceNumber(), ect0Counter: this.getEct0Counter(), ect1Counter: this.getEct1Counter(), ecnCeCounter: this.getEcnCeCounter(), nonEctCounter: this.getNonEctCounter(), lostPacketsCounter: this.getLostPacketsCounter(), duplicationCounter: this.getDuplicationCounter(), }; } /** * @inheritDoc */ getByteLength() { return ECN_PACKET_LENGTH + this.padding; } /** * @inheritDoc */ serialize(buffer, byteOffset) { const view = this.serializeBase(buffer, byteOffset); const uint8Array = new Uint8Array(view.buffer, view.byteOffset, view.byteLength); // Position relative to the DataView byte offset. let pos = 0; // Move to FCI. pos += FeedbackPacket_1.FIXED_HEADER_LENGTH; // Copy the entire FCI into the new buffer. uint8Array.set(new Uint8Array(this.view.buffer, this.view.byteOffset + pos, ECN_PACKET_LENGTH - FeedbackPacket_1.FIXED_HEADER_LENGTH), pos); pos += ECN_PACKET_LENGTH - FeedbackPacket_1.FIXED_HEADER_LENGTH; pos += this.padding; // Assert that current position is equal than new buffer length. if (pos !== view.byteLength) { throw new RangeError(`filled length (${pos} bytes) is different than the available buffer size (${view.byteLength} bytes)`); } // Update DataView. this.view = view; this.setSerializationNeeded(false); } /** * @inheritDoc */ clone(buffer, byteOffset, serializationBuffer, serializationByteOffset) { const view = this.cloneInternal(buffer, byteOffset, serializationBuffer, serializationByteOffset); return new EcnPacket(view); } /** * Get Extended Highest Sequence Number. */ getExtendedHighestSequenceNumber() { return this.view.getUint32(12); } /** * Set Extended Highest Sequence Number. */ setExtendedHighestSequenceNumber(sequenceNumber) { this.view.setUint32(12, sequenceNumber); } /** * Get ECT (0) Counter. */ getEct0Counter() { return this.view.getUint32(16); } /** * Set ECT (0) Counter. */ setEct0Counter(counter) { this.view.setUint32(16, counter); } /** * Get ECT (1) Counter. */ getEct1Counter() { return this.view.getUint32(20); } /** * Set ECT (1) Counter. */ setEct1Counter(counter) { this.view.setUint32(20, counter); } /** * Get ECN-CE Counter. */ getEcnCeCounter() { return this.view.getUint16(24); } /** * Set ECN-CE Counter. */ setEcnCeCounter(counter) { this.view.setUint16(24, counter); } /** * Get not-ECT Counter. */ getNonEctCounter() { return this.view.getUint16(26); } /** * Set not-ECT Counter. */ setNonEctCounter(counter) { this.view.setUint16(26, counter); } /** * Get Lost Packets Counter. */ getLostPacketsCounter() { return this.view.getUint16(28); } /** * Set Lost Packets Counter. */ setLostPacketsCounter(counter) { this.view.setUint16(28, counter); } /** * Get Duplication Counter. */ getDuplicationCounter() { return this.view.getUint16(30); } /** * Set Duplication Counter. */ setDuplicationCounter(counter) { this.view.setUint16(30, counter); } } exports.EcnPacket = EcnPacket;