1use std::time::Duration;
9
10use broadcast_common::impl_spec_display;
11
12use crate::error::Unsupported;
13use crate::timing::utc_timing::UtcScheme;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
17#[non_exhaustive]
18pub enum PresentationType {
19 #[default]
21 Static,
22 Dynamic,
24}
25
26impl PresentationType {
27 #[must_use]
29 pub fn name(&self) -> &'static str {
30 match self {
31 Self::Static => "static",
32 Self::Dynamic => "dynamic",
33 }
34 }
35}
36impl_spec_display!(PresentationType);
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
40#[non_exhaustive]
41pub enum Actuate {
42 OnLoad,
44 #[default]
46 OnRequest,
47}
48
49impl Actuate {
50 #[must_use]
52 pub fn name(&self) -> &'static str {
53 match self {
54 Self::OnLoad => "onLoad",
55 Self::OnRequest => "onRequest",
56 }
57 }
58}
59impl_spec_display!(Actuate);
60
61#[derive(Debug, Clone, PartialEq, Eq)]
63#[non_exhaustive]
64pub struct Xlink {
65 pub href: String,
67 pub actuate: Actuate,
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq)]
73#[non_exhaustive]
74pub struct ByteRange {
75 pub first: u64,
77 pub last: Option<u64>,
79}
80
81impl ByteRange {
82 #[must_use]
84 pub fn new(first: u64, last: u64) -> Self {
85 Self {
86 first,
87 last: Some(last),
88 }
89 }
90
91 #[must_use]
93 pub fn len(&self) -> Option<u64> {
94 let last = self.last?;
95 last.checked_sub(self.first)?.checked_add(1)
96 }
97
98 #[must_use]
100 pub fn is_empty(&self) -> bool {
101 self.len().is_none()
102 }
103
104 pub fn offset_len(&self) -> Result<(u64, u64), Unsupported> {
110 self.len()
111 .map(|n| (self.first, n))
112 .ok_or(Unsupported::OpenEndedRange)
113 }
114}
115
116#[derive(Debug, Clone, PartialEq, Eq, Default)]
118#[non_exhaustive]
119pub struct UrlType {
120 pub source_url: Option<String>,
122 pub range: Option<ByteRange>,
124}
125
126#[derive(Debug, Clone, PartialEq, Default)]
128#[non_exhaustive]
129pub struct BaseUrl {
130 pub url: String,
132 pub service_location: Option<String>,
134 pub priority: Option<u32>,
136 pub weight: Option<u32>,
138 pub availability_time_offset: Option<f64>,
140 pub availability_time_complete: Option<bool>,
142 pub time_shift_buffer_depth: Option<Duration>,
144}
145
146#[derive(Debug, Clone, PartialEq, Eq, Default)]
149#[non_exhaustive]
150pub struct Descriptor {
151 pub scheme_id_uri: String,
153 pub value: Option<String>,
155 pub id: Option<String>,
157 pub default_kid: Option<String>,
159 pub url_query: Option<UrlQueryInfo>,
161}
162
163#[derive(Debug, Clone, PartialEq, Eq, Default)]
165#[non_exhaustive]
166pub struct UrlQueryInfo {
167 pub use_mpd_url_query: bool,
169 pub query_string: Option<String>,
171 pub query_template: Option<String>,
174}
175
176#[derive(Debug, Clone, PartialEq, Eq)]
178#[non_exhaustive]
179pub struct UtcTiming {
180 pub scheme: UtcScheme,
182 pub scheme_id_uri: String,
184 pub value: String,
186 pub id: Option<String>,
188}
189
190impl UtcTiming {
191 pub fn values(&self) -> impl Iterator<Item = &str> {
193 self.value.split_ascii_whitespace()
194 }
195}
196
197#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
199#[non_exhaustive]
200pub struct MpdFeatures {
201 pub patch_location: bool,
203 pub event_stream: bool,
205 pub inband_event_stream: bool,
207 pub preselection: bool,
209 pub service_description: bool,
211 pub producer_reference_time: bool,
213 pub content_steering: bool,
215 pub resync: bool,
217 pub low_latency: bool,
220 pub xlink_resolve_to_zero: bool,
223}
224
225#[derive(Debug, Clone, PartialEq, Default)]
228#[non_exhaustive]
229pub struct CommonAttributes {
230 pub profiles: Option<String>,
232 pub width: Option<u32>,
234 pub height: Option<u32>,
236 pub sar: Option<String>,
238 pub frame_rate: Option<String>,
240 pub audio_sampling_rate: Option<String>,
242 pub mime_type: Option<String>,
244 pub codecs: Option<String>,
246 pub max_playout_rate: Option<f64>,
248}
249
250#[derive(Debug, Clone, PartialEq, Default)]
252#[non_exhaustive]
253pub struct BaseInfo {
254 pub timescale: Option<u64>,
256 pub presentation_time_offset: Option<u64>,
258 pub ept_delta: Option<i64>,
260 pub pd_delta: Option<i64>,
262 pub presentation_duration: Option<u64>,
264 pub time_shift_buffer_depth: Option<Duration>,
266 pub index_range: Option<ByteRange>,
268 pub index_range_exact: Option<bool>,
270 pub availability_time_offset: Option<f64>,
272 pub availability_time_complete: Option<bool>,
274 pub initialization: Option<UrlType>,
276 pub representation_index: Option<UrlType>,
278}
279
280#[derive(Debug, Clone, PartialEq, Default)]
282#[non_exhaustive]
283pub struct SegmentBase {
284 pub info: BaseInfo,
286}
287
288#[derive(Debug, Clone, Copy, PartialEq, Eq)]
290#[non_exhaustive]
291pub struct TimelineEntry {
292 pub t: Option<u64>,
294 pub n: Option<u64>,
296 pub d: u64,
298 pub r: i64,
300 pub k: Option<u64>,
302}
303
304impl TimelineEntry {
305 #[must_use]
307 pub fn new(d: u64) -> Self {
308 Self {
309 t: None,
310 n: None,
311 d,
312 r: 0,
313 k: None,
314 }
315 }
316}
317
318#[derive(Debug, Clone, PartialEq, Eq, Default)]
320#[non_exhaustive]
321pub struct SegmentTimeline {
322 pub entries: Vec<TimelineEntry>,
324 pub unsupported: Option<Unsupported>,
327}
328
329#[derive(Debug, Clone, PartialEq, Default)]
331#[non_exhaustive]
332pub struct MultiInfo {
333 pub base: BaseInfo,
335 pub duration: Option<u64>,
337 pub start_number: Option<u64>,
339 pub end_number: Option<u64>,
341 pub timeline: Option<SegmentTimeline>,
343 pub bitstream_switching: Option<UrlType>,
345}
346
347#[derive(Debug, Clone, PartialEq, Default)]
349#[non_exhaustive]
350pub struct SegmentTemplate {
351 pub multi: MultiInfo,
353 pub media: Option<String>,
355 pub index: Option<String>,
357 pub initialization: Option<String>,
359 pub bitstream_switching: Option<String>,
361}
362
363#[derive(Debug, Clone, PartialEq, Eq, Default)]
365#[non_exhaustive]
366pub struct SegmentUrl {
367 pub media: Option<String>,
369 pub media_range: Option<ByteRange>,
371 pub index: Option<String>,
373 pub index_range: Option<ByteRange>,
375}
376
377#[derive(Debug, Clone, PartialEq, Default)]
379#[non_exhaustive]
380pub struct SegmentList {
381 pub multi: MultiInfo,
383 pub xlink: Option<Xlink>,
385 pub urls: Vec<SegmentUrl>,
387}
388
389#[derive(Debug, Clone, PartialEq, Default)]
392#[non_exhaustive]
393pub struct SegmentLayer {
394 pub base: Option<SegmentBase>,
396 pub list: Option<SegmentList>,
398 pub template: Option<SegmentTemplate>,
400}
401
402#[derive(Debug, Clone, PartialEq, Default)]
404#[non_exhaustive]
405pub struct Representation {
406 pub id: String,
408 pub bandwidth: u64,
410 pub quality_ranking: Option<u32>,
412 pub dependency_ids: Vec<String>,
414 pub common: CommonAttributes,
416 pub base_urls: Vec<BaseUrl>,
418 pub segment: SegmentLayer,
420 pub content_protections: Vec<Descriptor>,
422 pub essential_properties: Vec<Descriptor>,
424 pub supplemental_properties: Vec<Descriptor>,
426 pub audio_channel_configurations: Vec<Descriptor>,
428}
429
430#[derive(Debug, Clone, PartialEq, Default)]
432#[non_exhaustive]
433pub struct AdaptationSet {
434 pub id: Option<u64>,
436 pub group: Option<u64>,
438 pub lang: Option<String>,
440 pub content_type: Option<String>,
442 pub par: Option<String>,
444 pub segment_alignment: bool,
446 pub start_with_sap: Option<u8>,
448 pub bitstream_switching: Option<bool>,
450 pub common: CommonAttributes,
452 pub xlink: Option<Xlink>,
454 pub roles: Vec<Descriptor>,
456 pub accessibilities: Vec<Descriptor>,
458 pub labels: Vec<String>,
460 pub base_urls: Vec<BaseUrl>,
462 pub segment: SegmentLayer,
464 pub content_protections: Vec<Descriptor>,
466 pub essential_properties: Vec<Descriptor>,
468 pub supplemental_properties: Vec<Descriptor>,
470 pub audio_channel_configurations: Vec<Descriptor>,
472 pub representations: Vec<Representation>,
474}
475
476#[derive(Debug, Clone, PartialEq, Default)]
478#[non_exhaustive]
479pub struct Period {
480 pub id: Option<String>,
482 pub start: Option<Duration>,
484 pub duration: Option<Duration>,
486 pub bitstream_switching: bool,
488 pub xlink: Option<Xlink>,
490 pub base_urls: Vec<BaseUrl>,
492 pub segment: SegmentLayer,
494 pub asset_identifier: Option<Descriptor>,
496 pub essential_properties: Vec<Descriptor>,
498 pub supplemental_properties: Vec<Descriptor>,
500 pub adaptation_sets: Vec<AdaptationSet>,
502}
503
504#[derive(Debug, Clone, PartialEq, Default)]
506#[non_exhaustive]
507pub struct Mpd {
508 pub id: Option<String>,
510 pub profiles: Vec<String>,
512 pub kind: PresentationType,
514 pub availability_start_time_us: Option<i64>,
516 pub availability_end_time_us: Option<i64>,
518 pub publish_time_us: Option<i64>,
520 pub media_presentation_duration: Option<Duration>,
522 pub minimum_update_period: Option<Duration>,
524 pub min_buffer_time: Option<Duration>,
526 pub time_shift_buffer_depth: Option<Duration>,
528 pub suggested_presentation_delay: Option<Duration>,
530 pub max_segment_duration: Option<Duration>,
532 pub max_subsegment_duration: Option<Duration>,
534 pub base_urls: Vec<BaseUrl>,
536 pub locations: Vec<String>,
538 pub utc_timings: Vec<UtcTiming>,
541 pub essential_properties: Vec<Descriptor>,
543 pub supplemental_properties: Vec<Descriptor>,
545 pub periods: Vec<Period>,
547 pub features: MpdFeatures,
549}