Skip to content

Commit 68e7d44

Browse files
committed
Add RFC: WebRTC Simulcast
1 parent da063de commit 68e7d44

File tree

3 files changed

+146
-0
lines changed

3 files changed

+146
-0
lines changed

text/0055-webrtc-simulcast.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Summary
2+
3+
Add Simulcast support to WebRTC output.
4+
5+
Simulcast is a WebRTC protocol feature that allows a uploader to send multiple encodes of one track. This is built into the protocol so every WebRTC
6+
ingest already understands this. These layers can be different resolutions, bitrates and even codecs.
7+
8+
# Motivation
9+
10+
The sucess/demand for this feature has already been demonstrated with [Twitch's Multiple Encodes](https://help.twitch.tv/s/article/multiple-encodes).
11+
These are my personal reasons I am working on this.
12+
13+
* **Low Latency** - Transcodes add latency. WebRTC is chosen by OBS users because they want an interactive streams, transcodes break that.
14+
15+
* **Cheaper** - Running a streaming service is expensive. This would allow more streaming services to exist and for more self hosting.
16+
17+
* **Prevent Tampering/Ad Insertion** - WebRTC provides APIs for E2E Encryption. This means a user can upload Simulcast and share the keys viewers. Services can't modify the media anymore.
18+
19+
* **Better Quality** - 'Free Transcodes' is a race to the bottom. Streaming sites do the cheapest/lowest quality possible (to save money). Simulcast gives control to the user.
20+
21+
* **P2P Streaming** - Simulcast + E2E would enable P2P. You can have a mesh of viewers that distribute media to each other. Since things are E2E Encrypted you can detect tampering.
22+
23+
# Design
24+
25+
## Provide a `QSpinBox` with description to configure Simulcast Layers
26+
27+
When users select `WHIP` for their service a description will appear below `Ignore streaming service setting recommendiations`.
28+
29+
This QSBinBox will say `Simulcast Layers`. It will provide a description of what Simulcast is. This value will be 1 by default.
30+
This value can be 1 to 4.
31+
32+
As they increase the number box it will show the details of what the encodes that will be generated. The encodes settings will be ratios
33+
derived from their current encoding settings. These settings are not editable, but it allows the user to know explicitly what is happening.
34+
35+
```
36+
If user selects `Simulcast Layers: 1`
37+
38+
* 1920x1080 5000Kbps
39+
```
40+
41+
```
42+
If user selects `Simulcast Layers: 2`
43+
44+
* 1920x1080 5000Kbps
45+
* 1440x810 3750Kbps (75%)
46+
```
47+
48+
```
49+
If user selects `Simulcast Layers: 3`
50+
51+
* 1920x1080 5000Kbps
52+
* 1440x810 3750Kbps (75%)
53+
* 960x540 2500Kbps (50%)
54+
```
55+
56+
```
57+
If user selects `Simulcast Layers: 4`
58+
59+
* 1920x1080 5000Kbps
60+
* 1440x810 3750Kbps (75%)
61+
* 960x540 2500Kbps (50%)
62+
* 480x270 1250Kbps (25%)
63+
```
64+
65+
66+
## Create multiple encoders with the requested settings.
67+
68+
A new member will be added to the `BasicOutputHandler` class. This new member `std::vector<OBSEncoder> simulcastEncoders` will contain
69+
the encoders.
70+
71+
`BasicOutputHandler` will query `SimulcastLayers`. If greater then 0 it will loop and create the encoders.
72+
73+
## Configure PeerConnection in `obs_output_info.start`
74+
75+
`WHIPOutput::Start` will use `obs_output_get_video_encoder2` to query how many encoders exist. It will create a WebRTC offer with the requested details.
76+
77+
This offer contains the number of layers and the bitrate/resolution of them. The server can process this and decide to accept it or reject.
78+
79+
The server may respond with an error that 'Simulcast Configuration was not accepted'. The user can then modify
80+
how many layers they send and try again. Services can configure this ahead of time in OBS.
81+
82+
# Proposed UX
83+
84+
## Stream Page
85+
86+
![Service Example](./0055-webrtc-simulcast/service-page.png)
87+
88+
## Simple Output Mode
89+
90+
No changes will be made.
91+
92+
## Advanced Output Mode
93+
94+
No changes will be made.
95+
96+
# Alternatives
97+
98+
## Allow users to configure Bitrate/Resolution manually
99+
100+
This would require a large amount of UI work. The consensus was this would be frustrating for users. Nothing stops this from being done in the future though.
101+
102+
## Extend WHIP Protocol to enable 'Server Driven Configuration'
103+
104+
WHIP is an existing protocol with many users of Simulcast already. Something that does 'Server Driven Configuration' could be added to the protocol, but
105+
it would have to be done in a way that doesn't break existing clients. The value/advantage of WHIP is that it maintains compatability with 13 years of WebRTC servers and clients.
106+
107+
This is something we could take to the IETF. I don't anticipate much support since clients already have implemented 'Configuration driven by enviroment' (See point below)
108+
109+
One possibility is `GetClientConfiguration` is opt-in and driven via `services.json`.
110+
111+
## Configuration driven by enviroment
112+
113+
WebRTC clients today configure the amount of layers by observing the enviroment. They measure CPU Load/Network usage and enable layers dynamically. This
114+
is really powerful since the use cases for OBS are so diverse. If someone is streaming a demanding game they will want less layers. If you are just streaming
115+
your desktop you can accomodate more.
116+
117+
This could be possible in the future, but requires a lot more work.
118+
119+
# Drawbacks
120+
121+
## Additional Complexity
122+
123+
Simulcast will add additional code to the OBS code base. If this feature is unused it would be extra burden on the project for no value.
124+
125+
## More Compute/Network Usage
126+
127+
Simulcast will require extra compute and network. If users encounter hardware/network overusage they will need to reduce bitrate/resolution.
128+
129+
In the future I would like to write a dynamic simulcast feature. The WebRTC protocol allows layers to be disabled/enabled at anytime. We could detect network
130+
overusage and disable layers to ensure the streamer has the best experience possible. We would then re-enable them when the network and/or hardware recovers.
131+
132+
I develop and use OBS on a T420 (a laptop from 2011). When streaming using WebRTC and using x264 I see ~6% CPU usage in OBS. With Simulcast enabled I see ~8%. I can gather
133+
more fine performance information if that helps.
134+
135+
# Additional Information
136+
137+
How these layers are played is entirely controlled by the server operator.
138+
139+
With Broadcast Box I provide a drop down so users can explicitly choose the layer they want to watch.
140+
141+
![Broadcast Box](./0055-webrtc-simulcast/broadcast-box.png)
142+
143+
A better implementation would be to dynamically measure the users internet and deliver them the best rendition their internet can support.
144+
145+
Implementation:
146+
* [PR](https://github.com/obsproject/obs-studio/pull/9165)
1.18 MB
Loading
56.6 KB
Loading

0 commit comments

Comments
 (0)