use crate::container::Timestamp;
#[derive(Default)]
pub struct Jitter {
last_timestamp: Option<Timestamp>,
min_duration: Option<Timestamp>,
max_reorder: Timestamp,
reported: Option<Timestamp>,
}
impl Jitter {
pub fn new() -> Self {
Self::default()
}
pub fn observe(&mut self, ts: Timestamp) -> Option<moq_net::Time> {
if let Some(last) = self.last_timestamp.replace(ts)
&& let Ok(duration) = ts.checked_sub(last)
&& !duration.is_zero()
&& duration < self.min_duration.unwrap_or(Timestamp::MAX)
{
self.min_duration = Some(duration);
}
self.report()
}
pub fn observe_reorder(&mut self, reorder: Timestamp) -> Option<moq_net::Time> {
self.max_reorder = self.max_reorder.max(reorder);
self.report()
}
pub fn current(&self) -> Option<moq_net::Time> {
let jitter = self.combined();
(!jitter.is_zero()).then(|| jitter.convert().ok()).flatten()
}
fn combined(&self) -> Timestamp {
self.min_duration.unwrap_or(Timestamp::ZERO).max(self.max_reorder)
}
fn report(&mut self) -> Option<moq_net::Time> {
let jitter = self.combined();
if jitter.is_zero() || self.reported == Some(jitter) {
return None;
}
self.reported = Some(jitter);
jitter.convert().ok()
}
}