Skip to content

Commit

Permalink
add set_remote_description
Browse files Browse the repository at this point in the history
  • Loading branch information
yngrtc committed Jan 21, 2024
1 parent 6163a15 commit e4af340
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 53 deletions.
5 changes: 4 additions & 1 deletion src/server/endpoint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ pub mod candidate;
pub mod transport;

use crate::server::endpoint::transport::Transport;
use crate::server::session::description::rtp_transceiver::RTCRtpTransceiver;
use crate::server::session::Session;
use crate::types::{EndpointId, FourTuple};
use crate::types::{EndpointId, FourTuple, Mid};
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::{Rc, Weak};
Expand All @@ -13,6 +14,7 @@ pub(crate) struct Endpoint {
session: Weak<Session>,
endpoint_id: EndpointId,
transports: RefCell<HashMap<FourTuple, Rc<Transport>>>,
pub(crate) transceivers: RefCell<HashMap<Mid, RTCRtpTransceiver>>,
}

impl Endpoint {
Expand All @@ -21,6 +23,7 @@ impl Endpoint {
session,
endpoint_id,
transports: RefCell::new(HashMap::new()),
transceivers: RefCell::new(HashMap::new()),
}
}

Expand Down
46 changes: 22 additions & 24 deletions src/server/session/description/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,32 +272,28 @@ pub(crate) fn add_transceiver_sdp(
ice_params: &RTCIceParameters,
candidate: &SocketAddr,
media_section: &MediaSection,
transceiver: Option<&RTCRtpTransceiver>,
transceiver: &RTCRtpTransceiver,
params: AddTransceiverSdpParams,
) -> Result<(SessionDescription, bool)> {
if transceiver.is_none() {
return Err(Error::Other("ErrSDPZeroTransceivers".to_string()));
}
let (should_add_candidates, mid_value, dtls_role, ice_gathering_state) = (
params.should_add_candidates,
params.mid_value,
params.dtls_role,
params.ice_gathering_state,
);

// Use the first transceiver to generate the section attributes
let t = &transceiver.as_ref().unwrap();
let mut media = MediaDescription::new_jsep_media_description(t.kind.to_string(), vec![])
.with_value_attribute(ATTR_KEY_CONNECTION_SETUP.to_owned(), dtls_role.to_string())
.with_value_attribute(ATTR_KEY_MID.to_owned(), mid_value.clone())
.with_ice_credentials(
ice_params.username_fragment.clone(),
ice_params.password.clone(),
)
.with_property_attribute(ATTR_KEY_RTCPMUX.to_owned())
.with_property_attribute(ATTR_KEY_RTCPRSIZE.to_owned());

let codecs = &t.codecs;
let mut media =
MediaDescription::new_jsep_media_description(transceiver.kind.to_string(), vec![])
.with_value_attribute(ATTR_KEY_CONNECTION_SETUP.to_owned(), dtls_role.to_string())
.with_value_attribute(ATTR_KEY_MID.to_owned(), mid_value.clone())
.with_ice_credentials(
ice_params.username_fragment.clone(),
ice_params.password.clone(),
)
.with_property_attribute(ATTR_KEY_RTCPMUX.to_owned())
.with_property_attribute(ATTR_KEY_RTCPRSIZE.to_owned());

let codecs = &transceiver.codecs;
for codec in codecs {
let name = codec
.capability
Expand Down Expand Up @@ -325,14 +321,14 @@ pub(crate) fn add_transceiver_sdp(
}
if codecs.is_empty() {
// If we are sender and we have no codecs throw an error early
if t.sender.track.is_some() {
if transceiver.sender.track.is_some() {
return Err(Error::Other("ErrSenderWithNoCodecs".to_string()));
}

// Explicitly reject track if we don't have the codec
d = d.with_media(MediaDescription {
media_name: sdp::description::media::MediaName {
media: t.kind.to_string(),
media: transceiver.kind.to_string(),
port: RangedPort {
value: 0,
range: None,
Expand Down Expand Up @@ -391,7 +387,7 @@ pub(crate) fn add_transceiver_sdp(
);
}

let sender = &t.sender;
let sender = &transceiver.sender;
if let Some(track) = &sender.track {
media = media.with_media_source(
sender.ssrc,
Expand Down Expand Up @@ -432,7 +428,7 @@ pub(crate) fn add_transceiver_sdp(
let direction = match params.offered_direction {
Some(offered_direction) => {
use RTCRtpTransceiverDirection::*;
let transceiver_direction = t.direction;
let transceiver_direction = transceiver.direction;

match offered_direction {
Sendonly | Recvonly => {
Expand All @@ -449,7 +445,7 @@ pub(crate) fn add_transceiver_sdp(
// media or session level, in which case the stream is sendrecv by
// default), the corresponding stream in the answer MAY be marked as
// sendonly, recvonly, sendrecv, or inactive
Sendrecv | Unspecified => t.direction,
Sendrecv | Unspecified => transceiver.direction,
// If an offered media
// stream is listed as inactive, it MUST be marked as inactive in the
// answer.
Expand All @@ -464,7 +460,7 @@ pub(crate) fn add_transceiver_sdp(
//
// When creating offers, the transceiver direction is directly reflected
// in the output, even for re-offers.
t.direction
transceiver.direction
}
};
media = media.with_property_attribute(direction.to_string());
Expand Down Expand Up @@ -541,7 +537,9 @@ pub(crate) fn populate_sdp(
ice_params,
candidate,
m,
transceivers.get(&m.mid),
transceivers
.get(&m.mid)
.ok_or(Error::Other("ErrSDPZeroTransceivers".to_string()))?,
params,
)?;
d = d1;
Expand Down
34 changes: 25 additions & 9 deletions src/server/session/description/rtp_sender.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::server::session::description::rtp_codec::RTPCodecType;
use crate::server::session::description::rtp_transceiver::{PayloadType, SSRC};
use crate::server::session::description::rtp_transceiver::SSRC;

#[derive(Debug, Clone)]
pub(crate) struct TrackLocal {
Expand All @@ -18,34 +18,50 @@ pub struct RTCRtpSender {
//pub(crate) context: Mutex<TrackLocalContext>,

//pub(crate) transport: Arc<RTCDtlsTransport>,
pub(crate) payload_type: PayloadType,
//pub(crate) payload_type: PayloadType,
pub(crate) ssrc: SSRC,
pub(crate) receive_mtu: usize,

//pub(crate) receive_mtu: usize,
/// a transceiver sender since we can just check the
/// transceiver negotiation status
pub(crate) negotiated: bool,
negotiated: bool,

//pub(crate) media_engine: Arc<MediaEngine>,
//pub(crate) interceptor: Arc<dyn Interceptor + Send + Sync>,
pub(crate) id: String,

//pub(crate) id: String,
/// The id of the initial track, even if we later change to a different
/// track id should be use when negotiating.
pub(crate) initial_track_id: Option<String>,
/// AssociatedMediaStreamIds from the WebRTC specifications
pub(crate) associated_media_stream_ids: Vec<String>,

//pub(crate) rtp_transceiver: Option<RTCRtpTransceiver>,
pub(crate) paused: bool,
paused: bool,
}

impl RTCRtpSender {
pub(crate) fn new() -> Self {
Self {
track: None,
ssrc: rand::random::<u32>(),
negotiated: false,
initial_track_id: None,
associated_media_stream_ids: vec![],
paused: false,
}
}

pub(crate) fn is_negotiated(&self) -> bool {
self.negotiated
}

pub(crate) fn set_negotiated(&mut self) {
self.negotiated = true;
}

pub(crate) fn is_paused(&self) -> bool {
self.paused
}

pub(crate) fn set_paused(&mut self, paused: bool) {
self.paused = paused;
}
}
92 changes: 86 additions & 6 deletions src/server/session/description/rtp_transceiver.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::server::session::description::rtp_codec::{RTCRtpCodecParameters, RTPCodecType};
use crate::server::session::description::rtp_receiver::RTCRtpReceiver;
use crate::server::session::description::rtp_sender::RTCRtpSender;
use crate::server::session::description::rtp_transceiver_direction::RTCRtpTransceiverDirection;
use log::{debug, trace};
use shared::error::Result;

/// SSRC represents a synchronization source
/// A synchronization source is a randomly chosen
Expand Down Expand Up @@ -49,17 +50,96 @@ pub struct RTCPFeedback {
/// RTPTransceiver represents a combination of an RTPSender and an RTPReceiver that share a common mid.
#[derive(Debug, Clone)]
pub struct RTCRtpTransceiver {
pub(crate) mid: String,
//pub(crate) mid: String,
pub(crate) sender: RTCRtpSender,
pub(crate) receiver: RTCRtpReceiver,
//pub(crate) receiver: RTCRtpReceiver,
pub(crate) direction: RTCRtpTransceiverDirection,
pub(crate) current_direction: RTCRtpTransceiverDirection,

current_direction: RTCRtpTransceiverDirection,
pub(crate) codecs: Vec<RTCRtpCodecParameters>, // User provided codecs via set_codec_preferences

pub(crate) stopped: bool,
pub(crate) kind: RTPCodecType,
//media_engine: Arc<MediaEngine>,

//trigger_negotiation_needed: Mutex<TriggerNegotiationNeededFnOption>,
}

impl RTCRtpTransceiver {
pub(crate) fn new(
sender: RTCRtpSender,
direction: RTCRtpTransceiverDirection,
codecs: Vec<RTCRtpCodecParameters>,
kind: RTPCodecType,
) -> Self {
Self {
sender,
direction,
current_direction: RTCRtpTransceiverDirection::Unspecified,
codecs,
stopped: false,
kind,
}
}

/// current_direction returns the RTPTransceiver's current direction as negotiated.
///
/// If this transceiver has never been negotiated or if it's stopped this returns [`RTCRtpTransceiverDirection::Unspecified`].
pub fn current_direction(&self) -> RTCRtpTransceiverDirection {
if self.stopped {
return RTCRtpTransceiverDirection::Unspecified;
}

self.current_direction
}

pub(crate) fn set_current_direction(&mut self, d: RTCRtpTransceiverDirection) {
let previous = self.current_direction;
self.current_direction = d;
if d != previous {
debug!(
"Changing current direction of transceiver from {} to {}",
previous, d,
);
}
}

/// Perform any subsequent actions after altering the transceiver's direction.
///
/// After changing the transceiver's direction this method should be called to perform any
/// side-effects that results from the new direction, such as pausing/resuming the RTP receiver.
pub(crate) fn process_new_current_direction(
&mut self,
previous_direction: RTCRtpTransceiverDirection,
) -> Result<()> {
if self.stopped {
return Ok(());
}

let current_direction = self.current_direction();
if previous_direction != current_direction {
trace!(
"Processing transceiver direction change from {} to {}",
previous_direction,
current_direction
);
} else {
// no change.
return Ok(());
}

/*{
let receiver = self.receiver.lock().await;
let pause_receiver = !current_direction.has_recv();
if pause_receiver {
receiver.pause().await?;
} else {
receiver.resume().await?;
}
}*/

let pause_sender = !current_direction.has_send();
self.sender.set_paused(pause_sender);

Ok(())
}
}
Loading

0 comments on commit e4af340

Please sign in to comment.