]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
"cocoa",
"futures",
"gstreamer",
+ "gstreamer-rtp",
"gstreamer-sdp",
"gstreamer-webrtc",
"rand",
use gst::glib;
use gst::prelude::*;
+use gst_rtp::prelude::*;
use serde_derive::{Deserialize, Serialize};
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 {
// 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",
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));
}
}
}
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!(