Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Bitrate negotiation on stream startup #425

Merged
merged 4 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Frontend/library/src/Config/SettingNumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class SettingNumber<
if (!useUrlParams || !urlParams.has(this.id)) {
this.number = defaultNumber;
} else {
const parsedValue = Number.parseInt(urlParams.get(this.id));
const parsedValue = Number.parseFloat(urlParams.get(this.id));
this.number = Number.isNaN(parsedValue)
? defaultNumber
: parsedValue;
Expand Down
14 changes: 7 additions & 7 deletions Frontend/library/src/PixelStreaming/PixelStreaming.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,36 +571,36 @@ export class PixelStreaming {
NumericParameters.MinQP,
// If a setting is set in the URL, make sure we respect that value as opposed to what the application sends us
(useUrlParams && urlParams.has(NumericParameters.MinQP))
? Number.parseInt(urlParams.get(NumericParameters.MinQP))
? Number.parseFloat(urlParams.get(NumericParameters.MinQP))
: settings.EncoderSettings.MinQP
);


this.config.setNumericSetting(
NumericParameters.MaxQP,
(useUrlParams && urlParams.has(NumericParameters.MaxQP))
? Number.parseInt(urlParams.get(NumericParameters.MaxQP))
? Number.parseFloat(urlParams.get(NumericParameters.MaxQP))
: settings.EncoderSettings.MaxQP
);
}
if (settings.WebRTCSettings) {
this.config.setNumericSetting(
NumericParameters.WebRTCMinBitrate,
(useUrlParams && urlParams.has(NumericParameters.WebRTCMinBitrate))
? Number.parseInt(urlParams.get(NumericParameters.WebRTCMinBitrate))
: settings.WebRTCSettings.MinBitrate / 1000 /* bps to kbps */
? Number.parseFloat(urlParams.get(NumericParameters.WebRTCMinBitrate))
: (settings.WebRTCSettings.MinBitrate / 1000) /* bps to kbps */
);
this.config.setNumericSetting(
NumericParameters.WebRTCMaxBitrate,
(useUrlParams && urlParams.has(NumericParameters.WebRTCMaxBitrate))
? Number.parseInt(urlParams.get(NumericParameters.WebRTCMaxBitrate))
: settings.WebRTCSettings.MaxBitrate / 1000 /* bps to kbps */
? Number.parseFloat(urlParams.get(NumericParameters.WebRTCMaxBitrate))
: (settings.WebRTCSettings.MaxBitrate / 1000) /* bps to kbps */

);
this.config.setNumericSetting(
NumericParameters.WebRTCFPS,
(useUrlParams && urlParams.has(NumericParameters.WebRTCFPS))
? Number.parseInt(urlParams.get(NumericParameters.WebRTCFPS))
? Number.parseFloat(urlParams.get(NumericParameters.WebRTCFPS))
: settings.WebRTCSettings.FPS
);
}
Expand Down
17 changes: 15 additions & 2 deletions Frontend/library/src/WebRtcPlayer/WebRtcPlayerController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright Epic Games, Inc. All Rights Reserved.

import { WebSocketController } from '../WebSockets/WebSocketController';
import { ExtraOfferParameters, ExtraAnswerParameters } from '../WebSockets/MessageSend';
import { StreamController } from '../VideoPlayer/StreamController';
import {
MessageAnswer,
Expand Down Expand Up @@ -1551,7 +1552,13 @@ export class WebRtcPlayerController {
'Sending the offer to the Server',
6
);
this.webSocketController.sendWebRtcOffer(offer);

const extraParams: ExtraOfferParameters = {
minBitrateBps: 1000 * this.config.getNumericSettingValue(NumericParameters.WebRTCMinBitrate),
maxBitrateBps: 1000 * this.config.getNumericSettingValue(NumericParameters.WebRTCMaxBitrate)
};

this.webSocketController.sendWebRtcOffer(offer, extraParams);
}

/**
Expand All @@ -1564,7 +1571,13 @@ export class WebRtcPlayerController {
'Sending the answer to the Server',
6
);
this.webSocketController.sendWebRtcAnswer(answer);

const extraParams: ExtraAnswerParameters = {
minBitrateBps: 1000 * this.config.getNumericSettingValue(NumericParameters.WebRTCMinBitrate),
maxBitrateBps: 1000 * this.config.getNumericSettingValue(NumericParameters.WebRTCMaxBitrate)
};

this.webSocketController.sendWebRtcAnswer(answer, extraParams);

if (this.isUsingSFU) {
this.webSocketController.sendWebRtcDatachannelRequest();
Expand Down
54 changes: 50 additions & 4 deletions Frontend/library/src/WebSockets/MessageSend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,31 @@ export class MessageSend implements Send {
type: string;
peerConnectionOptions: object;

/**
* A filter for controlling what parameters to actually send.
* Good for excluding default values or hidden internals.
* Example for including everything but zero bitrate fields...
* sendFilter(key: string, value: any) {
* if ((key == "minBitrate" || key == "maxBitrate") && value <= 0) return undefined;
* return value;
* }
* Return undefined to exclude the property completely.
*/
sendFilter(key: string, value: any) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Can comment have an example of how it should be used.

