aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-12-06 16:01:18 +0100
committermetamuffin <metamuffin@disroot.org>2024-12-06 16:01:18 +0100
commit8e19859996eee29ba28c4e4a933ba396924ac163 (patch)
treecc9c44f6e19d3a18ad57782f11b760abab15bca1
parent8d02c52f770e5626a67dfdc47214fc23b744ac47 (diff)
downloadsip-rs-8e19859996eee29ba28c4e4a933ba396924ac163.tar
sip-rs-8e19859996eee29ba28c4e4a933ba396924ac163.tar.bz2
sip-rs-8e19859996eee29ba28c4e4a933ba396924ac163.tar.zst
a
-rw-r--r--Cargo.lock1
-rw-r--r--rtp/Cargo.toml1
-rw-r--r--rtp/src/lib.rs52
-rw-r--r--rtp/src/rtcp.rs86
4 files changed, 107 insertions, 33 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 672b764..1d2ada1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -395,6 +395,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
name = "rtp"
version = "0.1.0"
dependencies = [
+ "log",
"thiserror",
]
diff --git a/rtp/Cargo.toml b/rtp/Cargo.toml
index 84f0116..462f52e 100644
--- a/rtp/Cargo.toml
+++ b/rtp/Cargo.toml
@@ -5,3 +5,4 @@ edition = "2021"
[dependencies]
thiserror = "2.0.3"
+log = "0.4.22"
diff --git a/rtp/src/lib.rs b/rtp/src/lib.rs
index 0c80412..d7d8d6a 100644
--- a/rtp/src/lib.rs
+++ b/rtp/src/lib.rs
@@ -5,7 +5,8 @@ use std::{
time::{Duration, Instant},
};
-use rtcp::RtcpPacket;
+use log::debug;
+use rtcp::{RtcpPacket, RtcpPart};
use rtp::SSRC;
pub mod rtcp;
@@ -24,6 +25,7 @@ pub struct Session {
initial: bool,
member_table: HashSet<SSRC>,
+ sender_table: HashSet<SSRC>,
}
impl Session {
@@ -51,6 +53,7 @@ impl Session {
let td = tmin.max(n as f32 * c);
let t = td * ((random::<u16>() as f32) / (u16::MAX as f32) + 0.5);
let t = t / 1.5f32.exp();
+ debug!("RTCP transmission interval is {t:.02}s");
Duration::from_secs_f32(t)
}
@@ -65,6 +68,7 @@ impl Session {
members: 1,
we_sent: false,
initial: true,
+ sender_table: HashSet::new(),
member_table: HashSet::new(), // TODO add own ssrc to members
rtcp_bw: 1000., // TODO set rtcp bandwidth from params
avg_rtcp_size: 1000., // TODO set to next likely rtcp packet size
@@ -73,6 +77,48 @@ impl Session {
se
}
- /// RFC 3550, Section 6.3.3
- pub fn on_receive(&mut self, packet: RtcpPacket) {}
+ pub fn tt_expire(&mut self) {
+ let t = self.compute_rtcp_transmission_interval();
+ if self.tp + t < self.tc {
+ self.send_rtcp();
+ self.tp = self.tc;
+ let t = self.compute_rtcp_transmission_interval();
+ self.tn = self.tc + t;
+ if self.tp + t > self.tc {
+ self.tn = self.tp + t;
+ }
+ self.pmembers = self.members;
+ }
+ }
+
+ pub fn send_rtcp(&mut self) {
+
+ }
+
+ /// RFC 3550, Section 6.3.3 / 6.3.4
+ pub fn on_receive(&mut self, packet_raw: &[u8]) {
+ let packet = RtcpPacket::parse(packet_raw).unwrap(); // TODO
+
+ let bye = packet.parts.iter().find_map(|p| match p {
+ RtcpPart::Bye(b) => Some(b),
+ _ => None,
+ });
+ if let Some(bye) = bye {
+ for s in &bye.ssrcs {
+ if self.member_table.remove(s) {
+ self.members -= 1;
+ }
+ if self.sender_table.remove(s) {
+ self.senders -= 1;
+ }
+ }
+ let f_mem = self.members as f32 / self.pmembers as f32;
+ self.tn = self.tc + (self.tn - self.tc).mul_f32(f_mem);
+ self.tp = self.tc - (self.tc - self.tp).mul_f32(f_mem);
+ self.pmembers = self.members
+ } else {
+ self.avg_rtcp_size =
+ (1. / 16.) * packet_raw.len() as f32 + (15. / 16.) * self.avg_rtcp_size;
+ }
+ }
}
diff --git a/rtp/src/rtcp.rs b/rtp/src/rtcp.rs
index da0a683..371aa85 100644
--- a/rtp/src/rtcp.rs
+++ b/rtp/src/rtcp.rs
@@ -9,46 +9,63 @@ pub enum Error {
}
pub struct RtcpPacket<'a> {
- parts: Vec<RtcpPart<'a>>,
+ pub parts: Vec<RtcpPart<'a>>,
}
pub enum RtcpPart<'a> {
SenderReport(SenderReport<'a>),
ReceiverReport(ReceiverReport),
SourceDescription(SourceDescription),
- Bye(Bye),
+ Bye(Bye<'a>),
Application(Application<'a>),
}
-struct SenderReport<'a> {
- ssrc: SSRC,
- sender_info: SenderInfo,
- reports: Vec<ReportBlock>,
- extension: &'a [u8],
+pub struct SenderReport<'a> {
+ pub ssrc: SSRC,
+ pub sender_info: SenderInfo,
+ pub reports: Vec<ReportBlock>,
+ pub extension: &'a [u8],
}
-struct ReceiverReport {
- sender_ssrc: SSRC,
- reports: Vec<ReportBlock>,
+pub struct ReceiverReport {
+ pub sender_ssrc: SSRC,
+ pub reports: Vec<ReportBlock>,
}
-struct SourceDescription {}
-struct Bye {}
-struct Application<'a> {
- data: &'a [u8],
+pub struct SourceDescription {
+ sources: Vec<(SSRC, Vec<SourceDescriptionItem>)>,
}
-struct SenderInfo {
- ntp_ts: u64,
- rtp_ts: u32,
- packet_count: u32,
- octet_count: u32,
+pub enum SourceDescriptionItem {
+ CanonicalName(String),
+ Name(String),
+ Email(String),
+ Phone(String),
+ Location(String),
+ Tool(String),
+ Notice(String),
+ PrivateExtension(String),
}
-struct ReportBlock {
- ssrc: SSRC,
- fraction_lost: u8,
- cumulative_packets_lost: u32,
- ext_max_seq_num_recv: u32,
- interarrical_jitter: u32,
- lsr: u32,
- dlsr: u32,
+pub struct Bye<'a> {
+ pub ssrcs: Vec<SSRC>,
+ pub reason: &'a [u8],
+}
+pub struct Application<'a> {
+ pub subtype: u8,
+ pub name: [u8; 4],
+ pub data: &'a [u8],
+}
+pub struct SenderInfo {
+ pub ntp_ts: u64,
+ pub rtp_ts: u32,
+ pub packet_count: u32,
+ pub octet_count: u32,
+}
+pub struct ReportBlock {
+ pub ssrc: SSRC,
+ pub fraction_lost: u8,
+ pub cumulative_packets_lost: u32,
+ pub ext_max_seq_num_recv: u32,
+ pub interarrical_jitter: u32,
+ pub lsr: u32,
+ pub dlsr: u32,
}
impl<'a> RtcpPacket<'a> {
@@ -69,7 +86,7 @@ impl<'a> RtcpPacket<'a> {
match packet_type {
200 => {
- // Sender Report
+ // sender seport
if packet.len() < 28 + 24 * num_reports as usize {
return Err(Error::Truncated);
}
@@ -89,7 +106,17 @@ impl<'a> RtcpPacket<'a> {
extension,
}))
}
- 201 => { // Receiver Report
+ 201 => {
+ // receiver report
+ }
+ 202 => {
+ // source description
+ }
+ 203 => {
+ // bye
+ }
+ 204 => {
+ // application defined
}
_ => {}
}
@@ -107,7 +134,6 @@ impl<'a> RtcpPacket<'a> {
version << 6 | (padding as u8) << 5 | sender_report.reports.len() as u8,
);
out.push(200);
-
}
RtcpPart::ReceiverReport(receiver_report) => todo!(),
RtcpPart::SourceDescription(source_description) => todo!(),