scuffle_mp4/object_description/
es.rs1use isobmff::IsoSized;
2use scuffle_bytes_util::zero_copy::{Deserialize, DeserializeSeed, Serialize, ZeroCopyReader};
3use scuffle_bytes_util::{BitWriter, IoResultExt, StringCow};
4
5use super::decoder_config::DecoderConfigDescriptor;
6use super::sl_config::SLConfigDescriptor;
7use super::{BaseDescriptor, DescriptorTag, UnknownDescriptor};
8
9#[derive(Debug, PartialEq, Eq)]
13pub struct ESDescriptor<'a> {
14 pub es_id: u16,
17 pub stream_priority: u8,
21 pub depends_on_es_id: Option<u16>,
25 pub url_string: Option<StringCow<'a>>,
30 pub ocr_es_id: Option<u16>,
34 pub dec_config_descr: DecoderConfigDescriptor<'a>,
36 pub sl_config_descr: Option<SLConfigDescriptor>, pub unknown_descriptors: Vec<UnknownDescriptor<'a>>,
49}
50
51impl ESDescriptor<'_> {
52 pub fn base_descriptor(&self) -> BaseDescriptor {
54 BaseDescriptor {
55 tag: DescriptorTag::ES_DescrTag,
56 size_of_instance: self.payload_size() as u32,
57 }
58 }
59
60 fn payload_size(&self) -> usize {
61 let mut size = 0;
62 size += self.es_id.size(); size += 1; size += self.depends_on_es_id.size();
66
67 if let Some(url_string) = self.url_string.as_ref() {
68 size += 1; size += url_string.size();
70 }
71
72 size += self.ocr_es_id.size();
73 size += self.dec_config_descr.size();
74 size += self.sl_config_descr.size();
75 size += self.unknown_descriptors.size();
76
77 size
78 }
79}
80
81impl<'a> Deserialize<'a> for ESDescriptor<'a> {
82 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
83 where
84 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
85 {
86 let base_descriptor = BaseDescriptor::deserialize(&mut reader)?;
87 let mut reader = reader.take(base_descriptor.size_of_instance as usize);
88
89 let es_id = u16::deserialize(&mut reader)?;
90
91 let byte = u8::deserialize(&mut reader)?;
92 let stream_dependence_flag = (byte & 0b1000_0000) != 0;
93 let url_flag = (byte & 0b0100_0000) != 0;
94 let ocr_stream_flag = (byte & 0b0010_0000) != 0;
95 let stream_priority = byte & 0b0001_1111;
96
97 let depends_on_es_id = if stream_dependence_flag {
98 Some(u16::deserialize(&mut reader)?)
99 } else {
100 None
101 };
102
103 let url_string = if url_flag {
104 let url_length = u8::deserialize(&mut reader)?;
105 let url_string = reader.try_read(url_length as usize)?;
106 Some(url_string.try_into().map_err(|e| {
107 std::io::Error::new(std::io::ErrorKind::InvalidData, format!("URLString must be valid UTF-8: {e}"))
108 })?)
109 } else {
110 None
111 };
112
113 let ocr_es_id = if ocr_stream_flag {
114 Some(u16::deserialize(&mut reader)?)
115 } else {
116 None
117 };
118
119 let dec_config_descr = DecoderConfigDescriptor::deserialize(&mut reader)?;
120 let sl_config_descr = SLConfigDescriptor::deserialize(&mut reader).eof_to_none()?;
121
122 let mut unknown_descriptors = Vec::new();
123
124 loop {
125 let Some(base_descriptor) = BaseDescriptor::deserialize(&mut reader).eof_to_none()? else {
126 break;
127 };
128
129 let Some(descr) = UnknownDescriptor::deserialize_seed(&mut reader, base_descriptor).eof_to_none()? else {
130 break;
131 };
132 unknown_descriptors.push(descr);
133 }
134
135 Ok(Self {
136 es_id,
137 stream_priority,
138 depends_on_es_id,
139 url_string,
140 ocr_es_id,
141 dec_config_descr,
142 sl_config_descr,
143 unknown_descriptors,
144 })
145 }
146}
147
148impl Serialize for ESDescriptor<'_> {
149 fn serialize<W>(&self, writer: W) -> std::io::Result<()>
150 where
151 W: std::io::Write,
152 {
153 let mut bit_writer = BitWriter::new(writer);
154
155 self.base_descriptor().serialize(&mut bit_writer)?;
156 self.es_id.serialize(&mut bit_writer)?;
157 bit_writer.write_bit(self.depends_on_es_id.is_some())?;
158 bit_writer.write_bit(self.url_string.is_some())?;
159 bit_writer.write_bit(self.ocr_es_id.is_some())?;
160 bit_writer.write_bits(self.stream_priority as u64, 5)?;
161
162 if let Some(depends_on_es_id) = self.depends_on_es_id {
163 depends_on_es_id.serialize(&mut bit_writer)?;
164 }
165
166 if let Some(url_string) = &self.url_string {
167 let url_length = url_string.len() as u8;
168 url_length.serialize(&mut bit_writer)?;
169 url_string.serialize(&mut bit_writer)?;
170 }
171
172 if let Some(ocr_es_id) = self.ocr_es_id {
173 ocr_es_id.serialize(&mut bit_writer)?;
174 }
175
176 self.dec_config_descr.serialize(&mut bit_writer)?;
177
178 if let Some(sl_config_descr) = &self.sl_config_descr {
179 sl_config_descr.serialize(&mut bit_writer)?;
180 }
181
182 for unknown_descriptor in &self.unknown_descriptors {
183 unknown_descriptor.serialize(&mut bit_writer)?;
184 }
185
186 Ok(())
187 }
188}
189
190impl IsoSized for ESDescriptor<'_> {
191 fn size(&self) -> usize {
192 self.base_descriptor().size() + self.payload_size()
193 }
194}