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 1 commit
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
12 changes: 10 additions & 2 deletions Frontend/library/src/WebRtcPlayer/WebRtcPlayerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1551,7 +1551,11 @@ export class WebRtcPlayerController {
'Sending the offer to the Server',
6
);
this.webSocketController.sendWebRtcOffer(offer);

const minBitrate = 1000 * this.config.getNumericSettingValue(NumericParameters.WebRTCMinBitrate);
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider naming as minBitrateBps, although technicaly bitrate implies bps, the word bitrate is also used for kilobits and megabits quite often so I think the extra clarity here helps.

const maxBitrate = 1000 * this.config.getNumericSettingValue(NumericParameters.WebRTCMaxBitrate);

this.webSocketController.sendWebRtcOffer(offer, minBitrate, maxBitrate);
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than appending more parameters here (as I am certain we will want more in the future) can we instead pass an offerOptions, offerParams, offerConfig, or something like this as the additional parameter to this function/

}

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

const minBitrate = 1000 * this.config.getNumericSettingValue(NumericParameters.WebRTCMinBitrate);
const maxBitrate = 1000 * this.config.getNumericSettingValue(NumericParameters.WebRTCMaxBitrate);

this.webSocketController.sendWebRtcAnswer(answer, minBitrate, maxBitrate);
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above about an options param.


if (this.isUsingSFU) {
this.webSocketController.sendWebRtcDatachannelRequest();
Expand Down
39 changes: 35 additions & 4 deletions Frontend/library/src/WebSockets/MessageSend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,26 @@ 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.
* 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 @@ -88,39 +97,61 @@ export class MessagePong extends MessageSend {
*/
export class MessageWebRTCOffer extends MessageSend {
sdp: string;
minBitrate: number;
maxBitrate: number;

/**
* @param offer - Generated Web RTC Offer
*/
constructor(offer?: RTCSessionDescriptionInit) {
constructor(offer: RTCSessionDescriptionInit, minBitrate: number, maxBitrate: number) {
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 = minBitrate;
this.maxBitrate = maxBitrate;
}
}

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

/**
* 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, minBitrate: number, maxBitrate: number) {
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 = minBitrate;
this.maxBitrate = maxBitrate;
}
}

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, minBitrate: number, maxBitrate: number) {
const payload = new MessageSend.MessageWebRTCOffer(offer, minBitrate, maxBitrate);
this.webSocket.send(payload.payload());
}

sendWebRtcAnswer(answer: RTCSessionDescriptionInit) {
const payload = new MessageSend.MessageWebRTCAnswer(answer);
sendWebRtcAnswer(answer: RTCSessionDescriptionInit, minBitrate: number, maxBitrate: number) {
const payload = new MessageSend.MessageWebRTCAnswer(answer, minBitrate, maxBitrate);
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