-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
142 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
# Summary | ||
|
||
Add Simulcast support to WebRTC output. | ||
|
||
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 | ||
ingest already understands this. These layers can be different resolutions, bitrates and even codecs. | ||
|
||
# Motivation | ||
|
||
The sucess/demand for this feature has already been demonstrated with [Twitch's Multiple Encodes](https://help.twitch.tv/s/article/multiple-encodes). | ||
These are my personal reasons I am working on this. | ||
|
||
* **Low Latency** - Transcodes add latency. WebRTC is chosen by OBS users because they want an interactive streams, transcodes break that. | ||
|
||
* **Cheaper** - Running a streaming service is expensive. This would allow more streaming services to exist and for more self hosting. | ||
|
||
* **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. | ||
|
||
* **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. | ||
|
||
* **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. | ||
|
||
# Design | ||
|
||
## Provide a `QSpinBox` with description to configure Simulcast Layers | ||
|
||
When users select `WHIP` for their service a description will appear below `Ignore streaming service setting recommendiations`. | ||
|
||
This QSBinBox will say `Simulcast Layers`. It will provide a description of what Simulcast is. This value will be 1 by default. | ||
This value can be 1 to 4. | ||
|
||
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 | ||
derived from their current encoding settings. These settings are not editable, but it allows the user to know explicitly what is happening. | ||
|
||
``` | ||
If user selects `Simulcast Layers: 1` | ||
* 1920x1080 5000Kbps | ||
``` | ||
|
||
``` | ||
If user selects `Simulcast Layers: 2` | ||
* 1920x1080 5000Kbps | ||
* 1440x810 3750Kbps (75%) | ||
``` | ||
|
||
``` | ||
If user selects `Simulcast Layers: 3` | ||
* 1920x1080 5000Kbps | ||
* 1440x810 3750Kbps (75%) | ||
* 960x540 2500Kbps (50%) | ||
``` | ||
|
||
``` | ||
If user selects `Simulcast Layers: 4` | ||
* 1920x1080 5000Kbps | ||
* 1440x810 3750Kbps (75%) | ||
* 960x540 2500Kbps (50%) | ||
* 480x270 1250Kbps (25%) | ||
``` | ||
|
||
|
||
## Create multiple encoders with the requested settings. | ||
|
||
A new member will be added to the `BasicOutputHandler` class. This new member `std::vector<OBSEncoder> simulcastEncoders` will contain | ||
the encoders. | ||
|
||
`BasicOutputHandler` will query `SimulcastLayers`. If greater then 0 it will loop and create the encoders. | ||
|
||
## Configure PeerConnection in `obs_output_info.start` | ||
|
||
`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. | ||
|
||
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. | ||
|
||
The server may respond with an error that 'Simulcast Configuration was not accepted'. The user can then modify | ||
how many layers they send and try again. Services can configure this ahead of time in OBS. | ||
|
||
# Proposed UX | ||
|
||
## Stream Page | ||
|
||
![Service Example](./0055-webrtc-simulcast/service-page.png) | ||
|
||
## Simple Output Mode | ||
|
||
No changes will be made. | ||
|
||
## Advanced Output Mode | ||
|
||
No changes will be made. | ||
|
||
# Alternatives | ||
|
||
## Allow users to configure Bitrate/Resolution manually | ||
|
||
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. | ||
|
||
## Extend WHIP Protocol to enable 'Server Driven Configuration' | ||
|
||
If WHIP is extended it breaks compatibility with the existing 13 years of WebRTC servers. This isn't impossible, but improbable that | ||
this would make it through the IETF with support. It will also require me updating all other clients (GStreamer, FFmpeg, Larix, Pion...) | ||
|
||
## Configuration driven by enviroment | ||
|
||
WebRTC clients today configure the amount of layers by observing the enviroment. They measure CPU Load/Network usage and enable layers dynamically. This | ||
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 | ||
your desktop you can accomodate more. | ||
|
||
This could be possible in the future, but requires a lot more work. | ||
|
||
# Drawbacks | ||
|
||
## Additional Complexity | ||
|
||
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. | ||
|
||
## More Compute/Network Usage | ||
|
||
Simulcast will require extra compute and network. If users encounter hardware/network overusage they will need to reduce bitrate/resolution. | ||
|
||
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 | ||
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. | ||
|
||
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 | ||
more fine performance information if that helps. | ||
|
||
# Additional Information | ||
|
||
How these layers are played is entirely controlled by the server operator. | ||
|
||
With Broadcast Box I provide a drop down so users can explicitly choose the layer they want to watch. | ||
|
||
![Broadcast Box](./0055-webrtc-simulcast/broadcast-box.png) | ||
|
||
A better implementation would be to dynamically measure the users internet and deliver them the best rendition their internet can support. | ||
|
||
Implementation: | ||
* [PR](https://github.com/obsproject/obs-studio/pull/9165) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.