mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
examples: webrtc: sendrecv: rust: Implement TWCC support in both directions
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3758>
This commit is contained in:
parent
6541dccaea
commit
541c637910
3 changed files with 78 additions and 3 deletions
|
@ -693,6 +693,46 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-base-sys"
|
||||
version = "0.19.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbc3c4476e1503ae245c89fbe20060c30ec6ade5f44620bcc402cbc70a3911a1"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gstreamer-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-rtp"
|
||||
version = "0.19.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2e464957d09a9abb8c3cbf818635f38113b327d9ba23b89ef11b10afb25cdfe"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"glib",
|
||||
"gstreamer",
|
||||
"gstreamer-rtp-sys",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-rtp-sys"
|
||||
version = "0.19.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e65dbc4429a8cb494907c654caa74c1630111116f9ac2d1d9bf585c144e4821d"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gstreamer-base-sys",
|
||||
"gstreamer-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-sdp"
|
||||
version = "0.19.4"
|
||||
|
@ -1590,6 +1630,7 @@ dependencies = [
|
|||
"cocoa",
|
||||
"futures",
|
||||
"gstreamer",
|
||||
"gstreamer-rtp",
|
||||
"gstreamer-sdp",
|
||||
"gstreamer-webrtc",
|
||||
"rand",
|
||||
|
|
|
@ -12,6 +12,7 @@ anyhow = "1"
|
|||
rand = "0.8"
|
||||
async-tungstenite = { version = "0.19", features = ["async-std-runtime", "async-native-tls"] }
|
||||
gst = { package = "gstreamer", version = "0.19" }
|
||||
gst-rtp = { package = "gstreamer-rtp", version = "0.19", features = ["v1_20"] }
|
||||
gst-webrtc = { package = "gstreamer-webrtc", version = "0.19" }
|
||||
gst-sdp = { package = "gstreamer-sdp", version = "0.19" }
|
||||
serde = "1"
|
||||
|
|
|
@ -18,6 +18,7 @@ use tungstenite::Message as WsMessage;
|
|||
|
||||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
use gst_rtp::prelude::*;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
|
@ -26,6 +27,8 @@ use anyhow::{anyhow, bail, Context};
|
|||
const STUN_SERVER: &str = "stun://stun.l.google.com:19302";
|
||||
const TURN_SERVER: &str = "turn://foo:bar@webrtc.nirbheek.in:3478";
|
||||
|
||||
const TWCC_URI: &str = "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01";
|
||||
|
||||
// upgrade weak reference or return
|
||||
#[macro_export]
|
||||
macro_rules! upgrade_weak {
|
||||
|
@ -149,6 +152,15 @@ impl App {
|
|||
|
||||
// Connect to on-negotiation-needed to handle sending an Offer
|
||||
if app.args.peer_id.is_some() {
|
||||
let vpay = app.pipeline.by_name("vpay").unwrap();
|
||||
let apay = app.pipeline.by_name("apay").unwrap();
|
||||
|
||||
for pay in [vpay, apay] {
|
||||
let twcc = gst_rtp::RTPHeaderExtension::create_from_uri(TWCC_URI).unwrap();
|
||||
twcc.set_id(1);
|
||||
pay.emit_by_name::<()>("add-extension", &[&twcc]);
|
||||
}
|
||||
|
||||
let app_clone = app.downgrade();
|
||||
app.webrtcbin.connect_closure(
|
||||
"on-negotiation-needed",
|
||||
|
@ -403,10 +415,25 @@ impl App {
|
|||
Err(_) => continue,
|
||||
};
|
||||
|
||||
let twcc_id = media.attributes().find_map(|attr| {
|
||||
let key = attr.key();
|
||||
let value = attr.value();
|
||||
if key != "extmap" || !value.map_or(false, |value| value.ends_with(TWCC_URI)) {
|
||||
return None;
|
||||
}
|
||||
let value = value.unwrap();
|
||||
|
||||
let id = value
|
||||
.strip_suffix(TWCC_URI)
|
||||
.and_then(|id| id.trim().parse::<u8>().ok());
|
||||
|
||||
id
|
||||
});
|
||||
|
||||
if encoding_name == "VP8" && vp8_id.is_none() {
|
||||
vp8_id = Some(pt);
|
||||
vp8_id = Some((pt, twcc_id));
|
||||
} else if encoding_name == "OPUS" && opus_id.is_none() {
|
||||
opus_id = Some(pt);
|
||||
opus_id = Some((pt, twcc_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -415,8 +442,14 @@ impl App {
|
|||
let apay = self.pipeline.by_name("apay").unwrap();
|
||||
let vpay = self.pipeline.by_name("vpay").unwrap();
|
||||
|
||||
for (pay, pt) in [(apay, opus_id), (vpay, vp8_id)] {
|
||||
for (pay, (pt, twcc_id)) in [(apay, opus_id), (vpay, vp8_id)] {
|
||||
pay.set_property("pt", pt as u32);
|
||||
|
||||
if let Some(twcc_id) = twcc_id {
|
||||
let twcc = gst_rtp::RTPHeaderExtension::create_from_uri(TWCC_URI).unwrap();
|
||||
twcc.set_id(twcc_id as u32);
|
||||
pay.emit_by_name::<()>("add-extension", &[&twcc]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gst::element_error!(
|
||||
|
|
Loading…
Reference in a new issue