Bandwidth estimation (BWE) tuning.

Hello.

I’ve been performing some tests with simulated network disturbances to evaluate the BWE performed by the mediasoup server.

Are there any configuration parameters which can affect the aggressiveness of the probing, or other aspects of the algorithm?

I’m discovering that the upward probing is a bit more aggressive than I’d like for my use case. For example, if I limit the client download bandwidth to something like 700 kbps, it seems that the server is frequently switching between the simulcast layers, causing periodic video freezes. It seems like it is often trying to get back to HD, then hitting congestion and falling back to the lowest quality level, then repeating that cycle.

Is there any way to make the probing less aggressive?

I would like to bias the algorithm to be more stable at VGA resolution when the client download clamp is consistently limited.

I saw this post…

…which makes me think that digging into the C++ code may be required to tune BWE behavior.

Is that correct?

I noticed some open PRs and branches related to BWE tweaks, so perhaps some of that work might be related to what I’m asking about.

Thanks very much.

I should have mentioned that I’ve already tried experimenting with the following options:

initialAvailableOutgoingBitrate
minimumAvailableOutgoingBitrate
maxIncomingBitrate

I’ve also tried changing the simulcast layer configuration.

Those options alone don’t seem to influence the aggressiveness of the probing which is causing the behavior I’m seeing.

Thanks.

I’ve been playing around with the C++, and I’ve noticed that the ‘BweDowngradeConservativeMs’ constant seems to have a big impact on the behavior I’m seeing:

If I increase that value, it reduces the simulcast layer oscillations, and seems to make the upward probing less aggressive, which means the video freezes are less frequent when client download bandwidth is consistently constrained.

Would it ever make sense to expose certain parameters like this through the config file, or is this something that’s very low level, and should just be tuned in the C++ and then left alone?

I think another aspect of this issue is that when the consumer is probing upward, it seems to be jumping immediately from 320x180 up to 1280x720, and thus skipping over the 640x360 spatial layer. With 700 kbps download available, I think 640x360 is probably the sweet spot in terms of how I have the bandwidth settings configured, but perhaps I have something configured in a non-optimal way.

I’m running my tests in the mediasoup-demo app. Here are the bandwidth and simulcast settings I’m currently using. I’ve tried several different values.

initialAvailableOutgoingBitrate : 700000,
minimumAvailableOutgoingBitrate : 100000,
maxSctpMessageSize              : 262144,
maxIncomingBitrate              : 3500000
// Used for simulcast webcam video.
const WEBCAM_SIMULCAST_ENCODINGS =
[
	{ scaleResolutionDownBy: 4, maxBitrate: 700000 },
	{ scaleResolutionDownBy: 2, maxBitrate: 1000000 },
	{ scaleResolutionDownBy: 1, maxBitrate: 2500000 }
];

Thanks again.

Hi @codyherzog,

There is this branch that tries to make the BWE more resilient to abrupt BW peaks.

It would be useful having the same scenarios you’re describing tested within this branch, if that’s something you can do.

There is no magic tuning parameters to make the BWE work better. It’s just that we rely on libwebrtc source code for the BWE stuff, and it’s extremely hard to manage. So don’t look for specific variables or numbers to modify. You would improve a bit some scenarios and would make others worse.

What we have to do is getting rid of the libwebrtc code in mediasoup and implement our own BWE mechanism based on BBR or whatever: https://github.com/versatica/mediasoup/issues/344

Thanks very much, guys.

@jmillan I tried out that branch. For my particular test scenario of a constant client download limit, I haven’t noticed a difference. Perhaps that’s to be expected if the changes in that branch are about handling abrupt changes in available bandwidth.

@ibc Thanks for the good information. Sounds like it’s not worth spending too much time tinkering with it. Am I correct that code like ‘worker/src/RTC/SimulcastConsumer.cpp’ is part of mediasoup “proper”, and not part of libwebrtc? If so, then perhaps that layer of the software could be worth a bit more exploration on my part, to at least better understand the simulcast layer switching and how it relates to the bandwidth estimation.

Thanks again.

Everything under mediasoup/worker/src/ and mediasoup/worker/include/ is part of mediasoup. You can inspect SimulcastConsumer.cpp and Transport.cpp to see how the bandwidth distribution works. However the BWE is done by libwebrtc library which is included in mediasoup/worker/deps/, and that’s the problematic part rather than the mediasoup code.

I’m afraid I cannot give any guidance about what to do. As I said, once we get time enough, we’ll try to replace libwebrtc with our own BWE code.

1 Like

Understood.

Thanks very much.

Our team also are faced with this issue, is there a newer version or branch that could improve this issue?