dash_runtime/mpd/
descriptors.rs1use broadcast_common::impl_spec_display;
8
9use super::model::{Descriptor, UrlQueryInfo};
10
11pub const SCHEME_ROLE: &str = "urn:mpeg:dash:role:2011";
13pub const SCHEME_PERIOD_CONTINUITY: &str = "urn:mpeg:dash:period-continuity:2015";
15pub const SCHEME_PERIOD_CONNECTIVITY: &str = "urn:mpeg:dash:period-connectivity:2015";
17pub const SCHEME_RESET: &str = "urn:mpeg:dash:reset:2016";
19pub const SCHEME_URLPARAM: &str = "urn:mpeg:dash:urlparam:2014";
21pub const SCHEME_URLPARAM_2016: &str = "urn:mpeg:dash:urlparam:2016";
23pub const SCHEME_LAST_SEGMENT_NUMBER: &str = "http://dashif.org/guidelines/last-segment-number";
25pub const XLINK_RESOLVE_TO_ZERO: &str = "urn:mpeg:dash:resolve-to-zero:2013";
27pub const SCHEME_MP4_PROTECTION: &str = "urn:mpeg:dash:mp4protection:2011";
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32#[non_exhaustive]
33pub enum Role {
34 Caption,
36 Subtitle,
38 Main,
40 Alternate,
42 Supplementary,
44 Commentary,
46 Dub,
48 Description,
50 Sign,
52 Metadata,
54 EnhancedAudioIntelligibility,
56 Emergency,
58 ForcedSubtitle,
60 EasyReader,
62 Karaoke,
64 Other,
66}
67
68impl Role {
69 #[must_use]
71 pub fn from_value(value: &str) -> Self {
72 match value {
73 "caption" => Self::Caption,
74 "subtitle" => Self::Subtitle,
75 "main" => Self::Main,
76 "alternate" => Self::Alternate,
77 "supplementary" => Self::Supplementary,
78 "commentary" => Self::Commentary,
79 "dub" => Self::Dub,
80 "description" => Self::Description,
81 "sign" => Self::Sign,
82 "metadata" => Self::Metadata,
83 "enhanced-audio-intelligibility" => Self::EnhancedAudioIntelligibility,
84 "emergency" => Self::Emergency,
85 "forced-subtitle" => Self::ForcedSubtitle,
86 "easyreader" => Self::EasyReader,
87 "karaoke" => Self::Karaoke,
88 _ => Self::Other,
89 }
90 }
91
92 #[must_use]
94 pub fn name(&self) -> &'static str {
95 match self {
96 Self::Caption => "caption",
97 Self::Subtitle => "subtitle",
98 Self::Main => "main",
99 Self::Alternate => "alternate",
100 Self::Supplementary => "supplementary",
101 Self::Commentary => "commentary",
102 Self::Dub => "dub",
103 Self::Description => "description",
104 Self::Sign => "sign",
105 Self::Metadata => "metadata",
106 Self::EnhancedAudioIntelligibility => "enhanced-audio-intelligibility",
107 Self::Emergency => "emergency",
108 Self::ForcedSubtitle => "forced-subtitle",
109 Self::EasyReader => "easyreader",
110 Self::Karaoke => "karaoke",
111 Self::Other => "other",
112 }
113 }
114}
115impl_spec_display!(Role);
116
117pub fn roles(descriptors: &[Descriptor]) -> impl Iterator<Item = Role> + '_ {
119 descriptors
120 .iter()
121 .filter(|d| d.scheme_id_uri == SCHEME_ROLE)
122 .filter_map(|d| d.value.as_deref())
123 .map(Role::from_value)
124}
125
126#[must_use]
128pub fn find<'a>(descriptors: &'a [Descriptor], scheme: &str) -> Option<&'a Descriptor> {
129 descriptors.iter().find(|d| d.scheme_id_uri == scheme)
130}
131
132#[must_use]
134pub fn url_query_info(descriptors: &[Descriptor]) -> Option<&UrlQueryInfo> {
135 descriptors
136 .iter()
137 .filter(|d| d.scheme_id_uri == SCHEME_URLPARAM)
138 .find_map(|d| d.url_query.as_ref())
139}
140
141pub const UNDERSTOOD_ESSENTIAL: &[&str] = &[
145 SCHEME_PERIOD_CONTINUITY,
146 SCHEME_PERIOD_CONNECTIVITY,
147 SCHEME_RESET,
148 SCHEME_URLPARAM,
149 SCHEME_LAST_SEGMENT_NUMBER,
150];
151
152#[must_use]
154pub fn essential_understood(descriptor: &Descriptor) -> bool {
155 UNDERSTOOD_ESSENTIAL.contains(&descriptor.scheme_id_uri.as_str())
156}