const MICROS_PER_SECOND: i128 = 1_000_000;
const MICROS_PER_SECOND_F64: f64 = 1_000_000.0;
const ATO_CLAMP_US: i128 = 1 << 80;
#[must_use]
pub fn ato_seconds_to_us(seconds: f64) -> i128 {
let us = seconds * MICROS_PER_SECOND_F64;
(us as i128).clamp(-ATO_CLAMP_US, ATO_CLAMP_US)
}
#[must_use]
pub fn ticks_to_us(ticks: i128, timescale: u64) -> i128 {
ticks
.saturating_mul(MICROS_PER_SECOND)
.div_euclid(i128::from(timescale.max(1)))
}
#[must_use]
pub fn segment_available_from_ticks(
ast_us: i128,
period_start_us: i128,
start_ticks: i128,
duration_ticks: i128,
timescale: u64,
ato_us: i128,
) -> i128 {
segment_available_from(
ast_us,
period_start_us,
ticks_to_us(start_ticks.saturating_add(duration_ticks), timescale),
0,
ato_us,
)
}
#[must_use]
pub fn segment_available_until_ticks(
ast_us: i128,
period_start_us: i128,
start_ticks: i128,
duration_ticks: i128,
timescale: u64,
tsb_us: Option<i128>,
) -> Option<i128> {
let end2 = start_ticks.saturating_add(duration_ticks.saturating_mul(2));
segment_available_until(
ast_us,
period_start_us,
ticks_to_us(end2, timescale),
0,
tsb_us,
)
}
#[must_use]
pub fn segment_available_from(
ast_us: i128,
period_start_us: i128,
mpd_start_us: i128,
mpd_duration_us: i128,
ato_us: i128,
) -> i128 {
ast_us
.saturating_add(period_start_us)
.saturating_add(mpd_start_us)
.saturating_add(mpd_duration_us)
.saturating_sub(ato_us)
}
#[must_use]
pub fn segment_available_until(
ast_us: i128,
period_start_us: i128,
mpd_start_us: i128,
mpd_duration_us: i128,
tsb_us: Option<i128>,
) -> Option<i128> {
tsb_us.map(|tsb| {
ast_us
.saturating_add(period_start_us)
.saturating_add(mpd_start_us)
.saturating_add(mpd_duration_us.saturating_mul(2))
.saturating_add(tsb)
})
}
#[must_use]
pub fn init_available_from(ast_us: i128, period_start_us: i128) -> i128 {
ast_us.saturating_add(period_start_us)
}
#[must_use]
pub fn complete_count_constant(
utc_us: i128,
ast_us: i128,
period_start_us: i128,
ato_us: i128,
duration_ticks: u64,
timescale: u64,
) -> u64 {
if duration_ticks == 0 || timescale == 0 {
return 0;
}
let x = utc_us
.saturating_sub(ast_us)
.saturating_sub(period_start_us)
.saturating_add(ato_us);
let x1 = x.saturating_add(1);
if x1 <= 0 {
return 0;
}
let numerator = x1.saturating_mul(i128::from(timescale)).saturating_sub(1);
let denominator = i128::from(duration_ticks).saturating_mul(MICROS_PER_SECOND);
let n = numerator / denominator;
u64::try_from(n.max(0)).unwrap_or(u64::MAX)
}