From 98e193ef63f755463fe633abd9818e00e1de922b Mon Sep 17 00:00:00 2001 From: Steven Vancoillie Date: Sat, 7 Dec 2024 11:38:29 +0100 Subject: [PATCH] chore(streams): rtp-parser Buffer -> Uint8Array --- streams/src/components/aacdepay/parser.ts | 5 +- streams/src/utils/bytes.ts | 18 ++++++ streams/src/utils/protocols/rtp.ts | 67 +++++++++++------------ streams/tests/protocols-rtp.test.ts | 20 +++---- streams/tests/protocols.fixtures.ts | 10 ++-- 5 files changed, 69 insertions(+), 51 deletions(-) diff --git a/streams/src/components/aacdepay/parser.ts b/streams/src/components/aacdepay/parser.ts index d4c190e5f..e735f1d14 100644 --- a/streams/src/components/aacdepay/parser.ts +++ b/streams/src/components/aacdepay/parser.ts @@ -1,3 +1,4 @@ +import { readUInt16BE } from 'utils/bytes' import { payload, payloadType, timestamp } from '../../utils/protocols/rtp' import { ElementaryMessage, MessageType, RtpMessage } from '../message' @@ -41,12 +42,12 @@ export function parse( let headerLength = 0 if (hasHeader) { - const auHeaderLengthInBits = buffer.readUInt16BE(0) + const auHeaderLengthInBits = readUInt16BE(buffer, 0) headerLength = 2 + (auHeaderLengthInBits + (auHeaderLengthInBits % 8)) / 8 // Add padding } const packet: ElementaryMessage = { type: MessageType.ELEMENTARY, - data: buffer.slice(headerLength), + data: Buffer.from(buffer.subarray(headerLength)), payloadType: payloadType(rtp.data), timestamp: timestamp(rtp.data), ntpTimestamp: rtp.ntpTimestamp, diff --git a/streams/src/utils/bytes.ts b/streams/src/utils/bytes.ts index 6fa6d74cf..22616d488 100644 --- a/streams/src/utils/bytes.ts +++ b/streams/src/utils/bytes.ts @@ -18,3 +18,21 @@ export function decode(bytes: Uint8Array): string { const dec = new TextDecoder() return dec.decode(bytes) } + +// Extract 16-bit big-endian value at byte offset +export function readUInt16BE(bytes: Uint8Array, byteOffset: number): number { + return new DataView( + bytes.buffer, + bytes.byteOffset, + bytes.byteLength + ).getUint16(byteOffset) +} + +// Extract 32-bit big-endian value at byte offset +export function readUInt32BE(bytes: Uint8Array, byteOffset: number): number { + return new DataView( + bytes.buffer, + bytes.byteOffset, + bytes.byteLength + ).getUint32(byteOffset) +} diff --git a/streams/src/utils/protocols/rtp.ts b/streams/src/utils/protocols/rtp.ts index c028c22a8..197f44c71 100644 --- a/streams/src/utils/protocols/rtp.ts +++ b/streams/src/utils/protocols/rtp.ts @@ -1,3 +1,4 @@ +import { readUInt16BE, readUInt32BE } from 'utils/bytes' import { POS } from '../bits' // Real Time Protocol (RTP) @@ -25,63 +26,61 @@ RTP Fixed Header Fields +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -export const version = (buffer: Buffer) => { - return buffer[0] >>> 6 +export const version = (bytes: Uint8Array): number => { + return bytes[0] >>> 6 } -export const padding = (buffer: Buffer) => { - return !!(buffer[0] & POS[2]) +export const padding = (bytes: Uint8Array): boolean => { + return !!(bytes[0] & POS[2]) } -export const extension = (buffer: Buffer) => { - return !!(buffer[0] & POS[3]) +export const extension = (bytes: Uint8Array): boolean => { + return !!(bytes[0] & POS[3]) } -export const cSrcCount = (buffer: Buffer) => { - return buffer[0] & 0x0f +export const cSrcCount = (bytes: Uint8Array): number => { + return bytes[0] & 0x0f } -export const marker = (buffer: Buffer) => { - return !!(buffer[1] & POS[0]) +export const marker = (bytes: Uint8Array): boolean => { + return !!(bytes[1] & POS[0]) } -export const payloadType = (buffer: Buffer) => { - return buffer[1] & 0x7f +export const payloadType = (bytes: Uint8Array): number => { + return bytes[1] & 0x7f } -export const sequenceNumber = (buffer: Buffer) => { - return buffer.readUInt16BE(2) +export const sequenceNumber = (bytes: Uint8Array): number => { + return readUInt16BE(bytes, 2) } -export const timestamp = (buffer: Buffer) => { - return buffer.readUInt32BE(4) +export const timestamp = (bytes: Uint8Array): number => { + return readUInt32BE(bytes, 4) } -export const sSrc = (buffer: Buffer) => { - return buffer.readUInt32BE(8) +export const sSrc = (bytes: Uint8Array): number => { + return readUInt32BE(bytes, 8) } -export const cSrc = (buffer: Buffer, rank = 0) => { - return cSrcCount(buffer) > rank ? buffer.readUInt32BE(12 + rank * 4) : 0 +export const cSrc = (bytes: Uint8Array, rank = 0): number => { + return cSrcCount(bytes) > rank ? readUInt32BE(bytes, 12 + rank * 4) : 0 } -export const extHeaderLength = (buffer: Buffer) => { - return !extension(buffer) - ? 0 - : buffer.readUInt16BE(12 + cSrcCount(buffer) * 4 + 2) +export const extHeaderLength = (bytes: Uint8Array): number => { + return !extension(bytes) ? 0 : readUInt16BE(bytes, 12 + cSrcCount(bytes) * 4 + 2) } -export const extHeader = (buffer: Buffer) => { - return extHeaderLength(buffer) === 0 - ? Buffer.from([]) - : buffer.slice( - 12 + cSrcCount(buffer) * 4, - 12 + cSrcCount(buffer) * 4 + 4 + extHeaderLength(buffer) * 4 +export const extHeader = (bytes: Uint8Array): Uint8Array => { + return extHeaderLength(bytes) === 0 + ? new Uint8Array(0) + : bytes.subarray( + 12 + cSrcCount(bytes) * 4, + 12 + cSrcCount(bytes) * 4 + 4 + extHeaderLength(bytes) * 4 ) } -export const payload = (buffer: Buffer) => { - return !extension(buffer) - ? buffer.slice(12 + cSrcCount(buffer) * 4) - : buffer.slice(12 + cSrcCount(buffer) * 4 + 4 + extHeaderLength(buffer) * 4) +export const payload = (bytes: Uint8Array): Uint8Array => { + return !extension(bytes) + ? bytes.subarray(12 + cSrcCount(bytes) * 4) + : bytes.subarray(12 + cSrcCount(bytes) * 4 + 4 + extHeaderLength(bytes) * 4) } diff --git a/streams/tests/protocols-rtp.test.ts b/streams/tests/protocols-rtp.test.ts index c0ed529d7..af41fa94e 100644 --- a/streams/tests/protocols-rtp.test.ts +++ b/streams/tests/protocols-rtp.test.ts @@ -71,21 +71,21 @@ describe('Rtp parsing', (test) => { }) test('should expose the payload', () => { - assert.equal(payload(rtpBuffers[0]), Buffer.from([])) - assert.equal(payload(rtpBuffers[1]), Buffer.from([1, 2, 3])) - assert.equal(payload(rtpBuffers[2]), Buffer.from([1, 2, 3])) - assert.equal(payload(rtpBuffersWithHeaderExt[0]), Buffer.from([1, 2, 3])) - assert.equal(payload(rtpBuffersWithHeaderExt[1]), Buffer.from([1, 2, 3])) + assert.equal(payload(rtpBuffers[0]), new Uint8Array([])) + assert.equal(payload(rtpBuffers[1]), new Uint8Array([1, 2, 3])) + assert.equal(payload(rtpBuffers[2]), new Uint8Array([1, 2, 3])) + assert.equal(payload(rtpBuffersWithHeaderExt[0]), new Uint8Array([1, 2, 3])) + assert.equal(payload(rtpBuffersWithHeaderExt[1]), new Uint8Array([1, 2, 3])) }) test('should expose the extension header', () => { - assert.equal(extHeader(rtpBuffers[0]), Buffer.from([])) - assert.equal(extHeader(rtpBuffers[1]), Buffer.from([])) - assert.equal(extHeader(rtpBuffers[2]), Buffer.from([])) - assert.equal(extHeader(rtpBuffersWithHeaderExt[0]), Buffer.from([])) + assert.equal(extHeader(rtpBuffers[0]), new Uint8Array([])) + assert.equal(extHeader(rtpBuffers[1]), new Uint8Array([])) + assert.equal(extHeader(rtpBuffers[2]), new Uint8Array([])) + assert.equal(extHeader(rtpBuffersWithHeaderExt[0]), new Uint8Array([])) assert.equal( extHeader(rtpBuffersWithHeaderExt[1]), - Buffer.from([1, 2, 0, 1, 1, 2, 3, 4]) + new Uint8Array([1, 2, 0, 1, 1, 2, 3, 4]) ) }) }) diff --git a/streams/tests/protocols.fixtures.ts b/streams/tests/protocols.fixtures.ts index 389d23b01..262f1b8cb 100644 --- a/streams/tests/protocols.fixtures.ts +++ b/streams/tests/protocols.fixtures.ts @@ -1,18 +1,18 @@ /* biome-ignore format: custom formatting */ export const rtpBuffers = [ - Buffer.from([128, 96, 80, 56, 225, 39, 20, 132, 25, 190, 186, 105]), - Buffer.from([128, 224, 80, 76, 225, 39, 108, 97, 25, 190, 186, 105, 1, 2, 3]), - Buffer.from([ + new Uint8Array([128, 96, 80, 56, 225, 39, 20, 132, 25, 190, 186, 105]), + new Uint8Array([128, 224, 80, 76, 225, 39, 108, 97, 25, 190, 186, 105, 1, 2, 3]), + new Uint8Array([ 129, 224, 80, 95, 225, 40, 57, 104, 25, 190, 186, 105, 0, 0, 0, 1, 1, 2, 3, ]), ] /* biome-ignore format: custom formatting */ export const rtpBuffersWithHeaderExt = [ - Buffer.from([ + new Uint8Array([ 144, 224, 80, 76, 225, 39, 108, 97, 25, 190, 186, 105, 1, 2, 0, 0, 1, 2, 3, ]), - Buffer.from([ + new Uint8Array([ 144, 224, 80, 76, 225, 39, 108, 97, 25, 190, 186, 105, 1, 2, 0, 1, 1, 2, 3, 4, 1, 2, 3, ]),