Skip to main content

sheathe_core/
time.rs

1//! Media timing primitives.
2//!
3//! All timestamps in sheathe are integers expressed in a per-stream
4//! [`Timescale`] (ticks per second), matching how ISO-BMFF and MPEG-TS carry
5//! time. Avoiding floating point keeps segment boundaries exact.
6
7/// Ticks-per-second for a stream's timeline (e.g. 90_000 for MPEG-TS video).
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub struct Timescale(pub u32);
10
11impl Timescale {
12    /// A common video timescale (90 kHz), as used by MPEG-2 transport streams.
13    pub const MPEG_TS: Timescale = Timescale(90_000);
14
15    /// Convert a duration in this timescale to whole milliseconds (truncating).
16    pub fn to_millis(self, ticks: u64) -> u64 {
17        ticks.saturating_mul(1_000) / u64::from(self.0.max(1))
18    }
19}
20
21/// A value (timestamp or duration) paired with the [`Timescale`] it lives in.
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub struct Scaled {
24    /// The raw tick count.
25    pub ticks: u64,
26    /// The timescale `ticks` are expressed in.
27    pub scale: Timescale,
28}
29
30impl Scaled {
31    /// Pair a tick count with its timescale.
32    pub fn new(ticks: u64, scale: Timescale) -> Self {
33        Self { ticks, scale }
34    }
35
36    /// Seconds as an `f64`, for display only — never for boundary math.
37    pub fn seconds(self) -> f64 {
38        self.ticks as f64 / f64::from(self.scale.0.max(1))
39    }
40}