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