diff --git a/src/change/sdp.rs b/src/change/sdp.rs index 06db7d45..00cb185b 100644 --- a/src/change/sdp.rs +++ b/src/change/sdp.rs @@ -1081,8 +1081,14 @@ fn update_media( media.set_direction(new_dir); } - for rid in m.rids().iter() { - media.expect_rid_rx(*rid); + if new_dir.is_sending() { + // The other side has declared how it EXPECTING to receive. We must only send + // the RIDs declared in the answer. + media.set_rid_tx(m.rids().into()); + } + if new_dir.is_receiving() { + // The other side has declared what it proposes to send. We are accepting it. + media.set_rid_rx(m.rids().into()); } // Narrowing/ordering of of PT diff --git a/src/media/mod.rs b/src/media/mod.rs index e5182af9..0c5da4d4 100644 --- a/src/media/mod.rs +++ b/src/media/mod.rs @@ -49,6 +49,11 @@ pub struct Media { /// RTP level. rids_rx: Rids, + /// Rid that we can send using the [`Writer`]. + /// + /// RTP level. + rids_tx: Rids, + // ========================================= SDP level ========================================= // /// The index of this media line in the Session::media Vec. @@ -120,8 +125,10 @@ pub struct Media { } #[derive(Debug)] -/// Config value for [`Media::rids_rx()`] +/// Config value for [`Media::rids_rx()`] and [`Media::rids_tx()`] pub enum Rids { + /// No rid is allowed. + None, /// Any Rid is allowed. /// /// This is the default value for direct API. @@ -135,6 +142,7 @@ pub enum Rids { impl Rids { pub(crate) fn contains(&self, rid: Rid) -> bool { match self { + Rids::None => false, Rids::Any => true, Rids::Specific(v) => v.contains(&rid), } @@ -145,6 +153,12 @@ impl Rids { } } +impl> From for Rids { + fn from(value: I) -> Self { + Rids::Specific(value.as_ref().to_vec()) + } +} + #[derive(Debug)] pub(crate) struct ToPayload { pub pt: Pt, @@ -200,6 +214,16 @@ impl Media { &self.rids_rx } + /// Rids we are can send via the [`Writer`]. + /// + /// By default this is set to [`Rids::None`], which changes to [`Rids::Specific`] via SDP negotiation + /// that configures Simulcast where specific rids are expected. + /// + /// RTP level. + pub fn rids_tx(&self) -> &Rids { + &self.rids_tx + } + pub(crate) fn index(&self) -> usize { self.index } @@ -467,6 +491,14 @@ impl Media { // Simply remove the depayloader, it will be re-created on the next RTP packet. self.depayloaders.remove(&(payload_type, rid)); } + + pub(crate) fn set_rid_rx(&mut self, rids: Rids) { + self.rids_rx = rids; + } + + pub(crate) fn set_rid_tx(&mut self, rids: Rids) { + self.rids_tx = rids; + } } impl Default for Media { @@ -484,6 +516,7 @@ impl Default for Media { dir: Direction::SendRecv, simulcast: None, rids_rx: Rids::Any, + rids_tx: Rids::None, payloaders: HashMap::new(), depayloaders: HashMap::new(), to_payload: VecDeque::default(),