From 0a34c2d752afc9321b7c8a96c18bc6d6849f8423 Mon Sep 17 00:00:00 2001 From: Juan Navarro Date: Tue, 22 Jun 2021 19:01:07 +0200 Subject: [PATCH] openvidu-browser: enable simulcast for SDP Offers --- .../OpenViduInternal/WebRtcPeer/WebRtcPeer.ts | 56 ++++++++++++++++++- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts b/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts index b22df6fc..204e395a 100644 --- a/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts +++ b/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts @@ -30,6 +30,49 @@ const logger: OpenViduLogger = OpenViduLogger.getInstance(); */ let platform: PlatformUtils; +/* + * Table of sender video encodings for simulcast. + * Note that this is just a polite request, but the browser is free to honor it + * or just play by its own rules. + * + * Chrome imposes some restrictions based on the size of the video, max bitrate, + * and available bandwidth. Check here for the video size table: + * https://chromium.googlesource.com/external/webrtc/+/master/media/engine/simulcast.cc#90 + * + * | Size (px) | Bitrate (kbps) | Max Layers | + * |----------:|---------------:|-----------:| + * | 1920x1080 | 5000 | 3 | + * | 1280x720 | 2500 | 3 | + * | 960x540 | 1200 | 3 | + * | 640x360 | 700 | 2 | + * | 480x270 | 450 | 2 | + * | 320x180 | 200 | 1 | + */ +const simulcastVideoEncodings: RTCRtpEncodingParameters[] = [ + { + rid: "r0", + maxBitrate: 700000, + + // TODO: Remove for final version; leave the browser decide: + // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver + // > If the scaleResolutionDownBy attribues of sendEncodings are still + // > undefined, initialize each encoding's scaleResolutionDownBy to + // > 2^(length of sendEncodings - encoding index - 1). This results in + // > smaller-to-larger resolutions where the last encoding has no scaling + // > applied to it, e.g. 4:2:1 if the length is 3. + scaleResolutionDownBy: 16, + }, + { + rid: "r1", + maxBitrate: 800000, + scaleResolutionDownBy: 8, + }, + { + rid: "r2", + maxBitrate: 900000, + scaleResolutionDownBy: 1, + }, +]; export interface WebRtcPeerConfiguration { mediaConstraints: { @@ -127,6 +170,8 @@ export class WebRtcPeer { if ("addTransceiver" in this.pc) { logger.debug("[createOffer] Method RTCPeerConnection.addTransceiver() is available; using it"); + // Spec doc: https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver + if (this.configuration.mode !== "recvonly") { // To send media, assume that all desired media tracks // have been already added by higher level code to our @@ -138,11 +183,16 @@ export class WebRtcPeer { } for (const track of this.configuration.mediaStream.getTracks()) { - this.pc.addTransceiver(track, { + const tcInit: RTCRtpTransceiverInit = { direction: this.configuration.mode, streams: [this.configuration.mediaStream], - sendEncodings: [], - }); + }; + + if (track.kind === "video") { + tcInit.sendEncodings = simulcastVideoEncodings; + } + + this.pc.addTransceiver(track, tcInit); } } else { // To just receive media, create new recvonly transceivers.