|
| 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 | + |
| 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 | + |
| 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) |
0 commit comments