1use scuffle_bytes_util::BitWriter;
2use scuffle_bytes_util::zero_copy::{Deserialize, DeserializeSeed, Serialize, U24Be};
3
4use super::Brand;
5use crate::{BoxHeader, FullBoxHeader, IsoBox, IsoSized};
6
7#[derive(IsoBox, Debug, PartialEq, Eq)]
11#[iso_box(box_type = b"styp", crate_path = crate)]
12pub struct SegmentTypeBox {
13 #[iso_box(from = "[u8; 4]")]
15 pub major_brand: Brand,
16 pub minor_version: u32,
18 #[iso_box(repeated, from = "[u8; 4]")]
20 pub compatible_brands: Vec<Brand>,
21}
22
23#[derive(IsoBox, Debug, PartialEq, Eq)]
27#[iso_box(box_type = b"sidx", skip_impl(deserialize_seed, serialize, sized), crate_path = crate)]
28pub struct SegmentIndexBox {
29 pub full_header: FullBoxHeader,
31 pub reference_id: u32,
35 pub timescale: u32,
39 pub earliest_presentation_time: u64,
44 pub first_offset: u64,
47 pub reserved: u16,
49 pub reference_count: u16,
51 pub references: Vec<SegmentIndexBoxReference>,
53}
54
55impl<'a> DeserializeSeed<'a, BoxHeader> for SegmentIndexBox {
56 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> std::io::Result<Self>
57 where
58 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
59 {
60 let full_header = FullBoxHeader::deserialize(&mut reader)?;
61
62 let reference_id = u32::deserialize(&mut reader)?;
63 let timescale = u32::deserialize(&mut reader)?;
64
65 let earliest_presentation_time = if full_header.version == 0 {
66 u32::deserialize(&mut reader)? as u64
67 } else {
68 u64::deserialize(&mut reader)?
69 };
70 let first_offset = if full_header.version == 0 {
71 u32::deserialize(&mut reader)? as u64
72 } else {
73 u64::deserialize(&mut reader)?
74 };
75
76 let reserved = u16::deserialize(&mut reader)?;
77 let reference_count = u16::deserialize(&mut reader)?;
78
79 let mut references = Vec::with_capacity(reference_count as usize);
80 for _ in 0..reference_count {
81 references.push(SegmentIndexBoxReference::deserialize(&mut reader)?);
82 }
83
84 Ok(SegmentIndexBox {
85 full_header,
86 reference_id,
87 timescale,
88 earliest_presentation_time,
89 first_offset,
90 reserved,
91 reference_count,
92 references,
93 })
94 }
95}
96
97impl Serialize for SegmentIndexBox {
98 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
99 where
100 W: std::io::Write,
101 {
102 self.serialize_box_header(&mut writer)?;
103 self.full_header.serialize(&mut writer)?;
104
105 self.reference_id.serialize(&mut writer)?;
106 self.timescale.serialize(&mut writer)?;
107
108 if self.full_header.version == 0 {
109 (self.earliest_presentation_time as u32).serialize(&mut writer)?;
110 (self.first_offset as u32).serialize(&mut writer)?;
111 } else {
112 self.earliest_presentation_time.serialize(&mut writer)?;
113 self.first_offset.serialize(&mut writer)?;
114 }
115
116 self.reserved.serialize(&mut writer)?;
117 self.reference_count.serialize(&mut writer)?;
118
119 for reference in &self.references {
120 reference.serialize(&mut writer)?;
121 }
122
123 Ok(())
124 }
125}
126
127impl IsoSized for SegmentIndexBox {
128 fn size(&self) -> usize {
129 let mut size = self.full_header.size();
130 size += 4; size += 4; if self.full_header.version == 0 {
133 size += 4; size += 4; } else {
136 size += 8; size += 8; }
139 size += 2; size += 2; size += self.references.size();
143
144 Self::add_header_size(size)
145 }
146}
147
148#[derive(Debug, PartialEq, Eq)]
150pub struct SegmentIndexBoxReference {
151 pub reference_type: bool,
157 pub referenced_size: u32,
160 pub subsegment_duration: u32,
168 pub starts_with_sap: bool,
171 pub sap_type: u8,
174 pub sap_delta_time: u32,
180}
181
182impl<'a> Deserialize<'a> for SegmentIndexBoxReference {
183 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
184 where
185 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
186 {
187 let first_u32 = u32::deserialize(&mut reader)?;
188 let reference_type = (first_u32 >> 31) != 0;
189 let referenced_size = first_u32 & 0x7F_FF_FF_FF;
190
191 let subsegment_duration = u32::deserialize(&mut reader)?;
192
193 let third_u32 = u32::deserialize(&mut reader)?;
194 let starts_with_sap = (third_u32 >> 31) != 0;
195 let sap_type = ((third_u32 >> 28) & 0b111) as u8;
196 let sap_delta_time = third_u32 & 0x0F_FF_FF_FF;
197
198 Ok(SegmentIndexBoxReference {
199 reference_type,
200 referenced_size,
201 subsegment_duration,
202 starts_with_sap,
203 sap_type,
204 sap_delta_time,
205 })
206 }
207}
208
209impl Serialize for SegmentIndexBoxReference {
210 fn serialize<W>(&self, writer: W) -> std::io::Result<()>
211 where
212 W: std::io::Write,
213 {
214 let mut bit_writer = BitWriter::new(writer);
215
216 bit_writer.write_bit(self.reference_type)?;
217 bit_writer.write_bits(self.referenced_size as u64, 31)?;
218
219 self.subsegment_duration.serialize(&mut bit_writer)?;
220
221 bit_writer.write_bit(self.starts_with_sap)?;
222 bit_writer.write_bits(self.sap_type as u64, 3)?;
223 bit_writer.write_bits(self.sap_delta_time as u64, 28)?;
224
225 Ok(())
226 }
227}
228
229impl IsoSized for SegmentIndexBoxReference {
230 fn size(&self) -> usize {
231 4 + 4 + 4 }
233}
234
235#[derive(IsoBox, Debug, PartialEq, Eq)]
239#[iso_box(box_type = b"ssix", crate_path = crate)]
240pub struct SubsegmentIndexBox {
241 pub full_header: FullBoxHeader,
243 pub subsegment_count: u32,
247 #[iso_box(repeated)]
249 pub subsegments: Vec<SubsegmentIndexBoxSubsegment>,
250}
251
252#[derive(Debug, PartialEq, Eq)]
254pub struct SubsegmentIndexBoxSubsegment {
255 pub range_count: u32,
258 pub ranges: Vec<SubsegmentIndexBoxSubsegmentRange>,
260}
261
262impl<'a> Deserialize<'a> for SubsegmentIndexBoxSubsegment {
263 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
264 where
265 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
266 {
267 let range_count = u32::deserialize(&mut reader)?;
268 let mut ranges = Vec::with_capacity(range_count as usize);
269 for _ in 0..range_count {
270 ranges.push(SubsegmentIndexBoxSubsegmentRange::deserialize(&mut reader)?);
271 }
272
273 Ok(SubsegmentIndexBoxSubsegment { range_count, ranges })
274 }
275}
276
277impl Serialize for SubsegmentIndexBoxSubsegment {
278 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
279 where
280 W: std::io::Write,
281 {
282 self.range_count.serialize(&mut writer)?;
283
284 for range in &self.ranges {
285 range.serialize(&mut writer)?;
286 }
287
288 Ok(())
289 }
290}
291
292impl IsoSized for SubsegmentIndexBoxSubsegment {
293 fn size(&self) -> usize {
294 self.range_count.size() + self.ranges.size()
295 }
296}
297
298#[derive(Debug, PartialEq, Eq)]
300pub struct SubsegmentIndexBoxSubsegmentRange {
301 pub level: u8,
303 pub range_size: U24Be,
306}
307
308impl<'a> Deserialize<'a> for SubsegmentIndexBoxSubsegmentRange {
309 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
310 where
311 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
312 {
313 let level = u8::deserialize(&mut reader)?;
314 let range_size = U24Be::deserialize(&mut reader)?;
315
316 Ok(SubsegmentIndexBoxSubsegmentRange { level, range_size })
317 }
318}
319
320impl Serialize for SubsegmentIndexBoxSubsegmentRange {
321 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
322 where
323 W: std::io::Write,
324 {
325 self.level.serialize(&mut writer)?;
326 self.range_size.serialize(&mut writer)?;
327 Ok(())
328 }
329}
330
331impl IsoSized for SubsegmentIndexBoxSubsegmentRange {
332 fn size(&self) -> usize {
333 self.level.size() + self.range_size.size()
334 }
335}
336
337#[derive(IsoBox, Debug, PartialEq, Eq)]
341#[iso_box(box_type = b"prft", skip_impl(deserialize_seed, serialize, sized), crate_path = crate)]
342pub struct ProducerReferenceTimeBox {
343 pub full_header: FullBoxHeader,
345 pub reference_track_id: u32,
347 pub ntp_timestamp: u64,
367 pub media_time: u64,
369}
370
371impl<'a> DeserializeSeed<'a, BoxHeader> for ProducerReferenceTimeBox {
372 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> std::io::Result<Self>
373 where
374 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
375 {
376 let full_header = FullBoxHeader::deserialize(&mut reader)?;
377
378 let reference_track_id = u32::deserialize(&mut reader)?;
379 let ntp_timestamp = u64::deserialize(&mut reader)?;
380 let media_time = if full_header.version == 0 {
381 u32::deserialize(&mut reader)? as u64
382 } else {
383 u64::deserialize(&mut reader)?
384 };
385
386 Ok(ProducerReferenceTimeBox {
387 full_header,
388 reference_track_id,
389 ntp_timestamp,
390 media_time,
391 })
392 }
393}
394
395impl Serialize for ProducerReferenceTimeBox {
396 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
397 where
398 W: std::io::Write,
399 {
400 self.serialize_box_header(&mut writer)?;
401 self.full_header.serialize(&mut writer)?;
402
403 self.reference_track_id.serialize(&mut writer)?;
404 self.ntp_timestamp.serialize(&mut writer)?;
405 if self.full_header.version == 0 {
406 (self.media_time as u32).serialize(&mut writer)?;
407 } else {
408 self.media_time.serialize(&mut writer)?;
409 }
410 Ok(())
411 }
412}
413
414impl IsoSized for ProducerReferenceTimeBox {
415 fn size(&self) -> usize {
416 let mut size = self.full_header.size();
417 size += 4; size += 8; if self.full_header.version == 0 {
420 size += 4; } else {
422 size += 8; }
424
425 Self::add_header_size(size)
426 }
427}