Disclaimer: The following research took place at Around (Teamport Inc.)

Introduction

This is repost of the work that was done during Eugene’s investigation of issues in BWE in Mediasoup. Mediasoup has adopted libwebrtc congestion control algorithm by hard-forking libwebrtc congestion control module and adapting it to mediasoup project structure. Hardfork was created from:

This report is basically a compilation of my dairy notes during work on this project, that are reflected here : https://linear.app/aroundco/issue/MS-50/further-work-on-bwe-on-api-media-mediasoup

Scope

During the investigation the main scope of work was around send side bandwidth estimation. In other words estimation of bandwidth in direction from mediasoup towards consumers. The work that was done can be divided in multiple categories:

Methodology

After many different attempts to find best replicable scenario for test, we identified that we require an external server in the “wild” internet and create a case of congested uplink in direction from mediasoup towards client receiver. In order to achieve that we configured mediasoup-demo on server hosted by Hetzner in Finland. And we were connecting two clients to it. One that was producing traffic and the other that was consuming with N consumers replicas. N has to be picked dynamically depending on network conditions of the user that performs analysis. In my case it was usually 20-25 consumer replicas. So in the end I was connecting two clients with respective URL params:

https://${SERVER_ADDRESS}/?roomId=test&produce=false&consumerReplicas=24 - The page that is going to consume all the replicas

https://${SERVER_ADDRESS}/?roomId=test&consume=false - The page that is producing sigle 720p simulcast VP8 stream.

In order to trace stats and analyse behaviour of CC module we were needed extended visibility of CC module internal stats. As a first attempt we were sampling mediasoup transport stats, but realised that this is not enough. In order to sample stats more precisely and understand CC module better we added instrumentation into mediasoup for CC module. Which in the end resulted in the next structure emitted (transport trace event with type “bweStats”) on every CC module state change:

https://github.com/sarumjanuch/mediasoup/blob/bwe_backport/node/src/Transport.ts#L64

export type TransportTraceEventBweStatsInfo = {
	estimatedBitrate: number;
	delay: { 
		slope: number;
		rSquared: number;
		threshold: number;
		rtt: number;
		rateControlState: number;
		delayDetectorState: number;
	};
	probe: {
		estimatedBitrate: number;
	};
	loss: {
		inherent: number;
		avg: number;
		estimatedBitrate: number;
		sendingRate: number;
	};
	alr: boolean;
	ackBitrate: number;
	desiredBitrate: number;
	effectiveDesiredBitrate: number;
	minBitrate: number;
	maxBitrate: number;
	startBitrate: number;
	maxPaddingBitrate: number;
	sendingRate: number;
};

Using this stats I have modified mediasoup-demo to write a CSV file with this stats for each transport. Changes can be seen here: https://github.com/sarumjanuch/mediasoup-demo/commit/78a498f7b8e74435723f354797d46f34918e42d4 As for visualisation @Lukasz Tracewski did setup a Jupiter Notebook on server, that we were using to represent results in a visual form.

All the work done in mediasoup so far is reflected in this branch: https://github.com/sarumjanuch/mediasoup/tree/bwe_backport