use std::time::Instant;
use crate::Reason;
use crate::bwe_::ProbeClusterConfig;
use crate::rtp_::{Bitrate, DataSize, MidRid, TwccClusterId};
mod control;
pub(crate) use control::PacerControl;
mod null;
use null::NullPacer;
mod leaky;
use leaky::LeakyBucketPacer;
mod queue;
pub(crate) use queue::{PaddingRequest, QueuePriority, QueueSnapshot, QueueState};
#[allow(clippy::large_enum_variant)]
pub(crate) enum PacerImpl {
Null(NullPacer),
LeakyBucket(LeakyBucketPacer),
}
impl PacerImpl {
pub fn leaky_bucket(rate: Bitrate) -> PacerImpl {
PacerImpl::LeakyBucket(LeakyBucketPacer::new(rate))
}
pub fn null() -> PacerImpl {
PacerImpl::Null(NullPacer::default())
}
pub fn start_probe(&mut self, config: ProbeClusterConfig) {
match self {
PacerImpl::Null(_) => {
}
PacerImpl::LeakyBucket(v) => v.start_probe(config),
}
}
pub fn check_probe_complete(&mut self, now: Instant) -> Option<TwccClusterId> {
match self {
PacerImpl::Null(_) => None,
PacerImpl::LeakyBucket(v) => v.check_probe_complete(now),
}
}
}
impl Pacer for PacerImpl {
fn set_pacing_rate(&mut self, pacing_bitrate: Bitrate) {
match self {
PacerImpl::Null(v) => v.set_pacing_rate(pacing_bitrate),
PacerImpl::LeakyBucket(v) => v.set_pacing_rate(pacing_bitrate),
}
}
fn set_padding_rate(&mut self, padding_bitrate: Bitrate) {
match self {
PacerImpl::Null(v) => v.set_padding_rate(padding_bitrate),
PacerImpl::LeakyBucket(v) => v.set_padding_rate(padding_bitrate),
}
}
fn poll_timeout(&self) -> (Option<Instant>, Reason) {
match self {
PacerImpl::Null(v) => v.poll_timeout(),
PacerImpl::LeakyBucket(v) => v.poll_timeout(),
}
}
fn handle_timeout(
&mut self,
now: Instant,
iter: impl Iterator<Item = QueueState>,
) -> Option<PaddingRequest> {
match self {
PacerImpl::Null(v) => v.handle_timeout(now, iter),
PacerImpl::LeakyBucket(v) => v.handle_timeout(now, iter),
}
}
fn poll_queue(&mut self) -> Option<(MidRid, Option<TwccClusterId>)> {
match self {
PacerImpl::Null(v) => v.poll_queue(),
PacerImpl::LeakyBucket(v) => v.poll_queue(),
}
}
fn register_send(&mut self, now: Instant, packet_size: DataSize, from: MidRid) {
match self {
PacerImpl::Null(v) => v.register_send(now, packet_size, from),
PacerImpl::LeakyBucket(v) => v.register_send(now, packet_size, from),
}
}
fn has_padding_queue(&self) -> bool {
match self {
PacerImpl::Null(v) => v.has_padding_queue(),
PacerImpl::LeakyBucket(v) => v.has_padding_queue(),
}
}
}
pub trait Pacer {
fn set_pacing_rate(&mut self, pacing_bitrate: Bitrate);
fn set_padding_rate(&mut self, padding_bitrate: Bitrate);
fn poll_timeout(&self) -> (Option<Instant>, Reason);
fn handle_timeout(
&mut self,
now: Instant,
iter: impl Iterator<Item = QueueState>,
) -> Option<PaddingRequest>;
fn poll_queue(&mut self) -> Option<(MidRid, Option<TwccClusterId>)>;
fn register_send(&mut self, now: Instant, packet_size: DataSize, from: MidRid);
fn has_padding_queue(&self) -> bool;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum PacerReason {
Handle,
FirstEver,
Unpaced,
Probe1,
Probe2,
Paced,
Padding,
Immediate,
}