1use std::io;
2
3use scuffle_bytes_util::zero_copy::{Deserialize, DeserializeSeed, Serialize, ZeroCopyReader};
4use scuffle_bytes_util::{BytesCow, IoResultExt};
5
6use crate::IsoSized;
7
8#[derive(Debug, PartialEq, Eq)]
10pub enum SampleGroupDescriptionEntry<'a> {
11 RollRecovery(RollRecoveryEntry),
13 AudioPreRoll(AudioPreRollEntry),
15 RateShare(RateShareEntry),
17 AlternativeStartup(AlternativeStartupEntry),
19 VisualRandomAccess(VisualRandomAccessEntry),
21 TemporalLevel(TemporalLevelEntry),
23 SAP(SAPEntry),
25 SampleToMetadataItem(SampleToMetadataItemEntry),
27 VisualDRAP(VisualDRAPEntry),
29 PixelAspectRatio(PixelAspectRatioEntry),
31 CleanAperture(CleanApertureEntry),
33 Unknown {
35 grouping_type: [u8; 4],
37 data: BytesCow<'a>,
39 },
40}
41
42impl<'a> DeserializeSeed<'a, ([u8; 4], Option<u32>)> for SampleGroupDescriptionEntry<'a> {
43 fn deserialize_seed<R>(mut reader: R, seed: ([u8; 4], Option<u32>)) -> io::Result<Self>
44 where
45 R: ZeroCopyReader<'a>,
46 {
47 let (grouping_type, length) = seed;
48
49 match &grouping_type {
50 b"roll" => Ok(Self::RollRecovery(RollRecoveryEntry::deserialize(reader)?)),
51 b"prol" => Ok(Self::AudioPreRoll(AudioPreRollEntry::deserialize(reader)?)),
52 b"rash" => Ok(Self::RateShare(RateShareEntry::deserialize(reader)?)),
53 b"alst" => Ok(Self::AlternativeStartup(AlternativeStartupEntry::deserialize(reader)?)),
54 b"rap " => Ok(Self::VisualRandomAccess(VisualRandomAccessEntry::deserialize(reader)?)),
55 b"tele" => Ok(Self::TemporalLevel(TemporalLevelEntry::deserialize(reader)?)),
56 b"sap " => Ok(Self::SAP(SAPEntry::deserialize(reader)?)),
57 b"stmi" => Ok(Self::SampleToMetadataItem(SampleToMetadataItemEntry::deserialize(reader)?)),
58 b"drap" => Ok(Self::VisualDRAP(VisualDRAPEntry::deserialize(reader)?)),
59 b"pasr" => Ok(Self::PixelAspectRatio(PixelAspectRatioEntry::deserialize(reader)?)),
60 b"casg" => Ok(Self::CleanAperture(CleanApertureEntry::deserialize(reader)?)),
61 _ => {
62 let data = if let Some(length) = length {
63 reader.try_read(length as usize)?
64 } else {
65 BytesCow::new()
66 };
67 Ok(Self::Unknown { grouping_type, data })
68 }
69 }
70 }
71}
72
73impl Serialize for SampleGroupDescriptionEntry<'_> {
74 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
75 where
76 W: std::io::Write,
77 {
78 match self {
79 Self::RollRecovery(entry) => entry.serialize(&mut writer),
80 Self::AudioPreRoll(entry) => entry.serialize(&mut writer),
81 Self::RateShare(entry) => entry.serialize(&mut writer),
82 Self::AlternativeStartup(entry) => entry.serialize(&mut writer),
83 Self::VisualRandomAccess(entry) => entry.serialize(&mut writer),
84 Self::TemporalLevel(entry) => entry.serialize(&mut writer),
85 Self::SAP(entry) => entry.serialize(&mut writer),
86 Self::SampleToMetadataItem(entry) => entry.serialize(&mut writer),
87 Self::VisualDRAP(entry) => entry.serialize(&mut writer),
88 Self::PixelAspectRatio(entry) => entry.serialize(&mut writer),
89 Self::CleanAperture(entry) => entry.serialize(&mut writer),
90 Self::Unknown { data, .. } => data.serialize(&mut writer),
91 }
92 }
93}
94
95impl IsoSized for SampleGroupDescriptionEntry<'_> {
96 fn size(&self) -> usize {
97 match self {
98 Self::RollRecovery(entry) => entry.size(),
99 Self::AudioPreRoll(entry) => entry.size(),
100 Self::RateShare(entry) => entry.size(),
101 Self::AlternativeStartup(entry) => entry.size(),
102 Self::VisualRandomAccess(entry) => entry.size(),
103 Self::TemporalLevel(entry) => entry.size(),
104 Self::SAP(entry) => entry.size(),
105 Self::SampleToMetadataItem(entry) => entry.size(),
106 Self::VisualDRAP(entry) => entry.size(),
107 Self::PixelAspectRatio(entry) => entry.size(),
108 Self::CleanAperture(entry) => entry.size(),
109 Self::Unknown { data, .. } => data.len(),
110 }
111 }
112}
113
114#[derive(Debug, PartialEq, Eq)]
120pub struct RollRecoveryEntry {
121 roll_distance: i16,
122}
123
124impl<'a> Deserialize<'a> for RollRecoveryEntry {
125 fn deserialize<R>(reader: R) -> io::Result<Self>
126 where
127 R: ZeroCopyReader<'a>,
128 {
129 Ok(Self {
130 roll_distance: i16::deserialize(reader)?,
131 })
132 }
133}
134
135impl Serialize for RollRecoveryEntry {
136 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
137 where
138 W: std::io::Write,
139 {
140 self.roll_distance.serialize(&mut writer)?;
141 Ok(())
142 }
143}
144
145impl IsoSized for RollRecoveryEntry {
146 fn size(&self) -> usize {
147 2 }
149}
150
151#[derive(Debug, PartialEq, Eq)]
157pub struct AudioPreRollEntry {
158 roll_distance: i16,
159}
160
161impl<'a> Deserialize<'a> for AudioPreRollEntry {
162 fn deserialize<R>(reader: R) -> io::Result<Self>
163 where
164 R: ZeroCopyReader<'a>,
165 {
166 Ok(AudioPreRollEntry {
167 roll_distance: i16::deserialize(reader)?,
168 })
169 }
170}
171
172impl Serialize for AudioPreRollEntry {
173 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
174 where
175 W: std::io::Write,
176 {
177 self.roll_distance.serialize(&mut writer)?;
178 Ok(())
179 }
180}
181
182impl IsoSized for AudioPreRollEntry {
183 fn size(&self) -> usize {
184 2 }
186}
187
188#[derive(Debug, PartialEq, Eq)]
194pub struct RateShareEntry {
195 operation_point_count: u16,
196 operation_points: Vec<RateShareEntryOperationPoint>,
197 maximum_bitrate: u32,
198 minimum_bitrate: u32,
199 discard_priority: u8,
200}
201
202impl<'a> Deserialize<'a> for RateShareEntry {
203 fn deserialize<R>(mut reader: R) -> io::Result<Self>
204 where
205 R: ZeroCopyReader<'a>,
206 {
207 let operation_point_count = u16::deserialize(&mut reader)?;
208 let mut operation_points = Vec::with_capacity(operation_point_count as usize);
209
210 if operation_point_count == 1 {
211 let target_rate_share = u16::deserialize(&mut reader)?;
212 operation_points.push(RateShareEntryOperationPoint {
213 target_rate_share,
214 available_bitrate: None,
215 });
216 } else {
217 for _ in 0..operation_point_count {
218 operation_points.push(RateShareEntryOperationPoint::deserialize(&mut reader)?);
219 }
220 }
221
222 let maximum_bitrate = u32::deserialize(&mut reader)?;
223 let minimum_bitrate = u32::deserialize(&mut reader)?;
224 let discard_priority = u8::deserialize(&mut reader)?;
225
226 Ok(Self {
227 operation_point_count,
228 operation_points,
229 maximum_bitrate,
230 minimum_bitrate,
231 discard_priority,
232 })
233 }
234}
235
236impl Serialize for RateShareEntry {
237 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
238 where
239 W: std::io::Write,
240 {
241 self.operation_point_count.serialize(&mut writer)?;
242 for operation_point in &self.operation_points {
243 if self.operation_point_count > 1 && operation_point.available_bitrate.is_none() {
244 return Err(io::Error::new(io::ErrorKind::InvalidData, "available_bitrate is required"));
245 }
246 operation_point.serialize(&mut writer)?;
247 }
248 self.maximum_bitrate.serialize(&mut writer)?;
249 self.minimum_bitrate.serialize(&mut writer)?;
250 self.discard_priority.serialize(&mut writer)?;
251 Ok(())
252 }
253}
254
255impl IsoSized for RateShareEntry {
256 fn size(&self) -> usize {
257 2 + self.operation_points.size() + 4 + 4 + 1
258 }
259}
260
261#[derive(Debug, PartialEq, Eq)]
263pub struct RateShareEntryOperationPoint {
264 pub target_rate_share: u16,
271 pub available_bitrate: Option<u32>,
275}
276
277impl<'a> Deserialize<'a> for RateShareEntryOperationPoint {
278 fn deserialize<R>(mut reader: R) -> io::Result<Self>
279 where
280 R: ZeroCopyReader<'a>,
281 {
282 let available_bitrate = u32::deserialize(&mut reader)?;
283 let target_rate_share = u16::deserialize(&mut reader)?;
284
285 Ok(Self {
286 available_bitrate: Some(available_bitrate),
287 target_rate_share,
288 })
289 }
290}
291
292impl Serialize for RateShareEntryOperationPoint {
293 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
294 where
295 W: std::io::Write,
296 {
297 if let Some(available_bitrate) = &self.available_bitrate {
298 available_bitrate.serialize(&mut writer)?;
299 }
300 self.target_rate_share.serialize(&mut writer)?;
301 Ok(())
302 }
303}
304
305impl IsoSized for RateShareEntryOperationPoint {
306 fn size(&self) -> usize {
307 if self.available_bitrate.is_some() {
308 4 + 2 } else {
310 2 }
312 }
313}
314
315#[derive(Debug, PartialEq, Eq)]
321pub struct AlternativeStartupEntry {
322 roll_count: u16,
323 first_output_sample: u16,
324 sample_offset: Vec<u32>,
325 nums: Vec<AlternativeStartupEntryNums>,
326}
327
328impl<'a> Deserialize<'a> for AlternativeStartupEntry {
329 fn deserialize<R>(mut reader: R) -> io::Result<Self>
330 where
331 R: ZeroCopyReader<'a>,
332 {
333 let roll_count = u16::deserialize(&mut reader)?;
334 let first_output_sample = u16::deserialize(&mut reader)?;
335
336 let mut sample_offset = Vec::with_capacity(roll_count as usize);
337 for _ in 0..roll_count {
338 sample_offset.push(u32::deserialize(&mut reader)?);
339 }
340
341 let mut nums = Vec::new();
342 loop {
343 let Some(num) = AlternativeStartupEntryNums::deserialize(&mut reader).eof_to_none()? else {
344 break;
345 };
346 nums.push(num);
347 }
348
349 Ok(Self {
350 roll_count,
351 first_output_sample,
352 sample_offset,
353 nums,
354 })
355 }
356}
357
358impl Serialize for AlternativeStartupEntry {
359 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
360 where
361 W: std::io::Write,
362 {
363 self.roll_count.serialize(&mut writer)?;
364 self.first_output_sample.serialize(&mut writer)?;
365 for offset in &self.sample_offset {
366 offset.serialize(&mut writer)?;
367 }
368 for num in &self.nums {
369 num.serialize(&mut writer)?;
370 }
371 Ok(())
372 }
373}
374
375impl IsoSized for AlternativeStartupEntry {
376 fn size(&self) -> usize {
377 2 + 2 + self.sample_offset.size() + self.nums.size()
378 }
379}
380
381#[derive(Debug, PartialEq, Eq)]
393pub struct AlternativeStartupEntryNums {
394 pub num_output_samples: u16,
396 pub num_total_samples: u16,
398}
399
400impl<'a> Deserialize<'a> for AlternativeStartupEntryNums {
401 fn deserialize<R>(mut reader: R) -> io::Result<Self>
402 where
403 R: ZeroCopyReader<'a>,
404 {
405 Ok(Self {
406 num_output_samples: u16::deserialize(&mut reader)?,
407 num_total_samples: u16::deserialize(&mut reader)?,
408 })
409 }
410}
411
412impl Serialize for AlternativeStartupEntryNums {
413 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
414 where
415 W: std::io::Write,
416 {
417 self.num_output_samples.serialize(&mut writer)?;
418 self.num_total_samples.serialize(&mut writer)?;
419 Ok(())
420 }
421}
422
423impl IsoSized for AlternativeStartupEntryNums {
424 fn size(&self) -> usize {
425 2 + 2 }
427}
428
429#[derive(Debug, PartialEq, Eq)]
435pub struct VisualRandomAccessEntry {
436 num_leading_samples_known: bool,
437 num_leading_samples: u8,
438}
439
440impl<'a> Deserialize<'a> for VisualRandomAccessEntry {
441 fn deserialize<R>(mut reader: R) -> io::Result<Self>
442 where
443 R: ZeroCopyReader<'a>,
444 {
445 let byte = u8::deserialize(&mut reader)?;
446 let num_leading_samples_known = (byte & 0b1000_0000) != 0;
447 let num_leading_samples = byte & 0b0111_1111;
448
449 Ok(Self {
450 num_leading_samples_known,
451 num_leading_samples,
452 })
453 }
454}
455
456impl Serialize for VisualRandomAccessEntry {
457 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
458 where
459 W: std::io::Write,
460 {
461 let mut byte = (self.num_leading_samples_known as u8) << 7;
462 byte |= self.num_leading_samples;
463 byte.serialize(&mut writer)?;
464 Ok(())
465 }
466}
467
468impl IsoSized for VisualRandomAccessEntry {
469 fn size(&self) -> usize {
470 1 }
472}
473
474#[derive(Debug, PartialEq, Eq)]
480pub struct TemporalLevelEntry {
481 level_independently_decodable: bool,
482}
483
484impl<'a> Deserialize<'a> for TemporalLevelEntry {
485 fn deserialize<R>(mut reader: R) -> io::Result<Self>
486 where
487 R: ZeroCopyReader<'a>,
488 {
489 let level_independently_decodable = (u8::deserialize(&mut reader)? & 0b1000_0000) != 0;
490
491 Ok(Self {
492 level_independently_decodable,
493 })
494 }
495}
496
497impl Serialize for TemporalLevelEntry {
498 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
499 where
500 W: std::io::Write,
501 {
502 ((self.level_independently_decodable as u8) << 7).serialize(&mut writer)?;
503 Ok(())
504 }
505}
506
507impl IsoSized for TemporalLevelEntry {
508 fn size(&self) -> usize {
509 1 }
511}
512
513#[derive(Debug, PartialEq, Eq)]
519pub struct SAPEntry {
520 dependent_flag: bool,
521 sap_type: u8,
522}
523
524impl<'a> Deserialize<'a> for SAPEntry {
525 fn deserialize<R>(mut reader: R) -> io::Result<Self>
526 where
527 R: ZeroCopyReader<'a>,
528 {
529 let byte = u8::deserialize(&mut reader)?;
531 let dependent_flag = (byte & 0b1000_0000) != 0;
532 let sap_type = byte & 0b0000_1111;
533
534 Ok(Self {
535 dependent_flag,
536 sap_type,
537 })
538 }
539}
540
541impl Serialize for SAPEntry {
542 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
543 where
544 W: std::io::Write,
545 {
546 let mut byte = (self.dependent_flag as u8) << 7;
547 byte |= self.sap_type & 0b0000_1111;
548 byte.serialize(&mut writer)?;
549 Ok(())
550 }
551}
552
553impl IsoSized for SAPEntry {
554 fn size(&self) -> usize {
555 1 }
557}
558
559#[derive(Debug, PartialEq, Eq)]
565pub struct SampleToMetadataItemEntry {
566 meta_box_handler_type: u32,
567 num_items: u32,
568 item_id: Vec<u32>,
569}
570
571impl<'a> Deserialize<'a> for SampleToMetadataItemEntry {
572 fn deserialize<R>(mut reader: R) -> io::Result<Self>
573 where
574 R: ZeroCopyReader<'a>,
575 {
576 let meta_box_handler_type = u32::deserialize(&mut reader)?;
577 let num_items = u32::deserialize(&mut reader)?;
578
579 let mut item_id = Vec::with_capacity(num_items as usize);
580 for _ in 0..num_items {
581 item_id.push(u32::deserialize(&mut reader)?);
582 }
583
584 Ok(Self {
585 meta_box_handler_type,
586 num_items,
587 item_id,
588 })
589 }
590}
591
592impl Serialize for SampleToMetadataItemEntry {
593 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
594 where
595 W: std::io::Write,
596 {
597 self.meta_box_handler_type.serialize(&mut writer)?;
598 self.num_items.serialize(&mut writer)?;
599 for id in &self.item_id {
600 id.serialize(&mut writer)?;
601 }
602 Ok(())
603 }
604}
605
606impl IsoSized for SampleToMetadataItemEntry {
607 fn size(&self) -> usize {
608 4 + 4 + self.item_id.size() }
610}
611
612#[derive(Debug, PartialEq, Eq)]
618pub struct VisualDRAPEntry {
619 drap_type: u8,
620}
621
622impl<'a> Deserialize<'a> for VisualDRAPEntry {
623 fn deserialize<R>(mut reader: R) -> io::Result<Self>
624 where
625 R: ZeroCopyReader<'a>,
626 {
627 let drap_type = ((u32::deserialize(&mut reader)? >> 29) & 0b111) as u8;
628 Ok(Self { drap_type })
629 }
630}
631
632impl Serialize for VisualDRAPEntry {
633 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
634 where
635 W: std::io::Write,
636 {
637 let byte = ((self.drap_type & 0b1111) as u32) << 29;
638 byte.serialize(&mut writer)?;
639 Ok(())
640 }
641}
642
643impl IsoSized for VisualDRAPEntry {
644 fn size(&self) -> usize {
645 4 }
647}
648
649#[derive(Debug, PartialEq, Eq)]
655pub struct PixelAspectRatioEntry {
656 h_spacing: u32,
657 v_spacing: u32,
658}
659
660impl<'a> Deserialize<'a> for PixelAspectRatioEntry {
661 fn deserialize<R>(mut reader: R) -> io::Result<Self>
662 where
663 R: ZeroCopyReader<'a>,
664 {
665 Ok(Self {
666 h_spacing: u32::deserialize(&mut reader)?,
667 v_spacing: u32::deserialize(&mut reader)?,
668 })
669 }
670}
671
672impl Serialize for PixelAspectRatioEntry {
673 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
674 where
675 W: std::io::Write,
676 {
677 self.h_spacing.serialize(&mut writer)?;
678 self.v_spacing.serialize(&mut writer)?;
679 Ok(())
680 }
681}
682
683impl IsoSized for PixelAspectRatioEntry {
684 fn size(&self) -> usize {
685 4 + 4 }
687}
688
689#[derive(Debug, PartialEq, Eq)]
695pub struct CleanApertureEntry {
696 clean_aperture_width_n: u32,
697 clean_aperture_width_d: u32,
698 clean_aperture_height_n: u32,
699 clean_aperture_height_d: u32,
700 horiz_off_n: u32,
701 horiz_off_d: u32,
702 vert_off_n: u32,
703 vert_off_d: u32,
704}
705
706impl<'a> Deserialize<'a> for CleanApertureEntry {
707 fn deserialize<R>(mut reader: R) -> io::Result<Self>
708 where
709 R: ZeroCopyReader<'a>,
710 {
711 Ok(Self {
712 clean_aperture_width_n: u32::deserialize(&mut reader)?,
713 clean_aperture_width_d: u32::deserialize(&mut reader)?,
714 clean_aperture_height_n: u32::deserialize(&mut reader)?,
715 clean_aperture_height_d: u32::deserialize(&mut reader)?,
716 horiz_off_n: u32::deserialize(&mut reader)?,
717 horiz_off_d: u32::deserialize(&mut reader)?,
718 vert_off_n: u32::deserialize(&mut reader)?,
719 vert_off_d: u32::deserialize(&mut reader)?,
720 })
721 }
722}
723
724impl Serialize for CleanApertureEntry {
725 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
726 where
727 W: std::io::Write,
728 {
729 self.clean_aperture_width_n.serialize(&mut writer)?;
730 self.clean_aperture_width_d.serialize(&mut writer)?;
731 self.clean_aperture_height_n.serialize(&mut writer)?;
732 self.clean_aperture_height_d.serialize(&mut writer)?;
733 self.horiz_off_n.serialize(&mut writer)?;
734 self.horiz_off_d.serialize(&mut writer)?;
735 self.vert_off_n.serialize(&mut writer)?;
736 self.vert_off_d.serialize(&mut writer)?;
737 Ok(())
738 }
739}
740
741impl IsoSized for CleanApertureEntry {
742 fn size(&self) -> usize {
743 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 }
745}