use std::collections::HashMap; use std::time::Instant; use super::Pacer; use super::PaddingRequest; use super::QueueState; use crate::Reason; use crate::pacer::PacerReason; use crate::rtp_::{Bitrate, DataSize, MidRid, TwccClusterId}; /// A null pacer that doesn't pace. #[derive(Debug)] pub struct NullPacer { last_sends: HashMap, queue_states: Vec, needs_timeout_before_next_poll: bool, } impl Default for NullPacer { fn default() -> Self { Self { last_sends: HashMap::default(), queue_states: Vec::default(), needs_timeout_before_next_poll: true, } } } impl Pacer for NullPacer { fn set_pacing_rate(&mut self, _padding_bitrate: Bitrate) { // We don't care } fn set_padding_rate(&mut self, _padding_bitrate: Bitrate) { // We don't care } fn poll_timeout(&self) -> (Option, Reason) { let time = if self.needs_timeout_before_next_poll { self.last_sends.values().min().copied() } else { None }; (time, Reason::Pacer(PacerReason::Handle)) } fn handle_timeout( &mut self, _now: Instant, iter: impl Iterator, ) -> Option { self.needs_timeout_before_next_poll = false; self.queue_states.clear(); self.queue_states.extend(iter); None } fn poll_queue(&mut self) -> Option<(MidRid, Option)> { let non_empty_queues = self .queue_states .iter() .filter(|q| q.snapshot.packet_count > 0); // Pick a queue using round robin, prioritize the least recently sent on queue. let to_send_on = non_empty_queues.min_by_key(|q| self.last_sends.get(&q.midrid)); let result = to_send_on.map(|q| (q.midrid, None)); if result.is_some() { self.needs_timeout_before_next_poll = true; } result } fn register_send(&mut self, now: Instant, _packet_size: DataSize, from: MidRid) { let e = self.last_sends.entry(from).or_insert(now); *e = now; } fn has_padding_queue(&self) -> bool { false } }