1use scuffle_bytes_util::IoResultExt;
2use scuffle_bytes_util::zero_copy::{Deserialize, DeserializeSeed, Serialize};
3
4use crate::{Base64String, BoxHeader, FullBoxHeader, IsoBox, IsoSized, Utf8String};
5
6#[derive(IsoBox, Debug, PartialEq, Eq)]
10#[iso_box(box_type = b"fiin", skip_impl(deserialize_seed, serialize), crate_path = crate)]
11pub struct FDItemInformationBox {
12 pub full_header: FullBoxHeader,
14 pub entry_count: u16,
16 pub partition_entries: Vec<PartitionEntry>,
18 pub session_info: Option<FDSessionGroupBox>,
20 pub group_id_to_name: Option<GroupIdToNameBox>,
22}
23
24impl<'a> DeserializeSeed<'a, BoxHeader> for FDItemInformationBox {
25 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> std::io::Result<Self>
26 where
27 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
28 {
29 let full_header = FullBoxHeader::deserialize(&mut reader)?;
30 let entry_count = u16::deserialize(&mut reader)?;
31
32 let mut partition_entries = Vec::with_capacity(entry_count as usize);
33 for _ in 0..entry_count {
34 partition_entries.push(PartitionEntry::deserialize(&mut reader)?);
35 }
36
37 let session_info = FDSessionGroupBox::deserialize(&mut reader).eof_to_none()?;
38 let group_id_to_name = GroupIdToNameBox::deserialize(&mut reader).eof_to_none()?;
39
40 Ok(Self {
41 full_header,
42 entry_count,
43 partition_entries,
44 session_info,
45 group_id_to_name,
46 })
47 }
48}
49
50impl Serialize for FDItemInformationBox {
51 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
52 where
53 W: std::io::Write,
54 {
55 self.serialize_box_header(&mut writer)?;
56 self.full_header.serialize(&mut writer)?;
57 self.entry_count.serialize(&mut writer)?;
58
59 for entry in &self.partition_entries {
60 entry.serialize(&mut writer)?;
61 }
62
63 if let Some(ref session_info) = self.session_info {
64 session_info.serialize(&mut writer)?;
65 }
66
67 if let Some(ref group_id_to_name) = self.group_id_to_name {
68 group_id_to_name.serialize(&mut writer)?;
69 }
70
71 Ok(())
72 }
73}
74
75#[derive(IsoBox, Debug, PartialEq, Eq)]
79#[iso_box(box_type = b"paen", crate_path = crate)]
80pub struct PartitionEntry {
81 #[iso_box(nested_box(collect))]
83 pub file_symbol_locations: Option<FileReservoirBox>,
84 #[iso_box(nested_box)]
86 pub blocks_and_symbols: FilePartitionBox,
87 #[iso_box(nested_box(collect))]
89 pub fec_symbol_locations: Option<FECReservoirBox>,
90}
91
92#[derive(IsoBox, Debug, PartialEq, Eq)]
96#[iso_box(box_type = b"fpar", skip_impl(deserialize_seed, serialize, sized), crate_path = crate)]
97pub struct FilePartitionBox {
98 pub full_header: FullBoxHeader,
100 pub item_id: u32,
102 pub packet_payload_size: u16,
106 pub reserved: u8,
108 pub fec_encoding_id: u8,
115 pub fec_instance_id: u16,
120 pub max_source_block_length: u16,
122 pub encoding_symbol_length: u16,
125 pub max_number_of_encoding_symbols: u16,
131 pub scheme_specific_info: Base64String,
134 pub entry_count: u32,
138 pub entries: Vec<FilePartitionBoxEntry>,
140}
141
142impl<'a> DeserializeSeed<'a, BoxHeader> for FilePartitionBox {
143 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> std::io::Result<Self>
144 where
145 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
146 {
147 let full_header = FullBoxHeader::deserialize(&mut reader)?;
148 let item_id = if full_header.version == 0 {
149 u16::deserialize(&mut reader)? as u32
150 } else {
151 u32::deserialize(&mut reader)?
152 };
153 let packet_payload_size = u16::deserialize(&mut reader)?;
154 let reserved = u8::deserialize(&mut reader)?;
155 let fec_encoding_id = u8::deserialize(&mut reader)?;
156 let fec_instance_id = u16::deserialize(&mut reader)?;
157 let max_source_block_length = u16::deserialize(&mut reader)?;
158 let encoding_symbol_length = u16::deserialize(&mut reader)?;
159 let max_number_of_encoding_symbols = u16::deserialize(&mut reader)?;
160 let scheme_specific_info = Base64String::deserialize(&mut reader)?;
161
162 let entry_count = if full_header.version == 0 {
163 u16::deserialize(&mut reader)? as u32
164 } else {
165 u32::deserialize(&mut reader)?
166 };
167
168 let mut entries = Vec::with_capacity(entry_count as usize);
169 for _ in 0..entry_count {
170 entries.push(FilePartitionBoxEntry::deserialize(&mut reader)?);
171 }
172
173 Ok(Self {
174 full_header,
175 item_id,
176 packet_payload_size,
177 reserved,
178 fec_encoding_id,
179 fec_instance_id,
180 max_source_block_length,
181 encoding_symbol_length,
182 max_number_of_encoding_symbols,
183 scheme_specific_info,
184 entry_count,
185 entries,
186 })
187 }
188}
189
190impl Serialize for FilePartitionBox {
191 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
192 where
193 W: std::io::Write,
194 {
195 self.serialize_box_header(&mut writer)?;
196 self.full_header.serialize(&mut writer)?;
197 if self.full_header.version == 0 {
198 (self.item_id as u16).serialize(&mut writer)?;
199 } else {
200 self.item_id.serialize(&mut writer)?;
201 }
202 self.packet_payload_size.serialize(&mut writer)?;
203 self.reserved.serialize(&mut writer)?;
204 self.fec_encoding_id.serialize(&mut writer)?;
205 self.fec_instance_id.serialize(&mut writer)?;
206 self.max_source_block_length.serialize(&mut writer)?;
207 self.encoding_symbol_length.serialize(&mut writer)?;
208 self.max_number_of_encoding_symbols.serialize(&mut writer)?;
209 self.scheme_specific_info.serialize(&mut writer)?;
210
211 if self.full_header.version == 0 {
212 (self.entry_count as u16).serialize(&mut writer)?;
213 } else {
214 self.entry_count.serialize(&mut writer)?;
215 }
216
217 for entry in &self.entries {
218 entry.serialize(&mut writer)?;
219 }
220
221 Ok(())
222 }
223}
224
225impl IsoSized for FilePartitionBox {
226 fn size(&self) -> usize {
227 let mut size = self.full_header.size();
228 if self.full_header.version == 0 {
229 size += 2; } else {
231 size += 4; }
233 size += self.packet_payload_size.size()
234 + self.reserved.size()
235 + self.fec_encoding_id.size()
236 + self.fec_instance_id.size()
237 + self.max_source_block_length.size()
238 + self.encoding_symbol_length.size()
239 + self.max_number_of_encoding_symbols.size()
240 + self.scheme_specific_info.size();
241 if self.full_header.version == 0 {
242 size += 2; } else {
244 size += 4; }
246 size += self.entries.size();
247
248 Self::add_header_size(size)
249 }
250}
251
252#[derive(Debug, PartialEq, Eq)]
254pub struct FilePartitionBoxEntry {
255 pub block_count: u16,
257 pub block_size: u32,
263}
264
265impl<'a> Deserialize<'a> for FilePartitionBoxEntry {
266 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
267 where
268 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
269 {
270 let block_count = u16::deserialize(&mut reader)?;
271 let block_size = u32::deserialize(&mut reader)?;
272
273 Ok(Self { block_count, block_size })
274 }
275}
276
277impl Serialize for FilePartitionBoxEntry {
278 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
279 where
280 W: std::io::Write,
281 {
282 self.block_count.serialize(&mut writer)?;
283 self.block_size.serialize(&mut writer)?;
284 Ok(())
285 }
286}
287
288impl IsoSized for FilePartitionBoxEntry {
289 fn size(&self) -> usize {
290 self.block_count.size() + self.block_size.size()
291 }
292}
293
294#[derive(IsoBox, Debug, PartialEq, Eq)]
298#[iso_box(box_type = b"fecr", skip_impl(deserialize_seed, serialize, sized), crate_path = crate)]
299pub struct FECReservoirBox {
300 pub full_header: FullBoxHeader,
302 pub entry_count: u32,
305 pub entries: Vec<FECReservoirBoxEntry>,
307}
308
309impl<'a> DeserializeSeed<'a, BoxHeader> for FECReservoirBox {
310 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> std::io::Result<Self>
311 where
312 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
313 {
314 let full_header = FullBoxHeader::deserialize(&mut reader)?;
315 let entry_count = if full_header.version == 0 {
316 u16::deserialize(&mut reader)? as u32
317 } else {
318 u32::deserialize(&mut reader)?
319 };
320
321 let mut entries = Vec::with_capacity(entry_count as usize);
322 for _ in 0..entry_count {
323 entries.push(FECReservoirBoxEntry::deserialize_seed(&mut reader, full_header.version)?);
324 }
325
326 Ok(Self {
327 full_header,
328 entry_count,
329 entries,
330 })
331 }
332}
333
334impl Serialize for FECReservoirBox {
335 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
336 where
337 W: std::io::Write,
338 {
339 self.serialize_box_header(&mut writer)?;
340 self.full_header.serialize(&mut writer)?;
341 if self.full_header.version == 0 {
342 (self.entry_count as u16).serialize(&mut writer)?;
343 } else {
344 self.entry_count.serialize(&mut writer)?;
345 }
346
347 for entry in &self.entries {
348 entry.serialize(&mut writer, self.full_header.version)?;
349 }
350
351 Ok(())
352 }
353}
354
355impl IsoSized for FECReservoirBox {
356 fn size(&self) -> usize {
357 let mut size = self.full_header.size();
358 if self.full_header.version == 0 {
359 size += (self.entry_count as u16).size();
360 } else {
361 size += self.entry_count.size();
362 }
363 size += self
364 .entries
365 .iter()
366 .map(|entry| entry.size(self.full_header.version))
367 .sum::<usize>();
368
369 Self::add_header_size(size)
370 }
371}
372
373#[derive(Debug, PartialEq, Eq)]
375pub struct FECReservoirBoxEntry {
376 pub item_id: u32,
378 pub symbol_count: u32,
380}
381
382impl<'a> DeserializeSeed<'a, u8> for FECReservoirBoxEntry {
383 fn deserialize_seed<R>(mut reader: R, seed: u8) -> std::io::Result<Self>
384 where
385 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
386 {
387 let item_id = if seed == 0 {
388 u16::deserialize(&mut reader)? as u32
389 } else {
390 u32::deserialize(&mut reader)?
391 };
392 let symbol_count = u32::deserialize(&mut reader)?;
393
394 Ok(Self { item_id, symbol_count })
395 }
396}
397
398impl FECReservoirBoxEntry {
399 fn serialize<W>(&self, mut writer: W, version: u8) -> std::io::Result<()>
400 where
401 W: std::io::Write,
402 {
403 if version == 0 {
404 (self.item_id as u16).serialize(&mut writer)?;
405 } else {
406 self.item_id.serialize(&mut writer)?;
407 }
408 self.symbol_count.serialize(&mut writer)?;
409
410 Ok(())
411 }
412}
413
414impl FECReservoirBoxEntry {
415 pub fn size(&self, version: u8) -> usize {
417 if version == 0 {
418 (self.item_id as u16).size() + self.symbol_count.size()
419 } else {
420 self.item_id.size() + self.symbol_count.size()
421 }
422 }
423}
424
425#[derive(IsoBox, Debug, PartialEq, Eq)]
429#[iso_box(box_type = b"segr", skip_impl(deserialize_seed, serialize), crate_path = crate)]
430pub struct FDSessionGroupBox {
431 pub num_session_groups: u16,
433 pub session_groups: Vec<FDSessionGroupBoxSessionGroup>,
435}
436
437impl<'a> DeserializeSeed<'a, BoxHeader> for FDSessionGroupBox {
438 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> std::io::Result<Self>
439 where
440 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
441 {
442 let num_session_groups = u16::deserialize(&mut reader)?;
443
444 let mut session_groups = Vec::with_capacity(num_session_groups as usize);
445 for _ in 0..num_session_groups {
446 session_groups.push(FDSessionGroupBoxSessionGroup::deserialize(&mut reader)?);
447 }
448
449 Ok(Self {
450 num_session_groups,
451 session_groups,
452 })
453 }
454}
455
456impl Serialize for FDSessionGroupBox {
457 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
458 where
459 W: std::io::Write,
460 {
461 self.serialize_box_header(&mut writer)?;
462 self.num_session_groups.serialize(&mut writer)?;
463
464 for group in &self.session_groups {
465 group.serialize(&mut writer)?;
466 }
467
468 Ok(())
469 }
470}
471
472#[derive(Debug, PartialEq, Eq)]
474pub struct FDSessionGroupBoxSessionGroup {
475 pub entry_count: u8,
480 pub group_id: Vec<u32>,
482 pub num_channels_in_session_group: u16,
485 pub hint_track_id: Vec<u32>,
488}
489
490impl<'a> Deserialize<'a> for FDSessionGroupBoxSessionGroup {
491 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
492 where
493 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
494 {
495 let entry_count = u8::deserialize(&mut reader)?;
496 let mut group_id = Vec::with_capacity(entry_count as usize);
497 for _ in 0..entry_count {
498 group_id.push(u32::deserialize(&mut reader)?);
499 }
500
501 let num_channels_in_session_group = u16::deserialize(&mut reader)?;
502 let mut hint_track_id = Vec::with_capacity(entry_count as usize);
503 for _ in 0..entry_count {
504 hint_track_id.push(u32::deserialize(&mut reader)?);
505 }
506
507 Ok(Self {
508 entry_count,
509 group_id,
510 num_channels_in_session_group,
511 hint_track_id,
512 })
513 }
514}
515
516impl Serialize for FDSessionGroupBoxSessionGroup {
517 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
518 where
519 W: std::io::Write,
520 {
521 self.entry_count.serialize(&mut writer)?;
522 for id in &self.group_id {
523 id.serialize(&mut writer)?;
524 }
525
526 self.num_channels_in_session_group.serialize(&mut writer)?;
527 for id in &self.hint_track_id {
528 id.serialize(&mut writer)?;
529 }
530
531 Ok(())
532 }
533}
534
535impl IsoSized for FDSessionGroupBoxSessionGroup {
536 fn size(&self) -> usize {
537 self.entry_count.size()
538 + self.group_id.size()
539 + self.num_channels_in_session_group.size()
540 + self.hint_track_id.size()
541 }
542}
543
544#[derive(IsoBox, Debug, PartialEq, Eq)]
548#[iso_box(box_type = b"gitn", skip_impl(deserialize_seed, serialize), crate_path = crate)]
549pub struct GroupIdToNameBox {
550 pub full_header: FullBoxHeader,
552 pub entry_count: u16,
554 pub entries: Vec<GroupIdToNameBoxEntry>,
556}
557
558impl<'a> DeserializeSeed<'a, BoxHeader> for GroupIdToNameBox {
559 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> std::io::Result<Self>
560 where
561 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
562 {
563 let full_header = FullBoxHeader::deserialize(&mut reader)?;
564 let entry_count = u16::deserialize(&mut reader)?;
565
566 let mut entries = Vec::with_capacity(entry_count as usize);
567 for _ in 0..entry_count {
568 entries.push(GroupIdToNameBoxEntry::deserialize(&mut reader)?);
569 }
570
571 Ok(Self {
572 full_header,
573 entry_count,
574 entries,
575 })
576 }
577}
578
579impl Serialize for GroupIdToNameBox {
580 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
581 where
582 W: std::io::Write,
583 {
584 self.serialize_box_header(&mut writer)?;
585 self.full_header.serialize(&mut writer)?;
586 self.entry_count.serialize(&mut writer)?;
587
588 for entry in &self.entries {
589 entry.serialize(&mut writer)?;
590 }
591
592 Ok(())
593 }
594}
595
596#[derive(Debug, PartialEq, Eq)]
598pub struct GroupIdToNameBoxEntry {
599 pub group_id: u32,
601 pub group_name: Utf8String,
603}
604
605impl<'a> Deserialize<'a> for GroupIdToNameBoxEntry {
606 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
607 where
608 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
609 {
610 Ok(Self {
611 group_id: u32::deserialize(&mut reader)?,
612 group_name: Utf8String::deserialize(&mut reader)?,
613 })
614 }
615}
616
617impl Serialize for GroupIdToNameBoxEntry {
618 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
619 where
620 W: std::io::Write,
621 {
622 self.group_id.serialize(&mut writer)?;
623 self.group_name.serialize(&mut writer)?;
624 Ok(())
625 }
626}
627
628impl IsoSized for GroupIdToNameBoxEntry {
629 fn size(&self) -> usize {
630 self.group_id.size() + self.group_name.size()
631 }
632}
633
634#[derive(IsoBox, Debug, PartialEq, Eq)]
638#[iso_box(box_type = b"fire", skip_impl(deserialize_seed, serialize, sized), crate_path = crate)]
639pub struct FileReservoirBox {
640 pub full_header: FullBoxHeader,
642 pub entry_count: u32,
645 pub entries: Vec<FileReservoirBoxEntry>,
647}
648
649impl<'a> DeserializeSeed<'a, BoxHeader> for FileReservoirBox {
650 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> std::io::Result<Self>
651 where
652 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
653 {
654 let full_header = FullBoxHeader::deserialize(&mut reader)?;
655 let entry_count = if full_header.version == 0 {
656 u16::deserialize(&mut reader)? as u32
657 } else {
658 u32::deserialize(&mut reader)?
659 };
660
661 let mut entries = Vec::with_capacity(entry_count as usize);
662 for _ in 0..entry_count {
663 entries.push(FileReservoirBoxEntry::deserialize_seed(&mut reader, full_header.version)?);
664 }
665
666 Ok(Self {
667 full_header,
668 entry_count,
669 entries,
670 })
671 }
672}
673
674impl Serialize for FileReservoirBox {
675 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
676 where
677 W: std::io::Write,
678 {
679 self.serialize_box_header(&mut writer)?;
680 self.full_header.serialize(&mut writer)?;
681 if self.full_header.version == 0 {
682 (self.entry_count as u16).serialize(&mut writer)?;
683 } else {
684 self.entry_count.serialize(&mut writer)?;
685 }
686
687 for entry in &self.entries {
688 entry.serialize(&mut writer, self.full_header.version)?;
689 }
690
691 Ok(())
692 }
693}
694
695impl IsoSized for FileReservoirBox {
696 fn size(&self) -> usize {
697 let mut size = self.full_header.size();
698 if self.full_header.version == 0 {
699 size += (self.entry_count as u16).size();
700 } else {
701 size += self.entry_count.size();
702 }
703 size += self
704 .entries
705 .iter()
706 .map(|entry| entry.size(self.full_header.version))
707 .sum::<usize>();
708
709 Self::add_header_size(size)
710 }
711}
712
713#[derive(Debug, PartialEq, Eq)]
715pub struct FileReservoirBoxEntry {
716 pub item_id: u32,
718 pub symbol_count: u32,
720}
721
722impl<'a> DeserializeSeed<'a, u8> for FileReservoirBoxEntry {
723 fn deserialize_seed<R>(mut reader: R, seed: u8) -> std::io::Result<Self>
724 where
725 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
726 {
727 let item_id = if seed == 0 {
728 u16::deserialize(&mut reader)? as u32
729 } else {
730 u32::deserialize(&mut reader)?
731 };
732 let symbol_count = u32::deserialize(&mut reader)?;
733
734 Ok(Self { item_id, symbol_count })
735 }
736}
737
738impl FileReservoirBoxEntry {
739 fn serialize<W>(&self, mut writer: W, version: u8) -> std::io::Result<()>
740 where
741 W: std::io::Write,
742 {
743 if version == 0 {
744 (self.item_id as u16).serialize(&mut writer)?;
745 } else {
746 self.item_id.serialize(&mut writer)?;
747 }
748 self.symbol_count.serialize(&mut writer)?;
749
750 Ok(())
751 }
752}
753
754impl FileReservoirBoxEntry {
755 pub fn size(&self, version: u8) -> usize {
757 if version == 0 {
758 (self.item_id as u16).size() + self.symbol_count.size()
759 } else {
760 self.item_id.size() + self.symbol_count.size()
761 }
762 }
763}