#![feature(random)] use std::{ collections::HashSet, random::random, time::{Duration, Instant}, }; use rtcp::RtcpPacket; use rtp::SSRC; pub mod rtcp; pub mod rtp; pub struct Session { tp: Instant, tc: Instant, tn: Instant, pmembers: usize, members: usize, senders: usize, rtcp_bw: f32, we_sent: bool, avg_rtcp_size: f32, initial: bool, member_table: HashSet, } impl Session { /// RFC 3550, Section 6.3.1 pub fn compute_rtcp_transmission_interval(&self) -> Duration { let n; let c; if self.senders * 4 < self.members { if self.we_sent { // Senders use a quarter of the bandwidth c = self.avg_rtcp_size / (self.rtcp_bw * 0.25); n = self.senders; } else { // Receivers use the remaining three quarters c = self.avg_rtcp_size / (self.rtcp_bw * 0.75); n = self.members - self.senders } } else { // Equally split between members c = self.avg_rtcp_size / self.rtcp_bw; n = self.members; } let tmin = if self.initial { 2.5f32 } else { 5. }; let td = tmin.max(n as f32 * c); let t = td * ((random::() as f32) / (u16::MAX as f32) + 0.5); let t = t / 1.5f32.exp(); Duration::from_secs_f32(t) } /// RFC 3550, Section 6.3.2 pub fn new() -> Self { let mut se = Self { tp: Instant::now(), tc: Instant::now(), tn: Instant::now(), senders: 0, pmembers: 1, members: 1, we_sent: false, initial: true, 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 }; se.tn += se.compute_rtcp_transmission_interval(); se } /// RFC 3550, Section 6.3.3 pub fn on_receive(&mut self, packet: RtcpPacket) {} }