1use std::fmt::Debug;
2use std::{io, iter};
3
4use scuffle_bytes_util::zero_copy::{Deserialize, DeserializeSeed, Serialize, U24Be, ZeroCopyReader};
5use scuffle_bytes_util::{BytesCow, IoResultExt};
6
7use crate::{BoxHeader, FullBoxHeader, IsoBox, IsoSized, UnknownBox, Utf8String};
8
9#[derive(IsoBox, Debug, PartialEq, Eq, Default)]
13#[iso_box(box_type = b"dinf", crate_path = crate)]
14pub struct DataInformationBox<'a> {
15 #[iso_box(nested_box)]
17 pub dref: DataReferenceBox<'a>,
18}
19
20#[derive(IsoBox, Debug, PartialEq, Eq, Default)]
24#[iso_box(box_type = b"url ", skip_impl(deserialize_seed, serialize), crate_path = crate)]
25pub struct DataEntryUrlBox {
26 pub full_header: FullBoxHeader,
28 pub location: Option<Utf8String>,
35}
36
37impl<'a> DeserializeSeed<'a, BoxHeader> for DataEntryUrlBox {
38 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> io::Result<Self>
39 where
40 R: ZeroCopyReader<'a>,
41 {
42 let full_header = FullBoxHeader::deserialize(&mut reader)?;
43 let location = Utf8String::deserialize(&mut reader).eof_to_none()?;
44
45 Ok(Self { full_header, location })
46 }
47}
48
49impl Serialize for DataEntryUrlBox {
50 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
51 where
52 W: std::io::Write,
53 {
54 self.serialize_box_header(&mut writer)?;
55 self.full_header.serialize(&mut writer)?;
56 if let Some(location) = &self.location {
57 location.serialize(&mut writer)?;
58 }
59
60 Ok(())
61 }
62}
63
64#[derive(IsoBox, Debug, PartialEq, Eq)]
68#[iso_box(box_type = b"urn ", skip_impl(deserialize_seed, serialize), crate_path = crate)]
69pub struct DataEntryUrnBox {
70 pub full_header: FullBoxHeader,
72 pub name: Utf8String,
74 pub location: Option<Utf8String>,
79}
80
81impl<'a> DeserializeSeed<'a, BoxHeader> for DataEntryUrnBox {
82 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> io::Result<Self>
83 where
84 R: ZeroCopyReader<'a>,
85 {
86 let full_header = FullBoxHeader::deserialize(&mut reader)?;
87 let name = Utf8String::deserialize(&mut reader)?;
88 let location = Utf8String::deserialize(&mut reader).eof_to_none()?;
89
90 Ok(Self {
91 full_header,
92 name,
93 location,
94 })
95 }
96}
97
98impl Serialize for DataEntryUrnBox {
99 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
100 where
101 W: std::io::Write,
102 {
103 self.serialize_box_header(&mut writer)?;
104 self.full_header.serialize(&mut writer)?;
105 self.name.serialize(&mut writer)?;
106 if let Some(location) = &self.location {
107 location.serialize(&mut writer)?;
108 }
109
110 Ok(())
111 }
112}
113
114#[derive(IsoBox, Debug, PartialEq, Eq)]
118#[iso_box(box_type = b"imdt", crate_path = crate)]
119pub struct DataEntryImdaBox {
120 pub full_header: FullBoxHeader,
122 pub imda_ref_identifier: u32,
127}
128
129#[derive(IsoBox, Debug, PartialEq, Eq)]
133#[iso_box(box_type = b"snim", crate_path = crate)]
134pub struct DataEntrySeqNumImdaBox {
135 pub full_header: FullBoxHeader,
137}
138
139#[derive(IsoBox, Debug, PartialEq, Eq)]
143#[iso_box(box_type = b"dref", crate_path = crate)]
144pub struct DataReferenceBox<'a> {
145 pub full_header: FullBoxHeader,
147 pub entry_count: u32,
149 #[iso_box(nested_box(collect))]
151 pub url: Vec<DataEntryUrlBox>,
152 #[iso_box(nested_box(collect))]
154 pub urn: Vec<DataEntryUrnBox>,
155 #[iso_box(nested_box(collect))]
157 pub imda: Vec<DataEntryImdaBox>,
158 #[iso_box(nested_box(collect))]
160 pub snim: Vec<DataEntrySeqNumImdaBox>,
161 #[iso_box(nested_box(collect_unknown))]
163 pub unknown_boxes: Vec<UnknownBox<'a>>,
164}
165
166impl Default for DataReferenceBox<'_> {
167 fn default() -> Self {
168 Self {
169 full_header: FullBoxHeader::default(),
170 entry_count: 1,
171 url: vec![DataEntryUrlBox::default()],
172 urn: vec![],
173 imda: vec![],
174 snim: vec![],
175 unknown_boxes: vec![],
176 }
177 }
178}
179
180#[derive(IsoBox, PartialEq, Eq, Default)]
184#[iso_box(box_type = b"stsz", crate_path = crate)]
185pub struct SampleSizeBox {
186 pub full_header: FullBoxHeader,
188 pub sample_size: u32,
193 pub sample_count: u32,
196 #[iso_box(repeated)]
198 pub entry_size: Vec<u32>,
199}
200
201impl Debug for SampleSizeBox {
202 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
203 f.debug_struct("SampleSizeBox")
204 .field("full_header", &self.full_header)
205 .field("sample_size", &self.sample_size)
206 .field("sample_count", &self.sample_count)
207 .field("entry_size.len", &self.entry_size.len())
208 .finish()
209 }
210}
211
212#[derive(IsoBox, Debug, PartialEq, Eq)]
216#[iso_box(box_type = b"stz2", crate_path = crate)]
217pub struct CompactSampleSizeBox<'a> {
218 pub full_header: FullBoxHeader,
220 pub reserved: U24Be,
222 pub field_size: u8,
226 pub sample_count: u32,
228 pub entry_size: BytesCow<'a>,
230}
231
232#[derive(IsoBox, PartialEq, Eq, Default)]
236#[iso_box(box_type = b"stsc", crate_path = crate)]
237pub struct SampleToChunkBox {
238 pub full_header: FullBoxHeader,
240 pub entry_count: u32,
242 #[iso_box(repeated)]
244 pub entries: Vec<SampleToChunkBoxEntry>,
245}
246
247impl Debug for SampleToChunkBox {
248 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249 f.debug_struct("SampleToChunkBox")
250 .field("full_header", &self.full_header)
251 .field("entry_count", &self.entry_count)
252 .field("entries.len", &self.entries.len())
253 .finish()
254 }
255}
256
257#[derive(Debug, PartialEq, Eq)]
259pub struct SampleToChunkBoxEntry {
260 pub first_chunk: u32,
265 pub samples_per_chunk: u32,
267 pub sample_description_index: u32,
271}
272
273impl<'a> Deserialize<'a> for SampleToChunkBoxEntry {
274 fn deserialize<R>(mut reader: R) -> io::Result<Self>
275 where
276 R: ZeroCopyReader<'a>,
277 {
278 Ok(Self {
279 first_chunk: u32::deserialize(&mut reader)?,
280 samples_per_chunk: u32::deserialize(&mut reader)?,
281 sample_description_index: u32::deserialize(&mut reader)?,
282 })
283 }
284}
285
286impl Serialize for SampleToChunkBoxEntry {
287 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
288 where
289 W: std::io::Write,
290 {
291 self.first_chunk.serialize(&mut writer)?;
292 self.samples_per_chunk.serialize(&mut writer)?;
293 self.sample_description_index.serialize(&mut writer)?;
294 Ok(())
295 }
296}
297
298impl IsoSized for SampleToChunkBoxEntry {
299 fn size(&self) -> usize {
300 4 + 4 + 4 }
302}
303
304#[derive(IsoBox, PartialEq, Eq, Default)]
308#[iso_box(box_type = b"stco", crate_path = crate)]
309pub struct ChunkOffsetBox {
310 pub full_header: FullBoxHeader,
312 pub entry_count: u32,
314 #[iso_box(repeated)]
320 pub chunk_offset: Vec<u32>,
321}
322
323impl Debug for ChunkOffsetBox {
324 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
325 f.debug_struct("ChunkOffsetBox")
326 .field("full_header", &self.full_header)
327 .field("entry_count", &self.entry_count)
328 .field("chunk_offset.len", &self.chunk_offset.len())
329 .finish()
330 }
331}
332
333#[derive(IsoBox, Debug, PartialEq, Eq)]
337#[iso_box(box_type = b"co64", crate_path = crate)]
338pub struct ChunkLargeOffsetBox {
339 pub full_header: FullBoxHeader,
341 pub entry_count: u32,
343 #[iso_box(repeated)]
349 pub chunk_offset: Vec<u64>,
350}
351
352#[derive(IsoBox, PartialEq, Eq)]
356#[iso_box(box_type = b"padb", crate_path = crate)]
357pub struct PaddingBitsBox {
358 pub full_header: FullBoxHeader,
360 pub sample_count: u32,
362 #[iso_box(from = "u8", repeated)]
364 pub entry: Vec<PaddingBitsBoxEntry>,
365}
366
367impl Debug for PaddingBitsBox {
368 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
369 f.debug_struct("PaddingBitsBox")
370 .field("full_header", &self.full_header)
371 .field("sample_count", &self.sample_count)
372 .field("entry.len", &self.entry.len())
373 .finish()
374 }
375}
376
377#[derive(Debug, PartialEq, Eq, Clone, Copy)]
379pub struct PaddingBitsBoxEntry {
380 pub pad1: u8,
382 pub pad2: u8,
384}
385
386impl From<u8> for PaddingBitsBoxEntry {
387 fn from(value: u8) -> Self {
388 Self {
390 pad1: (value >> 4) & 0b0111,
391 pad2: value & 0b0111,
392 }
393 }
394}
395
396impl From<PaddingBitsBoxEntry> for u8 {
397 fn from(value: PaddingBitsBoxEntry) -> Self {
398 (value.pad1 << 4) | value.pad2
399 }
400}
401
402impl IsoSized for PaddingBitsBoxEntry {
403 fn size(&self) -> usize {
404 1
405 }
406}
407
408#[derive(IsoBox, Debug, PartialEq, Eq)]
412#[iso_box(box_type = b"subs", skip_impl(deserialize_seed, serialize, sized), crate_path = crate)]
413pub struct SubSampleInformationBox {
414 pub full_header: FullBoxHeader,
416 pub entry_count: u32,
418 pub entries: Vec<SubSampleInformationBoxEntry>,
420}
421
422impl<'a> DeserializeSeed<'a, BoxHeader> for SubSampleInformationBox {
423 fn deserialize_seed<R>(mut reader: R, seed: BoxHeader) -> io::Result<Self>
424 where
425 R: ZeroCopyReader<'a>,
426 {
427 let full_header = FullBoxHeader::deserialize(&mut reader)?;
428
429 let entry_count = u32::deserialize(&mut reader)?;
430
431 let entries = {
432 if let Some(payload_size) = seed.size.size() {
433 let mut payload_reader = reader.take(payload_size);
434 iter::from_fn(|| {
435 SubSampleInformationBoxEntry::deserialize_seed(&mut payload_reader, full_header.version)
436 .eof_to_none()
437 .transpose()
438 })
439 .collect::<Result<Vec<SubSampleInformationBoxEntry>, io::Error>>()?
440 } else {
441 iter::from_fn(|| {
442 SubSampleInformationBoxEntry::deserialize_seed(&mut reader, full_header.version)
443 .eof_to_none()
444 .transpose()
445 })
446 .collect::<Result<Vec<SubSampleInformationBoxEntry>, io::Error>>()?
447 }
448 };
449
450 Ok(Self {
451 full_header,
452 entry_count,
453 entries,
454 })
455 }
456}
457
458impl Serialize for SubSampleInformationBox {
459 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
460 where
461 W: std::io::Write,
462 {
463 self.serialize_box_header(&mut writer)?;
464 self.full_header.serialize(&mut writer)?;
465 self.entry_count.serialize(&mut writer)?;
466
467 for entry in &self.entries {
468 entry.serialize(&mut writer, self.full_header.version)?;
469 }
470
471 Ok(())
472 }
473}
474
475impl IsoSized for SubSampleInformationBox {
476 fn size(&self) -> usize {
477 let mut size = 0;
478 size += self.full_header.size();
479 size += 4;
480 size += self.entries.iter().map(|e| e.size(self.full_header.version)).sum::<usize>();
481
482 Self::add_header_size(size)
483 }
484}
485
486#[derive(Debug, PartialEq, Eq)]
488pub struct SubSampleInformationBoxEntry {
489 pub sample_delta: u32,
502 pub subsample_count: u16,
505 pub subsample_info: Vec<SubSampleInformationBoxEntrySubSample>,
507}
508
509impl<'a> DeserializeSeed<'a, u8> for SubSampleInformationBoxEntry {
510 fn deserialize_seed<R: ZeroCopyReader<'a>>(mut reader: R, seed: u8) -> io::Result<Self> {
511 let sample_delta = u32::deserialize(&mut reader)?;
512 let subsample_count = u16::deserialize(&mut reader)?;
513
514 let mut subsample_info = Vec::with_capacity(subsample_count as usize);
515 for _ in 0..subsample_count {
516 subsample_info.push(SubSampleInformationBoxEntrySubSample::deserialize_seed(&mut reader, seed)?);
517 }
518
519 Ok(Self {
520 sample_delta,
521 subsample_count,
522 subsample_info,
523 })
524 }
525}
526
527impl SubSampleInformationBoxEntry {
528 fn serialize<W>(&self, mut writer: W, version: u8) -> io::Result<()>
529 where
530 W: std::io::Write,
531 {
532 self.sample_delta.serialize(&mut writer)?;
533
534 self.subsample_count.serialize(&mut writer)?;
535 for subsample in &self.subsample_info {
536 subsample.serialize(&mut writer, version)?;
537 }
538
539 Ok(())
540 }
541}
542
543impl SubSampleInformationBoxEntry {
544 pub fn size(&self, version: u8) -> usize {
546 4 + 2 + self.subsample_info.iter().map(|s| s.size(version)).sum::<usize>()
547 }
548}
549
550#[derive(Debug, PartialEq, Eq)]
552pub struct SubSampleInformationBoxEntrySubSample {
553 pub subsample_size: u32,
555 pub subsample_priority: u8,
559 pub discardable: u8,
564 pub codec_specific_parameters: u32,
567}
568
569impl<'a> DeserializeSeed<'a, u8> for SubSampleInformationBoxEntrySubSample {
570 fn deserialize_seed<R>(mut reader: R, seed: u8) -> io::Result<Self>
571 where
572 R: ZeroCopyReader<'a>,
573 {
574 let subsample_size = if seed == 1 {
575 u32::deserialize(&mut reader)?
576 } else {
577 u16::deserialize(&mut reader)? as u32
578 };
579 let subsample_priority = u8::deserialize(&mut reader)?;
580 let discardable = u8::deserialize(&mut reader)?;
581 let codec_specific_parameters = u32::deserialize(&mut reader)?;
582
583 Ok(Self {
584 subsample_size,
585 subsample_priority,
586 discardable,
587 codec_specific_parameters,
588 })
589 }
590}
591
592impl SubSampleInformationBoxEntrySubSample {
593 fn serialize<W>(&self, mut writer: W, version: u8) -> io::Result<()>
594 where
595 W: std::io::Write,
596 {
597 if version == 1 {
598 self.subsample_size.serialize(&mut writer)?;
599 } else {
600 (self.subsample_size as u16).serialize(&mut writer)?;
601 }
602 self.subsample_priority.serialize(&mut writer)?;
603 self.discardable.serialize(&mut writer)?;
604 self.codec_specific_parameters.serialize(&mut writer)?;
605
606 Ok(())
607 }
608}
609
610impl SubSampleInformationBoxEntrySubSample {
611 pub fn size(&self, version: u8) -> usize {
613 if version == 1 { 4 + 1 + 1 + 4 } else { 2 + 1 + 1 + 4 }
614 }
615}
616
617#[derive(IsoBox, Debug, PartialEq, Eq)]
621#[iso_box(box_type = b"saiz", skip_impl(deserialize_seed, serialize), crate_path = crate)]
622pub struct SampleAuxiliaryInformationSizesBox<'a> {
623 pub full_header: FullBoxHeader,
625 pub aux_info_type: Option<u32>,
629 pub aux_info_type_parameter: Option<u32>,
633 pub default_sample_info_size: u8,
637 pub sample_count: u32,
649 pub sample_info_size: Option<BytesCow<'a>>,
654}
655
656impl<'a> DeserializeSeed<'a, BoxHeader> for SampleAuxiliaryInformationSizesBox<'a> {
657 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> io::Result<Self>
658 where
659 R: ZeroCopyReader<'a>,
660 {
661 let full_header = FullBoxHeader::deserialize(&mut reader)?;
662
663 let aux_info_type = if (*full_header.flags & 0b1) == 1 {
664 Some(u32::deserialize(&mut reader)?)
665 } else {
666 None
667 };
668 let aux_info_type_parameter = if (*full_header.flags & 0b1) == 1 {
669 Some(u32::deserialize(&mut reader)?)
670 } else {
671 None
672 };
673
674 let default_sample_info_size = u8::deserialize(&mut reader)?;
675 let sample_count = u32::deserialize(&mut reader)?;
676
677 let sample_info_size = if default_sample_info_size == 0 {
678 Some(reader.try_read(sample_count as usize)?)
679 } else {
680 None
681 };
682
683 Ok(Self {
684 full_header,
685 aux_info_type,
686 aux_info_type_parameter,
687 default_sample_info_size,
688 sample_count,
689 sample_info_size,
690 })
691 }
692}
693
694impl Serialize for SampleAuxiliaryInformationSizesBox<'_> {
695 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
696 where
697 W: std::io::Write,
698 {
699 self.serialize_box_header(&mut writer)?;
700 self.full_header.serialize(&mut writer)?;
701
702 if (*self.full_header.flags & 0b1) == 1 {
703 self.aux_info_type
704 .ok_or(io::Error::new(io::ErrorKind::InvalidData, "aux_info_type is required"))?
705 .serialize(&mut writer)?;
706 self.aux_info_type_parameter
707 .ok_or(io::Error::new(
708 io::ErrorKind::InvalidData,
709 "aux_info_type_parameter is required",
710 ))?
711 .serialize(&mut writer)?;
712 }
713
714 self.default_sample_info_size.serialize(&mut writer)?;
715 self.sample_count.serialize(&mut writer)?;
716 if self.default_sample_info_size == 0 {
717 self.sample_info_size
718 .as_ref()
719 .ok_or(io::Error::new(io::ErrorKind::InvalidData, "sample_info_size is required"))?
720 .serialize(&mut writer)?;
721 }
722
723 Ok(())
724 }
725}
726
727#[derive(IsoBox, Debug, PartialEq, Eq)]
731#[iso_box(box_type = b"saio", skip_impl(deserialize_seed, serialize, sized), crate_path = crate)]
732pub struct SampleAuxiliaryInformationOffsetsBox {
733 pub full_header: FullBoxHeader,
735 pub aux_info_type: Option<u32>,
739 pub aux_info_type_parameter: Option<u32>,
743 pub entry_count: u32,
752 pub offset: Vec<u64>,
760}
761
762impl<'a> DeserializeSeed<'a, BoxHeader> for SampleAuxiliaryInformationOffsetsBox {
763 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> io::Result<Self>
764 where
765 R: ZeroCopyReader<'a>,
766 {
767 let full_header = FullBoxHeader::deserialize(&mut reader)?;
768
769 let aux_info_type = if (*full_header.flags & 0b1) == 1 {
770 Some(u32::deserialize(&mut reader)?)
771 } else {
772 None
773 };
774 let aux_info_type_parameter = if (*full_header.flags & 0b1) == 1 {
775 Some(u32::deserialize(&mut reader)?)
776 } else {
777 None
778 };
779
780 let entry_count = u32::deserialize(&mut reader)?;
781
782 let offset = if full_header.version == 0 {
783 (0..entry_count)
784 .map(|_| u32::deserialize(&mut reader).map(|v| v as u64))
785 .collect::<Result<Vec<u64>, io::Error>>()?
786 } else {
787 (0..entry_count)
788 .map(|_| u64::deserialize(&mut reader))
789 .collect::<Result<Vec<u64>, io::Error>>()?
790 };
791
792 Ok(Self {
793 full_header,
794 aux_info_type,
795 aux_info_type_parameter,
796 entry_count,
797 offset,
798 })
799 }
800}
801
802impl Serialize for SampleAuxiliaryInformationOffsetsBox {
803 fn serialize<W>(&self, mut writer: W) -> io::Result<()>
804 where
805 W: std::io::Write,
806 {
807 self.serialize_box_header(&mut writer)?;
808 self.full_header.serialize(&mut writer)?;
809
810 if (*self.full_header.flags & 0b1) == 1 {
811 self.aux_info_type
812 .ok_or(io::Error::new(io::ErrorKind::InvalidData, "aux_info_type is required"))?
813 .serialize(&mut writer)?;
814 self.aux_info_type_parameter
815 .ok_or(io::Error::new(
816 io::ErrorKind::InvalidData,
817 "aux_info_type_parameter is required",
818 ))?
819 .serialize(&mut writer)?;
820 }
821
822 self.entry_count.serialize(&mut writer)?;
823 for entry in &self.offset {
824 if self.full_header.version == 0 {
825 (*entry as u32).serialize(&mut writer)?;
826 } else {
827 entry.serialize(&mut writer)?;
828 }
829 }
830
831 Ok(())
832 }
833}
834
835impl IsoSized for SampleAuxiliaryInformationOffsetsBox {
836 fn size(&self) -> usize {
837 let mut size = self.full_header.size();
838 if (*self.full_header.flags & 0b1) == 1 {
839 size += 4; size += 4; }
842 size += 4; size += if self.full_header.version == 0 {
844 4 * self.offset.len() } else {
846 8 * self.offset.len() };
848
849 Self::add_header_size(size)
850 }
851}