dash_runtime/timing/
availability.rs1use broadcast_common::timescale::{Rounding, to_micros};
12
13const MICROS_PER_SECOND_U32: u32 = 1_000_000;
14const MICROS_PER_SECOND: i128 = MICROS_PER_SECOND_U32 as i128;
15const MICROS_PER_SECOND_F64: f64 = 1_000_000.0;
16const ATO_CLAMP_US: i128 = 1 << 80;
17
18#[must_use]
21pub fn ato_seconds_to_us(seconds: f64) -> i128 {
22 let us = seconds * MICROS_PER_SECOND_F64;
23 (us as i128).clamp(-ATO_CLAMP_US, ATO_CLAMP_US)
24}
25
26#[must_use]
28pub fn ticks_to_us(ticks: i128, timescale: u64) -> i128 {
29 to_micros(ticks, timescale, Rounding::Floor)
30}
31
32#[must_use]
36pub fn segment_available_from_ticks(
37 ast_us: i128,
38 period_start_us: i128,
39 start_ticks: i128,
40 duration_ticks: i128,
41 timescale: u64,
42 ato_us: i128,
43) -> i128 {
44 segment_available_from(
45 ast_us,
46 period_start_us,
47 ticks_to_us(start_ticks.saturating_add(duration_ticks), timescale),
48 0,
49 ato_us,
50 )
51}
52
53#[must_use]
55pub fn segment_available_until_ticks(
56 ast_us: i128,
57 period_start_us: i128,
58 start_ticks: i128,
59 duration_ticks: i128,
60 timescale: u64,
61 tsb_us: Option<i128>,
62) -> Option<i128> {
63 let end2 = start_ticks.saturating_add(duration_ticks.saturating_mul(2));
64 segment_available_until(
65 ast_us,
66 period_start_us,
67 ticks_to_us(end2, timescale),
68 0,
69 tsb_us,
70 )
71}
72
73#[must_use]
75pub fn segment_available_from(
76 ast_us: i128,
77 period_start_us: i128,
78 mpd_start_us: i128,
79 mpd_duration_us: i128,
80 ato_us: i128,
81) -> i128 {
82 ast_us
83 .saturating_add(period_start_us)
84 .saturating_add(mpd_start_us)
85 .saturating_add(mpd_duration_us)
86 .saturating_sub(ato_us)
87}
88
89#[must_use]
92pub fn segment_available_until(
93 ast_us: i128,
94 period_start_us: i128,
95 mpd_start_us: i128,
96 mpd_duration_us: i128,
97 tsb_us: Option<i128>,
98) -> Option<i128> {
99 tsb_us.map(|tsb| {
100 ast_us
101 .saturating_add(period_start_us)
102 .saturating_add(mpd_start_us)
103 .saturating_add(mpd_duration_us.saturating_mul(2))
104 .saturating_add(tsb)
105 })
106}
107
108#[must_use]
110pub fn init_available_from(ast_us: i128, period_start_us: i128) -> i128 {
111 ast_us.saturating_add(period_start_us)
112}
113
114#[must_use]
119pub fn complete_count_constant(
120 utc_us: i128,
121 ast_us: i128,
122 period_start_us: i128,
123 ato_us: i128,
124 duration_ticks: u64,
125 timescale: u64,
126) -> u64 {
127 if duration_ticks == 0 || timescale == 0 {
128 return 0;
129 }
130 let x = utc_us
131 .saturating_sub(ast_us)
132 .saturating_sub(period_start_us)
133 .saturating_add(ato_us);
134 let x1 = x.saturating_add(1);
135 if x1 <= 0 {
136 return 0;
137 }
138 let numerator = x1.saturating_mul(i128::from(timescale)).saturating_sub(1);
139 let denominator = i128::from(duration_ticks).saturating_mul(MICROS_PER_SECOND);
140 let n = numerator / denominator;
141 u64::try_from(n.max(0)).unwrap_or(u64::MAX)
142}