use anyhow::Result;
use bytes::Bytes;
use rustrtc::media::MediaStreamTrack;
use rustrtc::media::frame::{MediaSample, VideoFrame};
use rustrtc::{MediaKind, RtcConfiguration};
use rustrtc::{PeerConnection, TransceiverDirection};
use std::time::Duration;
use tokio::time::timeout;
#[tokio::test]
async fn test_padding_packet_drop() -> Result<()> {
println!("Start test");
let _ = env_logger::builder().is_test(true).try_init();
println!("Create PC1");
let config1 = RtcConfiguration::default();
let pc1 = PeerConnection::new(config1);
println!("Create PC2");
let config2 = RtcConfiguration::default();
let pc2 = PeerConnection::new(config2);
let (client_source, client_track, _) =
rustrtc::media::sample_track(rustrtc::media::MediaKind::Video, 96);
let t1 = pc1.add_transceiver(MediaKind::Video, TransceiverDirection::SendRecv);
let s1 = rustrtc::peer_connection::RtpSender::builder(client_track, 11111)
.stream_id("stream".to_string())
.params(rustrtc::RtpCodecParameters {
payload_type: 96,
clock_rate: 90000,
channels: 0,
})
.build();
t1.set_sender(Some(s1.clone()));
println!("PC1 Create Offer");
let _ = pc1.create_offer().await?; println!("PC1 Wait Gathering");
pc1.wait_for_gathering_complete().await;
println!("PC1 Create Offer 2");
let offer = pc1.create_offer().await?;
pc1.set_local_description(offer.clone())?;
println!("PC2 Set Remote Offer");
pc2.set_remote_description(offer).await?;
let t2 = pc2.get_transceivers().first().unwrap().clone();
let (sample_source, outgoing_track, _) =
rustrtc::media::sample_track(rustrtc::media::MediaKind::Video, 96);
let s2 = rustrtc::peer_connection::RtpSender::builder(outgoing_track, 55555)
.stream_id("stream".to_string())
.params(rustrtc::RtpCodecParameters {
payload_type: 96,
clock_rate: 90000,
channels: 0,
})
.build();
t2.set_sender(Some(s2));
println!("PC2 Create Answer");
let _ = pc2.create_answer().await?; println!("PC2 Wait Gathering");
pc2.wait_for_gathering_complete().await;
println!("PC2 Create Answer 2");
let answer = pc2.create_answer().await?;
pc2.set_local_description(answer.clone())?;
println!("PC1 Set Remote Answer");
pc1.set_remote_description(answer).await?;
let r2 = t2.receiver().unwrap();
let track2 = r2.track();
tokio::spawn(async move {
loop {
match track2.recv().await {
Ok(sample) => {
let _ = sample_source.send(sample).await;
}
Err(_) => break,
}
}
});
println!("PC1 Wait Connection");
pc1.wait_for_connected().await?;
println!("PC2 Wait Connection");
pc2.wait_for_connected().await?;
println!("Sending P1");
let f1 = VideoFrame {
rtp_timestamp: 1000,
data: Bytes::from(vec![0x90, 0x80, 0x01]),
..Default::default()
};
client_source.send_video(f1).await?;
println!("Sent P1");
println!("Sending P2");
let f2 = VideoFrame {
rtp_timestamp: 1000,
data: Bytes::new(), ..Default::default()
};
client_source.send_video(f2).await?;
println!("Sent P2");
println!("Sending P3");
let f3 = VideoFrame {
rtp_timestamp: 4000,
data: Bytes::from(vec![0x90, 0x80, 0x01]), is_last_packet: true,
..Default::default()
};
client_source.send_video(f3).await?;
println!("Sent P3");
let r1 = t1.receiver().unwrap();
let track1 = r1.track();
let s1_recv = timeout(Duration::from_secs(5), track1.recv())
.await?
.unwrap();
if let MediaSample::Video(f) = s1_recv {
println!("Received P1: len={}", f.data.len());
assert!(!f.data.is_empty());
} else {
panic!("Expected Video sample");
}
let s2_recv = timeout(Duration::from_secs(5), track1.recv())
.await?
.unwrap();
if let MediaSample::Video(f) = s2_recv {
println!("Received P2: len={}", f.data.len());
assert!(f.data.is_empty());
} else {
panic!("Expected Video sample");
}
let s3_recv = timeout(Duration::from_secs(5), track1.recv())
.await?
.unwrap();
if let MediaSample::Video(f) = s3_recv {
println!("Received P3: len={}", f.data.len());
assert!(!f.data.is_empty());
} else {
panic!("Expected Video sample");
}
let res = timeout(Duration::from_millis(500), track1.recv()).await;
assert!(res.is_err(), "Should not receive a 3rd packet");
pc1.close();
pc2.close();
Ok(())
}