mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-12-02 16:26:34 +00:00
8c6ff24052
Naive heuristic lifted from an earlier proof of concept, augmented with logic from https://datatracker.ietf.org/doc/html/draft-ietf-rmcat-gcc-02#section-5.5 A property is exposed to disable congestion control for testing purposes, it can be extended in the future to allow selecting a different congestion control scheme. + Update the documentation
183 lines
6 KiB
Markdown
183 lines
6 KiB
Markdown
# webrtcsink
|
|
|
|
All-batteries included GStreamer WebRTC producer, that tries its best to do The Right Thing™.
|
|
|
|
## Use case
|
|
|
|
The [webrtcbin] element in GStreamer is extremely flexible and powerful, but using
|
|
it can be a difficult exercise. When all you want to do is serve a fixed set of streams
|
|
to any number of consumers, `webrtcsink` (which wraps `webrtcbin` internally) can be a
|
|
useful alternative.
|
|
|
|
[webrtcbin]: https://gstreamer.freedesktop.org/documentation/webrtc/index.html
|
|
|
|
## Features
|
|
|
|
`webrtcsink` implements the following features:
|
|
|
|
* Built-in signaller: when using the default signalling server (provided as a python
|
|
script [here](signalling/simple-server.py)), this element will perform signalling without
|
|
requiring application interaction. This makes it usable directly from `gst-launch`.
|
|
|
|
* Application-provided signalling: `webrtcsink` can be instantiated by an application
|
|
with a custom signaller. That signaller must be a GObject, and must implement the
|
|
`Signallable` interface as defined [here](plugins/src/webrtcsink/mod.rs). The
|
|
[default signaller](plugins/src/signaller/mod.rs) can be used as an example.
|
|
|
|
* Sandboxed consumers: when a consumer is added, its encoder / payloader / webrtcbin
|
|
elements run in a separately managed pipeline. This provides a certain level of
|
|
sandboxing, as opposed to having those elements running inside the element itself.
|
|
|
|
It is important to note that at this moment, encoding is not shared between consumers.
|
|
While this is not on the roadmap at the moment, nothing in the design prevents
|
|
implementing this optimization.
|
|
|
|
* Congestion control: the element levarages transport-wide congestion control
|
|
feedback messages in order to adapt the bitrate of individual consumers' video
|
|
encoders to the available bandwidth.
|
|
|
|
* Configuration: the level of user control over the element is at the moment quite
|
|
narrow, as the only interface exposed is control over proposed codecs, as well
|
|
as their order of priority, and disabling congestion control. Consult `gst-inspect=1.0`
|
|
for more information.
|
|
|
|
More features are on the roadmap, focusing on mechanisms for mitigating packet
|
|
loss.
|
|
|
|
It is important to note that full control over the individual elements used by
|
|
`webrtcsink` is *not* on the roadmap, as it will act as a black box in that respect,
|
|
for example `webrtcsink` wants to reserve control over the bitrate for congestion
|
|
control.
|
|
|
|
If more granular control is required, applications should use `webrtcbin` directly,
|
|
`webrtcsink` will focus on trying to just do the right thing, although it might
|
|
expose interfaces to guide and tune the heuristics it employs.
|
|
|
|
## Building
|
|
|
|
### Prerequisites
|
|
|
|
The element has only been tested for now against GStreamer master.
|
|
|
|
For testing, it is recommended to simply build GStreamer locally and run
|
|
in the uninstalled devenv.
|
|
|
|
> Make sure to install the development packages for some codec libraries
|
|
> beforehand, such as libx264, libvpx and libopusenc, exact names depend
|
|
> on your distribution.
|
|
|
|
```
|
|
git clone https://gitlab.freedesktop.org/meh/gstreamer/-/tree/webrtcsink
|
|
meson build
|
|
ninja -C build
|
|
ninja -C build devenv
|
|
```
|
|
|
|
### Compiling
|
|
|
|
``` shell
|
|
cargo build
|
|
```
|
|
|
|
## Usage
|
|
|
|
Open three terminals. In the first, run:
|
|
|
|
``` shell
|
|
cd signalling
|
|
python3 simple-server.py --addr=127.0.0.1 --disable-ssl
|
|
```
|
|
|
|
In the second, run:
|
|
|
|
``` shell
|
|
cd www
|
|
python3 -m http.server
|
|
```
|
|
|
|
In the third, run:
|
|
|
|
``` shell
|
|
export GST_PLUGIN_PATH=$PWD/target/debug:$GST_PLUGIN_PATH
|
|
gst-launch-1.0 webrtcsink name=ws videotestsrc ! ws. audiotestsrc ! ws.
|
|
```
|
|
|
|
When the pipeline above is running succesfully, open a browser and
|
|
point it to the python server:
|
|
|
|
``` shell
|
|
xdg-open http://127.0.0.1:8000
|
|
```
|
|
|
|
You should see an identifier listed in the left-hand panel, click on
|
|
it. You should see a test video stream, and hear a test tone.
|
|
|
|
## Configuration
|
|
|
|
The element itself can be configured through its properties, see
|
|
`gst-inspect-1.0 webrtcsink` for more information about that, in addition the
|
|
default signaller also exposes properties for configuring it, in
|
|
particular setting the signalling server address, those properties
|
|
can be accessed through the `gst::ChildProxy` interface, for example
|
|
with gst-launch:
|
|
|
|
``` shell
|
|
gst-launch-1.0 webrtcsink signaller::address="ws://127.0.0.1:8443" ..
|
|
```
|
|
|
|
The signaller object can not be inspected, refer to [the source code]
|
|
for the list of properties.
|
|
|
|
[the source code]: plugins/src/signaller/imp.rs
|
|
|
|
## Testing congestion control
|
|
|
|
For the purpose of testing congestion in a reproducible manner, a
|
|
[simple tool] has been used, I only used it on Linux but it is documented
|
|
as usable on MacOS too. I had to run the client browser on a separate
|
|
machine on my local network for congestion to actually be applied, I didn't
|
|
look into why that was necessary.
|
|
|
|
My testing procedure was:
|
|
|
|
* identify the server machine network interface (eg with `ifconfig` on Linux)
|
|
|
|
* identify the client machine IP address (eg with `ifconfig` on Linux)
|
|
|
|
* start the various services as explained in the Usage section (use
|
|
`GST_DEBUG=webrtcsink:7` to get detailed logs about congestion control)
|
|
|
|
* start playback in the client browser
|
|
|
|
* Run a `comcast` command on the server machine, for instance:
|
|
|
|
``` shell
|
|
/home/meh/go/bin/comcast --device=$SERVER_INTERFACE --target-bw 3000 --target-addr=$CLIENT_IP --target-port=1:65535 --target-proto=udp
|
|
```
|
|
|
|
* Observe the bitrate sharply decreasing, playback should slow down briefly
|
|
then catch back up
|
|
|
|
* Remove the bandwidth limitation, and observe the bitrate eventually increasing
|
|
back to a maximum:
|
|
|
|
``` shell
|
|
/home/meh/go/bin/comcast --device=$SERVER_INTERFACE --stop
|
|
```
|
|
|
|
For comparison, the congestion control property can be set to disabled on
|
|
webrtcsink, then the above procedure applied again, the expected result is
|
|
for playback to simply crawl down to a halt until the bandwidth limitation
|
|
is lifted:
|
|
|
|
``` shell
|
|
gst-launch-1.0 webrtcsink congestion-control=disabled
|
|
```
|
|
|
|
[simple tool]: https://github.com/tylertreat/comcast
|
|
|
|
## License
|
|
|
|
All code in this repository is licensed under the [MIT license].
|
|
|
|
[MIT license]: https://opensource.org/licenses/MIT
|