Skip to content

Commit

Permalink
Fix simulcast for firefox (#534)
Browse files Browse the repository at this point in the history
  • Loading branch information
yngrtc committed Apr 22, 2024
1 parent 0c5907d commit 98b4ec4
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 76 deletions.
3 changes: 3 additions & 0 deletions rtc-sdp/src/extmap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ pub const TRANSPORT_CC_URI: &str =
"http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01";
pub const SDES_MID_URI: &str = "urn:ietf:params:rtp-hdrext:sdes:mid";
pub const SDES_RTP_STREAM_ID_URI: &str = "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
pub const SDES_REPAIR_RTP_STREAM_ID_URI: &str =
"urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id";

pub const AUDIO_LEVEL_URI: &str = "urn:ietf:params:rtp-hdrext:ssrc-audio-level";
pub const VIDEO_ORIENTATION_URI: &str = "urn:3gpp:video-orientation";

Expand Down
2 changes: 0 additions & 2 deletions rtc/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ pub(crate) const RECEIVE_MTU: usize = 1460;
pub(crate) const SDP_ATTRIBUTE_RID: &str = "rid";
pub(crate) const SDP_ATTRIBUTE_SIMULCAST: &str = "simulcast";
pub(crate) const GENERATED_CERTIFICATE_ORIGIN: &str = "WebRTC";
pub(crate) const SDES_REPAIR_RTP_STREAM_ID_URI: &str =
"urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id";
pub(crate) const DEFAULT_SESSION_SRTP_REPLAY_PROTECTION_WINDOW: usize = 64;
pub(crate) const DEFAULT_SESSION_SRTCP_REPLAY_PROTECTION_WINDOW: usize = 64;
pub(crate) const DEFAULT_DTLS_REPLAY_PROTECTION_WINDOW: usize = 64;
40 changes: 19 additions & 21 deletions rtc/src/peer_connection/peer_connection_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::stats::{
StatsReportType,
};
use crate::track::TrackStream;
use crate::{SDES_REPAIR_RTP_STREAM_ID_URI, SDP_ATTRIBUTE_RID};
use crate::SDP_ATTRIBUTE_RID;

pub(crate) struct PeerConnectionInternal {}

Expand Down Expand Up @@ -573,7 +573,7 @@ impl PeerConnectionInternal {
let (rsid_extension_id, _, _) = self
.media_engine
.get_header_extension_id(RTCRtpHeaderExtensionCapability {
uri: SDES_REPAIR_RTP_STREAM_ID_URI.to_owned(),
uri: ::sdp::extmap::SDES_REPAIR_RTP_STREAM_ID_URI.to_owned(),
})
.await;

Expand Down Expand Up @@ -701,40 +701,38 @@ impl PeerConnectionInternal {
on_track_handler: Arc<ArcSwapOption<Mutex<OnTrackHdlrFn>>>,
) {
receiver.start(incoming).await;
for t in receiver.tracks().await {
if t.ssrc() == 0 {
for track in receiver.tracks().await {
if track.ssrc() == 0 {
return;
}

let receiver = Arc::clone(&receiver);
let transceiver = Arc::clone(&transceiver);
let on_track_handler = Arc::clone(&on_track_handler);
tokio::spawn(async move {
if let Some(track) = receiver.track().await {
let mut b = vec![0u8; receive_mtu];
let pkt = match track.peek(&mut b).await {
Ok((pkt, _)) => pkt,
Err(err) => {
log::warn!(
"Could not determine PayloadType for SSRC {} ({})",
track.ssrc(),
err
);
return;
}
};

if let Err(err) = track.check_and_update_track(&pkt).await {
let mut b = vec![0u8; receive_mtu];
let pkt = match track.peek(&mut b).await {
Ok((pkt, _)) => pkt,
Err(err) => {
log::warn!(
"Failed to set codec settings for track SSRC {} ({})",
"Could not determine PayloadType for SSRC {} ({})",
track.ssrc(),
err
);
return;
}
};

RTCPeerConnection::do_track(on_track_handler, track, receiver, transceiver);
if let Err(err) = track.check_and_update_track(&pkt).await {
log::warn!(
"Failed to set codec settings for track SSRC {} ({})",
track.ssrc(),
err
);
return;
}

RTCPeerConnection::do_track(on_track_handler, track, receiver, transceiver);
});
}
}
Expand Down
20 changes: 7 additions & 13 deletions rtc/src/peer_connection/sdp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,26 +224,20 @@ pub(crate) fn track_details_from_sdp(
};
}
// If media line is using RTP Stream Identifier Source Description per RFC8851
// we will need to override tracks, and remove ssrcs.
// This is in particular important for Firefox, as it uses both 'rid', 'simulcast'
// and 'a=ssrc' lines.
let rids = get_rids(media);
if !rids.is_empty() && !track_id.is_empty() && !stream_id.is_empty() {
let mut simulcast_track = TrackDetails {
tracks_in_media_section = vec![TrackDetails {
mid: SmolStr::from(mid_value),
kind: codec_type,
stream_id: stream_id.to_owned(),
id: track_id.to_owned(),
rids: vec![],
rids: rids.iter().map(|r| SmolStr::from(&r.id)).collect(),
..Default::default()
};
for rid in &rids {
simulcast_track.rids.push(SmolStr::from(&rid.id));
}
if simulcast_track.rids.len() == tracks_in_media_section.len() {
for track in &tracks_in_media_section {
simulcast_track.ssrcs.extend(&track.ssrcs)
}
}
tracks_in_media_section = vec![simulcast_track];
}];
}
incoming_tracks.extend(tracks_in_media_section);
Expand Down
10 changes: 0 additions & 10 deletions rtc/src/rtp_transceiver/rtp_receiver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,16 +397,6 @@ impl RTCRtpReceiver {
}
}
/// track returns the RtpTransceiver TrackRemote
pub async fn track(&self) -> Option<Arc<TrackRemote>> {
let tracks = self.internal.tracks.read().await;
if tracks.len() != 1 {
None
} else {
tracks.first().map(|t| Arc::clone(&t.track))
}
}
/// tracks returns the RtpTransceiver traclockks
/// A RTPReceiver to support Simulcast may now have multiple tracks
pub async fn tracks(&self) -> Vec<Arc<TrackRemote>> {
Expand Down
62 changes: 32 additions & 30 deletions rtc/src/rtp_transceiver/rtp_receiver/rtp_receiver_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,36 +92,38 @@ async fn test_set_rtp_parameters() -> Result<()> {
Box::pin(async move {
receiver.set_rtp_parameters(P.clone()).await;

if let Some(t) = receiver.track().await {
let incoming_track_codecs = t.codec();

assert_eq!(P.header_extensions, t.params().header_extensions);
assert_eq!(
P.codecs[0].capability.mime_type,
incoming_track_codecs.capability.mime_type
);
assert_eq!(
P.codecs[0].capability.clock_rate,
incoming_track_codecs.capability.clock_rate
);
assert_eq!(
P.codecs[0].capability.channels,
incoming_track_codecs.capability.channels
);
assert_eq!(
P.codecs[0].capability.sdp_fmtp_line,
incoming_track_codecs.capability.sdp_fmtp_line
);
assert_eq!(
P.codecs[0].capability.rtcp_feedback,
incoming_track_codecs.capability.rtcp_feedback
);
assert_eq!(P.codecs[0].payload_type, incoming_track_codecs.payload_type);

{
let mut done = seen_packet_tx2.lock().await;
done.take();
}
let tracks = receiver.tracks().await;
assert_eq!(tracks.len(), 1);
let t = tracks.first().unwrap();

let incoming_track_codecs = t.codec();

assert_eq!(P.header_extensions, t.params().header_extensions);
assert_eq!(
P.codecs[0].capability.mime_type,
incoming_track_codecs.capability.mime_type
);
assert_eq!(
P.codecs[0].capability.clock_rate,
incoming_track_codecs.capability.clock_rate
);
assert_eq!(
P.codecs[0].capability.channels,
incoming_track_codecs.capability.channels
);
assert_eq!(
P.codecs[0].capability.sdp_fmtp_line,
incoming_track_codecs.capability.sdp_fmtp_line
);
assert_eq!(
P.codecs[0].capability.rtcp_feedback,
incoming_track_codecs.capability.rtcp_feedback
);
assert_eq!(P.codecs[0].payload_type, incoming_track_codecs.payload_type);

{
let mut done = seen_packet_tx2.lock().await;
done.take();
}
})
}));
Expand Down

0 comments on commit 98b4ec4

Please sign in to comment.