return value;
}

/**
* Turns the wrapper into a JSON String
* @returns - JSON String of the Message to send
*/
payload() {
Logger.Log(
Logger.GetStackTrace(),
'Sending => \n' + JSON.stringify(this, undefined, 4),
'Sending => \n' + JSON.stringify(this, this.sendFilter, 4),
6
);
return JSON.stringify(this);
return JSON.stringify(this, this.sendFilter);
}
}

Expand Down Expand Up @@ -83,44 +97,76 @@ export class MessagePong extends MessageSend {
}
}

export type ExtraOfferParameters = {
minBitrateBps: number;
maxBitrateBps: number;
}

/**
* Web RTC Offer message wrapper
*/
export class MessageWebRTCOffer extends MessageSend {
sdp: string;
minBitrate: number;
maxBitrate: number;

/**
* @param offer - Generated Web RTC Offer
*/
constructor(offer?: RTCSessionDescriptionInit) {
constructor(offer: RTCSessionDescriptionInit, extraParams: ExtraOfferParameters) {
super();
this.type = MessageSendTypes.OFFER;
this.minBitrate = 0;
this.maxBitrate = 0;

if (offer) {
this.type = offer.type as MessageSendTypes;
this.sdp = offer.sdp;
this.minBitrate = extraParams.minBitrateBps;
this.maxBitrate = extraParams.maxBitrateBps;
}
}

sendFilter(key: string, value: any) {
if ((key == "minBitrate" || key == "maxBitrate") && value <= 0) return undefined;
return value;
}
}

export type ExtraAnswerParameters = {
minBitrateBps: number;
maxBitrateBps: number;
}

/**
* Web RTC Answer message wrapper
*/
export class MessageWebRTCAnswer extends MessageSend {
sdp: string;
minBitrate: number;
maxBitrate: number;

/**
* @param answer - Generated Web RTC Offer
*/
constructor(answer?: RTCSessionDescriptionInit) {
constructor(answer: RTCSessionDescriptionInit, extraParams: ExtraAnswerParameters) {
super();
this.type = MessageSendTypes.ANSWER;
this.minBitrate = 0;
this.maxBitrate = 0;

if (answer) {
this.type = answer.type as MessageSendTypes;
this.sdp = answer.sdp;
this.minBitrate = extraParams.minBitrateBps;
this.maxBitrate = extraParams.maxBitrateBps;
}
}

sendFilter(key: string, value: any) {
if ((key == "minBitrate" || key == "maxBitrate") && value <= 0) return undefined;
return value;
}
}

/**
Expand Down
8 changes: 4 additions & 4 deletions Frontend/library/src/WebSockets/WebSocketController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,13 @@ export class WebSocketController {
this.webSocket.send(payload.payload());
}

sendWebRtcOffer(offer: RTCSessionDescriptionInit) {
const payload = new MessageSend.MessageWebRTCOffer(offer);
sendWebRtcOffer(offer: RTCSessionDescriptionInit, extraParams: MessageSend.ExtraOfferParameters) {
const payload = new MessageSend.MessageWebRTCOffer(offer, extraParams);
this.webSocket.send(payload.payload());
}

sendWebRtcAnswer(answer: RTCSessionDescriptionInit) {
const payload = new MessageSend.MessageWebRTCAnswer(answer);
sendWebRtcAnswer(answer: RTCSessionDescriptionInit, extraParams: MessageSend.ExtraAnswerParameters) {
const payload = new MessageSend.MessageWebRTCAnswer(answer, extraParams);
this.webSocket.send(payload.payload());
}

Expand Down
2 changes: 1 addition & 1 deletion Frontend/ui-library/src/Config/SettingUINumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class SettingUINumber<
this.spinner.onchange = (event: Event) => {
const inputElem = event.target as HTMLInputElement;

const parsedValue = Number.parseInt(inputElem.value);
const parsedValue = Number.parseFloat(inputElem.value);

if (Number.isNaN(parsedValue)) {
Logger.Warning(
Expand Down