use std::sync::{Mutex, OnceLock}; use std::time::{Duration, Instant}; fn capture_clock_origin() -> &'static Instant { static ORIGIN: OnceLock = OnceLock::new(); ORIGIN.get_or_init(Instant::now) } pub fn capture_pts_us() -> u64 { capture_clock_origin().elapsed().as_micros() as u64 } pub fn upstream_timing_trace_enabled() -> bool { std::env::var("LESAVKA_UPSTREAM_TIMING_TRACE") .ok() .map(|value| { let trimmed = value.trim(); !(trimmed.eq_ignore_ascii_case("0") || trimmed.eq_ignore_ascii_case("false") || trimmed.eq_ignore_ascii_case("no") || trimmed.eq_ignore_ascii_case("off")) }) .unwrap_or(false) } #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct RebasedSourcePts { pub packet_pts_us: u64, pub capture_now_us: u64, pub source_pts_us: Option, pub source_base_us: Option, pub capture_base_us: Option, pub used_source_pts: bool, } #[derive(Debug, Default)] struct SourcePtsRebaserState { source_base_us: Option, capture_base_us: Option, last_packet_pts_us: Option, } #[derive(Debug, Default)] pub struct SourcePtsRebaser { state: Mutex, } impl SourcePtsRebaser { pub fn rebase_or_now(&self, source_pts_us: Option, min_step_us: u64) -> RebasedSourcePts { let capture_now_us = capture_pts_us(); let mut state = self .state .lock() .expect("source pts rebaser mutex poisoned"); let mut packet_pts_us = capture_now_us; let mut used_source_pts = false; if let Some(source_pts_us) = source_pts_us { let source_base_us = *state.source_base_us.get_or_insert(source_pts_us); let capture_base_us = *state.capture_base_us.get_or_insert(capture_now_us); packet_pts_us = capture_base_us.saturating_add(source_pts_us.saturating_sub(source_base_us)); used_source_pts = true; } if let Some(last_packet_pts_us) = state.last_packet_pts_us && packet_pts_us <= last_packet_pts_us { packet_pts_us = last_packet_pts_us.saturating_add(min_step_us.max(1)); } state.last_packet_pts_us = Some(packet_pts_us); RebasedSourcePts { packet_pts_us, capture_now_us, source_pts_us, source_base_us: state.source_base_us, capture_base_us: state.capture_base_us, used_source_pts, } } }