use std::time::Duration;
use crate::{
Error, Result,
video::{VideoFrameTiming, VideoTimeBase},
};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct MediaTimestamp(u64);
impl MediaTimestamp {
pub const fn from_microseconds(value: u64) -> Self {
Self(value)
}
pub const fn as_microseconds(self) -> u64 {
self.0
}
pub fn has_reached(self, boundary: Duration) -> bool {
boundary <= Duration::from_micros(self.0)
}
pub fn frame_is_due(self, timing: VideoFrameTiming) -> Result<bool> {
let duration = timing.duration().ok_or_else(|| {
Error::missing_capability("MediaPlayer requires known video frame durations")
})?;
let next_boundary = timing
.presentation_timestamp()
.checked_add(duration)
.ok_or_else(|| Error::out_of_range("video presentation time overflowed"))?;
Ok(self.has_reached(next_boundary))
}
pub fn to_video_ticks(self, base: VideoTimeBase) -> Result<u64> {
let ticks = u128::from(self.0) * u128::from(base.denominator())
/ (u128::from(base.numerator()) * 1_000_000);
u64::try_from(ticks).map_err(|_| Error::out_of_range("media timestamp exceeds video time base"))
}
}