use std::collections::HashSet;
use rtc::media_stream::MediaStreamTrack;
use rtc::peer_connection::RTCPeerConnectionBuilder;
use rtc::peer_connection::configuration::media_engine::{MIME_TYPE_VP8, MediaEngine};
use rtc::peer_connection::sdp::RTCSessionDescription;
use rtc::rtp_transceiver::rtp_sender::{
RTCRtpCodec, RTCRtpCodingParameters, RTCRtpEncodingParameters, RtpCodecKind,
};
use sansio::Protocol;
fn new_video_track(stream_id: &str, track_id: &str, ssrc: u32) -> MediaStreamTrack {
MediaStreamTrack::new(
stream_id.to_owned(),
track_id.to_owned(),
format!("track-{}", track_id),
RtpCodecKind::Video,
vec![RTCRtpEncodingParameters {
rtp_coding_parameters: RTCRtpCodingParameters {
ssrc: Some(ssrc),
..Default::default()
},
codec: RTCRtpCodec {
mime_type: MIME_TYPE_VP8.to_owned(),
clock_rate: 90000,
channels: 0,
sdp_fmtp_line: String::new(),
rtcp_feedback: vec![],
},
..Default::default()
}],
)
}
fn collect_mids(sdp: &RTCSessionDescription) -> Vec<String> {
let parsed = sdp.unmarshal().expect("failed to parse SDP");
parsed
.media_descriptions
.iter()
.filter_map(|m| m.attribute("mid").and_then(|v| v.map(|s| s.to_owned())))
.collect()
}
#[test]
fn test_renegotiation_no_duplicate_mids() -> Result<(), Box<dyn std::error::Error>> {
let mut me = MediaEngine::default();
me.register_default_codecs()?;
let me2 = me.clone();
let mut offerer = RTCPeerConnectionBuilder::new()
.with_media_engine(me)
.build()?;
let track1 = new_video_track("stream-1", "video-1", 11111);
offerer.add_track(track1)?;
let mut answerer = RTCPeerConnectionBuilder::new()
.with_media_engine(me2)
.build()?;
let offer1 = offerer.create_offer(None)?;
offerer.set_local_description(offer1.clone())?;
answerer.set_remote_description(offer1)?;
let answer1 = answerer.create_answer(None)?;
answerer.set_local_description(answer1.clone())?;
offerer.set_remote_description(answer1)?;
let offer1_for_check = offerer.create_offer(None)?;
let mids = collect_mids(&offer1_for_check);
let unique: HashSet<_> = mids.iter().collect();
assert_eq!(
mids.len(),
unique.len(),
"first renegotiation offer already has duplicate mids: {:?}",
mids,
);
let track2 = new_video_track("stream-2", "video-2", 22222);
offerer.add_track(track2)?;
let offer2 = offerer.create_offer(None)?;
let mids = collect_mids(&offer2);
let unique: HashSet<_> = mids.iter().collect();
assert_eq!(
mids.len(),
unique.len(),
"renegotiation offer has duplicate mids: {:?}",
mids,
);
assert_eq!(
mids.len(),
2,
"expected 2 media sections, got {}: {:?}",
mids.len(),
mids,
);
offerer.close()?;
answerer.close()?;
Ok(())
}