1use core::num::{NonZeroU16, NonZeroU32};
3
4#[cfg(not(feature = "std"))]
5use alloc::{boxed::Box, format, vec::Vec};
6
7use crate::{
8 BaseBox, BoxHeader, BoxSize, BoxType, Decode, Either, Encode, Error, FixedPointNumber, FullBox,
9 FullBoxFlags, FullBoxHeader, Mp4FileTime, Result, Uint, Utf8String, basic_types::as_box_object,
10 descriptors::EsDescriptor,
11};
12
13#[derive(Debug, Clone, PartialEq, Eq, Hash)]
17pub struct UnknownBox {
18 pub box_type: BoxType,
20
21 pub box_size: BoxSize,
23
24 pub payload: Vec<u8>,
26}
27
28impl Encode for UnknownBox {
29 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
30 let mut offset = BoxHeader::new(self.box_type, self.box_size).encode(buf)?;
31 offset += self.payload.encode(&mut buf[offset..])?;
32 Ok(offset)
33 }
34}
35
36impl Decode for UnknownBox {
37 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
38 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
39 Ok((
40 Self {
41 box_type: header.box_type,
42 box_size: header.box_size,
43 payload: payload.to_vec(),
44 },
45 header.external_size() + payload.len(),
46 ))
47 }
48}
49
50impl BaseBox for UnknownBox {
51 fn box_type(&self) -> BoxType {
52 self.box_type
53 }
54
55 fn is_unknown_box(&self) -> bool {
56 true
57 }
58
59 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
60 Box::new(core::iter::empty())
61 }
62}
63
64#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
68pub struct Brand([u8; 4]);
69
70impl Brand {
71 pub const ISOM: Self = Self::new(*b"isom");
73
74 pub const AVC1: Self = Self::new(*b"avc1");
76
77 pub const ISO2: Self = Self::new(*b"iso2");
79
80 pub const MP71: Self = Self::new(*b"mp71");
82
83 pub const ISO3: Self = Self::new(*b"iso3");
85
86 pub const ISO4: Self = Self::new(*b"iso4");
88
89 pub const ISO5: Self = Self::new(*b"iso5");
91
92 pub const ISO6: Self = Self::new(*b"iso6");
94
95 pub const ISO7: Self = Self::new(*b"iso7");
97
98 pub const ISO8: Self = Self::new(*b"iso8");
100
101 pub const ISO9: Self = Self::new(*b"iso9");
103
104 pub const ISOA: Self = Self::new(*b"isoa");
106
107 pub const ISOB: Self = Self::new(*b"isob");
109
110 pub const RELO: Self = Self::new(*b"relo");
112
113 pub const MP41: Self = Self::new(*b"mp41");
115
116 pub const AV01: Self = Self::new(*b"av01");
118
119 pub const fn new(brand: [u8; 4]) -> Self {
121 Self(brand)
122 }
123
124 pub const fn get(self) -> [u8; 4] {
126 self.0
127 }
128}
129
130impl core::fmt::Debug for Brand {
131 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
132 if let Ok(s) = core::str::from_utf8(&self.0) {
133 f.debug_tuple("Brand").field(&s).finish()
134 } else {
135 f.debug_tuple("Brand").field(&self.0).finish()
136 }
137 }
138}
139
140impl Encode for Brand {
141 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
142 self.0.encode(buf)
143 }
144}
145
146impl Decode for Brand {
147 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
148 let (bytes, offset) = <[u8; 4]>::decode(buf)?;
149 Ok((Self(bytes), offset))
150 }
151}
152
153#[derive(Debug, Clone, PartialEq, Eq, Hash)]
155#[allow(missing_docs)]
156pub struct FtypBox {
157 pub major_brand: Brand,
158 pub minor_version: u32,
159 pub compatible_brands: Vec<Brand>,
160}
161
162impl FtypBox {
163 pub const TYPE: BoxType = BoxType::Normal(*b"ftyp");
165}
166
167impl Encode for FtypBox {
168 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
169 let header = BoxHeader::new_variable_size(Self::TYPE);
170 let mut offset = header.encode(buf)?;
171 offset += self.major_brand.encode(&mut buf[offset..])?;
172 offset += self.minor_version.encode(&mut buf[offset..])?;
173 for brand in &self.compatible_brands {
174 offset += brand.encode(&mut buf[offset..])?;
175 }
176 header.finalize_box_size(&mut buf[..offset])?;
177 Ok(offset)
178 }
179}
180
181impl Decode for FtypBox {
182 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
183 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
184 header.box_type.expect(Self::TYPE)?;
185
186 let mut offset = 0;
187 let major_brand = Brand::decode_at(payload, &mut offset)?;
188 let minor_version = u32::decode_at(payload, &mut offset)?;
189
190 let mut compatible_brands = Vec::new();
191 while offset < payload.len() {
192 compatible_brands.push(Brand::decode_at(payload, &mut offset)?);
193 }
194
195 Ok((
196 Self {
197 major_brand,
198 minor_version,
199 compatible_brands,
200 },
201 header.external_size() + payload.len(),
202 ))
203 }
204}
205
206impl BaseBox for FtypBox {
207 fn box_type(&self) -> BoxType {
208 Self::TYPE
209 }
210
211 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
212 Box::new(core::iter::empty())
213 }
214}
215
216#[derive(Debug, Clone, PartialEq, Eq, Hash)]
218#[allow(missing_docs)]
219pub enum RootBox {
220 Free(FreeBox),
221 Mdat(MdatBox),
222 Moov(MoovBox),
223 Unknown(UnknownBox),
224}
225
226impl RootBox {
227 fn inner_box(&self) -> &dyn BaseBox {
228 match self {
229 RootBox::Free(b) => b,
230 RootBox::Mdat(b) => b,
231 RootBox::Moov(b) => b,
232 RootBox::Unknown(b) => b,
233 }
234 }
235}
236
237impl Encode for RootBox {
238 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
239 match self {
240 RootBox::Free(b) => b.encode(buf),
241 RootBox::Mdat(b) => b.encode(buf),
242 RootBox::Moov(b) => b.encode(buf),
243 RootBox::Unknown(b) => b.encode(buf),
244 }
245 }
246}
247
248impl Decode for RootBox {
249 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
250 let (header, _header_size) = BoxHeader::decode(buf)?;
251 match header.box_type {
252 FreeBox::TYPE => FreeBox::decode(buf).map(|(b, n)| (RootBox::Free(b), n)),
253 MdatBox::TYPE => MdatBox::decode(buf).map(|(b, n)| (RootBox::Mdat(b), n)),
254 MoovBox::TYPE => MoovBox::decode(buf).map(|(b, n)| (RootBox::Moov(b), n)),
255 _ => UnknownBox::decode(buf).map(|(b, n)| (RootBox::Unknown(b), n)),
256 }
257 }
258}
259
260impl BaseBox for RootBox {
261 fn box_type(&self) -> BoxType {
262 self.inner_box().box_type()
263 }
264
265 fn is_unknown_box(&self) -> bool {
266 self.inner_box().is_unknown_box()
267 }
268
269 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
270 self.inner_box().children()
271 }
272}
273
274#[derive(Debug, Clone, PartialEq, Eq, Hash)]
276#[allow(missing_docs)]
277pub struct FreeBox {
278 pub payload: Vec<u8>,
279}
280
281impl FreeBox {
282 pub const TYPE: BoxType = BoxType::Normal(*b"free");
284}
285
286impl Encode for FreeBox {
287 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
288 let box_size = BoxSize::with_payload_size(Self::TYPE, self.payload.len() as u64);
289 let mut offset = BoxHeader::new(Self::TYPE, box_size).encode(buf)?;
290 offset += self.payload.encode(&mut buf[offset..])?;
291 Ok(offset)
292 }
293}
294
295impl Decode for FreeBox {
296 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
297 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
298 header.box_type.expect(Self::TYPE)?;
299
300 Ok((
301 Self {
302 payload: payload.to_vec(),
303 },
304 header.external_size() + payload.len(),
305 ))
306 }
307}
308
309impl BaseBox for FreeBox {
310 fn box_type(&self) -> BoxType {
311 Self::TYPE
312 }
313
314 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
315 Box::new(core::iter::empty())
316 }
317}
318
319#[derive(Debug, Clone, PartialEq, Eq, Hash)]
325pub struct MdatBox {
326 pub payload: Vec<u8>,
328}
329
330impl MdatBox {
331 pub const TYPE: BoxType = BoxType::Normal(*b"mdat");
333}
334
335impl Encode for MdatBox {
336 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
337 let box_size = BoxSize::with_payload_size(Self::TYPE, self.payload.len() as u64);
338 let mut offset = BoxHeader::new(Self::TYPE, box_size).encode(buf)?;
339 offset += self.payload.encode(&mut buf[offset..])?;
340 Ok(offset)
341 }
342}
343
344impl Decode for MdatBox {
345 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
346 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
347 header.box_type.expect(Self::TYPE)?;
348
349 Ok((
350 Self {
351 payload: payload.to_vec(),
352 },
353 header.external_size() + payload.len(),
354 ))
355 }
356}
357
358impl BaseBox for MdatBox {
359 fn box_type(&self) -> BoxType {
360 Self::TYPE
361 }
362
363 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
364 Box::new(core::iter::empty())
365 }
366}
367
368#[derive(Debug, Clone, PartialEq, Eq, Hash)]
370#[allow(missing_docs)]
371pub struct MoovBox {
372 pub mvhd_box: MvhdBox,
373 pub trak_boxes: Vec<TrakBox>,
374 pub unknown_boxes: Vec<UnknownBox>,
375}
376
377impl MoovBox {
378 pub const TYPE: BoxType = BoxType::Normal(*b"moov");
380}
381
382impl Encode for MoovBox {
383 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
384 let header = BoxHeader::new_variable_size(Self::TYPE);
385 let mut offset = header.encode(buf)?;
386 offset += self.mvhd_box.encode(&mut buf[offset..])?;
387 for b in &self.trak_boxes {
388 offset += b.encode(&mut buf[offset..])?;
389 }
390 for b in &self.unknown_boxes {
391 offset += b.encode(&mut buf[offset..])?;
392 }
393 header.finalize_box_size(&mut buf[..offset])?;
394 Ok(offset)
395 }
396}
397
398impl Decode for MoovBox {
399 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
400 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
401 header.box_type.expect(Self::TYPE)?;
402
403 let mut offset = 0;
404 let mut mvhd_box = None;
405 let mut trak_boxes = Vec::new();
406 let mut unknown_boxes = Vec::new();
407
408 while offset < payload.len() {
409 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
410 match child_header.box_type {
411 MvhdBox::TYPE if mvhd_box.is_none() => {
412 mvhd_box = Some(MvhdBox::decode_at(payload, &mut offset)?);
413 }
414 TrakBox::TYPE => {
415 trak_boxes.push(TrakBox::decode_at(payload, &mut offset)?);
416 }
417 _ => {
418 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
419 }
420 }
421 }
422
423 Ok((
424 Self {
425 mvhd_box: check_mandatory_box(mvhd_box, "mvhd", "moov")?,
426 trak_boxes,
427 unknown_boxes,
428 },
429 header.external_size() + payload.len(),
430 ))
431 }
432}
433
434impl BaseBox for MoovBox {
435 fn box_type(&self) -> BoxType {
436 Self::TYPE
437 }
438
439 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
440 Box::new(
441 core::iter::empty()
442 .chain(core::iter::once(&self.mvhd_box).map(as_box_object))
443 .chain(self.trak_boxes.iter().map(as_box_object))
444 .chain(self.unknown_boxes.iter().map(as_box_object)),
445 )
446 }
447}
448
449#[derive(Debug, Clone, PartialEq, Eq, Hash)]
451#[allow(missing_docs)]
452pub struct MvhdBox {
453 pub creation_time: Mp4FileTime,
454 pub modification_time: Mp4FileTime,
455 pub timescale: NonZeroU32,
456 pub duration: u64,
457 pub rate: FixedPointNumber<i16, u16>,
458 pub volume: FixedPointNumber<i8, u8>,
459 pub matrix: [i32; 9],
460 pub next_track_id: u32,
461}
462
463impl MvhdBox {
464 pub const TYPE: BoxType = BoxType::Normal(*b"mvhd");
466
467 pub const DEFAULT_RATE: FixedPointNumber<i16, u16> = FixedPointNumber::new(1, 0);
469
470 pub const DEFAULT_VOLUME: FixedPointNumber<i8, u8> = FixedPointNumber::new(1, 0);
472
473 pub const DEFAULT_MATRIX: [i32; 9] = [0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000];
475}
476
477impl Encode for MvhdBox {
478 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
479 let header = BoxHeader::new_variable_size(Self::TYPE);
480 let mut offset = header.encode(buf)?;
481 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
482 if self.full_box_version() == 1 {
483 offset += self.creation_time.as_secs().encode(&mut buf[offset..])?;
484 offset += self
485 .modification_time
486 .as_secs()
487 .encode(&mut buf[offset..])?;
488 offset += self.timescale.encode(&mut buf[offset..])?;
489 offset += self.duration.encode(&mut buf[offset..])?;
490 } else {
491 offset += (self.creation_time.as_secs() as u32).encode(&mut buf[offset..])?;
492 offset += (self.modification_time.as_secs() as u32).encode(&mut buf[offset..])?;
493 offset += self.timescale.encode(&mut buf[offset..])?;
494 offset += (self.duration as u32).encode(&mut buf[offset..])?;
495 }
496 offset += self.rate.encode(&mut buf[offset..])?;
497 offset += self.volume.encode(&mut buf[offset..])?;
498 offset += [0u8; 2 + 4 * 2].encode(&mut buf[offset..])?;
499 offset += self.matrix.encode(&mut buf[offset..])?;
500 offset += [0u8; 4 * 6].encode(&mut buf[offset..])?;
501 offset += self.next_track_id.encode(&mut buf[offset..])?;
502 header.finalize_box_size(&mut buf[..offset])?;
503 Ok(offset)
504 }
505}
506
507impl Decode for MvhdBox {
508 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
509 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
510 header.box_type.expect(Self::TYPE)?;
511
512 let mut offset = 0;
513 let full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
514
515 let mut this = Self {
516 creation_time: Mp4FileTime::default(),
517 modification_time: Mp4FileTime::default(),
518 timescale: NonZeroU32::MIN,
519 duration: 0,
520 rate: Self::DEFAULT_RATE,
521 volume: Self::DEFAULT_VOLUME,
522 matrix: Self::DEFAULT_MATRIX,
523 next_track_id: 0,
524 };
525
526 if full_header.version == 1 {
527 this.creation_time =
528 u64::decode_at(payload, &mut offset).map(Mp4FileTime::from_secs)?;
529 this.modification_time =
530 u64::decode_at(payload, &mut offset).map(Mp4FileTime::from_secs)?;
531 this.timescale = NonZeroU32::decode_at(payload, &mut offset)?;
532 this.duration = u64::decode_at(payload, &mut offset)?;
533 } else {
534 this.creation_time =
535 u32::decode_at(payload, &mut offset).map(|v| Mp4FileTime::from_secs(v as u64))?;
536 this.modification_time =
537 u32::decode_at(payload, &mut offset).map(|v| Mp4FileTime::from_secs(v as u64))?;
538 this.timescale = NonZeroU32::decode_at(payload, &mut offset)?;
539 this.duration = u32::decode_at(payload, &mut offset).map(|v| v as u64)?;
540 }
541
542 this.rate = FixedPointNumber::decode_at(payload, &mut offset)?;
543 this.volume = FixedPointNumber::decode_at(payload, &mut offset)?;
544 let _ = <[u8; 2 + 4 * 2]>::decode_at(payload, &mut offset)?;
545 this.matrix = <[i32; 9]>::decode_at(payload, &mut offset)?;
546 let _ = <[u8; 4 * 6]>::decode_at(payload, &mut offset)?;
547 this.next_track_id = u32::decode_at(payload, &mut offset)?;
548
549 Ok((this, header.external_size() + payload.len()))
550 }
551}
552
553impl BaseBox for MvhdBox {
554 fn box_type(&self) -> BoxType {
555 Self::TYPE
556 }
557
558 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
559 Box::new(core::iter::empty())
560 }
561}
562
563impl FullBox for MvhdBox {
564 fn full_box_version(&self) -> u8 {
565 if self.creation_time.as_secs() > u32::MAX as u64
566 || self.modification_time.as_secs() > u32::MAX as u64
567 || self.duration > u32::MAX as u64
568 {
569 1
570 } else {
571 0
572 }
573 }
574
575 fn full_box_flags(&self) -> FullBoxFlags {
576 FullBoxFlags::new(0)
577 }
578}
579
580#[derive(Debug, Clone, PartialEq, Eq, Hash)]
582#[allow(missing_docs)]
583pub struct TrakBox {
584 pub tkhd_box: TkhdBox,
585 pub edts_box: Option<EdtsBox>,
586 pub mdia_box: MdiaBox,
587 pub unknown_boxes: Vec<UnknownBox>,
588}
589
590impl TrakBox {
591 pub const TYPE: BoxType = BoxType::Normal(*b"trak");
593}
594
595impl Encode for TrakBox {
596 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
597 let header = BoxHeader::new_variable_size(Self::TYPE);
598 let mut offset = header.encode(buf)?;
599 offset += self.tkhd_box.encode(&mut buf[offset..])?;
600 if let Some(b) = &self.edts_box {
601 offset += b.encode(&mut buf[offset..])?;
602 }
603 offset += self.mdia_box.encode(&mut buf[offset..])?;
604 for b in &self.unknown_boxes {
605 offset += b.encode(&mut buf[offset..])?;
606 }
607 header.finalize_box_size(&mut buf[..offset])?;
608 Ok(offset)
609 }
610}
611
612impl Decode for TrakBox {
613 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
614 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
615 header.box_type.expect(Self::TYPE)?;
616
617 let mut offset = 0;
618 let mut tkhd_box = None;
619 let mut edts_box = None;
620 let mut mdia_box = None;
621 let mut unknown_boxes = Vec::new();
622
623 while offset < payload.len() {
624 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
625 match child_header.box_type {
626 TkhdBox::TYPE if tkhd_box.is_none() => {
627 tkhd_box = Some(TkhdBox::decode_at(payload, &mut offset)?);
628 }
629 EdtsBox::TYPE if edts_box.is_none() => {
630 edts_box = Some(EdtsBox::decode_at(payload, &mut offset)?);
631 }
632 MdiaBox::TYPE if mdia_box.is_none() => {
633 mdia_box = Some(MdiaBox::decode_at(payload, &mut offset)?);
634 }
635 _ => {
636 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
637 }
638 }
639 }
640
641 Ok((
642 Self {
643 tkhd_box: check_mandatory_box(tkhd_box, "tkhd", "trak")?,
644 edts_box,
645 mdia_box: check_mandatory_box(mdia_box, "mdia", "trak")?,
646 unknown_boxes,
647 },
648 header.external_size() + payload.len(),
649 ))
650 }
651}
652
653impl BaseBox for TrakBox {
654 fn box_type(&self) -> BoxType {
655 Self::TYPE
656 }
657
658 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
659 Box::new(
660 core::iter::empty()
661 .chain(core::iter::once(&self.tkhd_box).map(as_box_object))
662 .chain(self.edts_box.iter().map(as_box_object))
663 .chain(core::iter::once(&self.mdia_box).map(as_box_object))
664 .chain(self.unknown_boxes.iter().map(as_box_object)),
665 )
666 }
667}
668
669#[derive(Debug, Clone, PartialEq, Eq, Hash)]
671#[allow(missing_docs)]
672pub struct TkhdBox {
673 pub flag_track_enabled: bool,
674 pub flag_track_in_movie: bool,
675 pub flag_track_in_preview: bool,
676 pub flag_track_size_is_aspect_ratio: bool,
677
678 pub creation_time: Mp4FileTime,
679 pub modification_time: Mp4FileTime,
680 pub track_id: u32,
681 pub duration: u64,
682 pub layer: i16,
683 pub alternate_group: i16,
684 pub volume: FixedPointNumber<i8, u8>,
685 pub matrix: [i32; 9],
686 pub width: FixedPointNumber<i16, u16>,
687 pub height: FixedPointNumber<i16, u16>,
688}
689
690impl TkhdBox {
691 pub const TYPE: BoxType = BoxType::Normal(*b"tkhd");
693
694 pub const DEFAULT_LAYER: i16 = 0;
696
697 pub const DEFAULT_ALTERNATE_GROUP: i16 = 0;
699
700 pub const DEFAULT_AUDIO_VOLUME: FixedPointNumber<i8, u8> = FixedPointNumber::new(1, 0);
702
703 pub const DEFAULT_VIDEO_VOLUME: FixedPointNumber<i8, u8> = FixedPointNumber::new(0, 0);
705
706 pub const DEFAULT_MATRIX: [i32; 9] = [0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000];
708}
709
710impl Encode for TkhdBox {
711 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
712 let header = BoxHeader::new_variable_size(Self::TYPE);
713 let mut offset = header.encode(buf)?;
714 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
715 if self.full_box_version() == 1 {
716 offset += self.creation_time.as_secs().encode(&mut buf[offset..])?;
717 offset += self
718 .modification_time
719 .as_secs()
720 .encode(&mut buf[offset..])?;
721 offset += self.track_id.encode(&mut buf[offset..])?;
722 offset += [0u8; 4].encode(&mut buf[offset..])?;
723 offset += self.duration.encode(&mut buf[offset..])?;
724 } else {
725 offset += (self.creation_time.as_secs() as u32).encode(&mut buf[offset..])?;
726 offset += (self.modification_time.as_secs() as u32).encode(&mut buf[offset..])?;
727 offset += self.track_id.encode(&mut buf[offset..])?;
728 offset += [0u8; 4].encode(&mut buf[offset..])?;
729 offset += (self.duration as u32).encode(&mut buf[offset..])?;
730 }
731 offset += [0u8; 4 * 2].encode(&mut buf[offset..])?;
732 offset += self.layer.encode(&mut buf[offset..])?;
733 offset += self.alternate_group.encode(&mut buf[offset..])?;
734 offset += self.volume.encode(&mut buf[offset..])?;
735 offset += [0u8; 2].encode(&mut buf[offset..])?;
736 offset += self.matrix.encode(&mut buf[offset..])?;
737 offset += self.width.encode(&mut buf[offset..])?;
738 offset += self.height.encode(&mut buf[offset..])?;
739 header.finalize_box_size(&mut buf[..offset])?;
740 Ok(offset)
741 }
742}
743
744impl Decode for TkhdBox {
745 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
746 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
747 header.box_type.expect(Self::TYPE)?;
748
749 let mut offset = 0;
750 let full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
751
752 let mut this = Self {
753 flag_track_enabled: false,
754 flag_track_in_movie: false,
755 flag_track_in_preview: false,
756 flag_track_size_is_aspect_ratio: false,
757 creation_time: Mp4FileTime::default(),
758 modification_time: Mp4FileTime::default(),
759 track_id: 0,
760 duration: 0,
761 layer: Self::DEFAULT_LAYER,
762 alternate_group: Self::DEFAULT_ALTERNATE_GROUP,
763 volume: Self::DEFAULT_AUDIO_VOLUME,
764 matrix: Self::DEFAULT_MATRIX,
765 width: FixedPointNumber::new(0, 0),
766 height: FixedPointNumber::new(0, 0),
767 };
768
769 this.flag_track_enabled = full_header.flags.is_set(0);
770 this.flag_track_in_movie = full_header.flags.is_set(1);
771 this.flag_track_in_preview = full_header.flags.is_set(2);
772 this.flag_track_size_is_aspect_ratio = full_header.flags.is_set(3);
773
774 if full_header.version == 1 {
775 this.creation_time =
776 u64::decode_at(payload, &mut offset).map(Mp4FileTime::from_secs)?;
777 this.modification_time =
778 u64::decode_at(payload, &mut offset).map(Mp4FileTime::from_secs)?;
779 this.track_id = u32::decode_at(payload, &mut offset)?;
780 let _ = <[u8; 4]>::decode_at(payload, &mut offset)?;
781 this.duration = u64::decode_at(payload, &mut offset)?;
782 } else {
783 this.creation_time =
784 u32::decode_at(payload, &mut offset).map(|v| Mp4FileTime::from_secs(v as u64))?;
785 this.modification_time =
786 u32::decode_at(payload, &mut offset).map(|v| Mp4FileTime::from_secs(v as u64))?;
787 this.track_id = u32::decode_at(payload, &mut offset)?;
788 let _ = <[u8; 4]>::decode_at(payload, &mut offset)?;
789 this.duration = u32::decode_at(payload, &mut offset).map(|v| v as u64)?;
790 }
791
792 let _ = <[u8; 4 * 2]>::decode_at(payload, &mut offset)?;
793 this.layer = i16::decode_at(payload, &mut offset)?;
794 this.alternate_group = i16::decode_at(payload, &mut offset)?;
795 this.volume = FixedPointNumber::decode_at(payload, &mut offset)?;
796 let _ = <[u8; 2]>::decode_at(payload, &mut offset)?;
797 this.matrix = <[i32; 9]>::decode_at(payload, &mut offset)?;
798 this.width = FixedPointNumber::decode_at(payload, &mut offset)?;
799 this.height = FixedPointNumber::decode_at(payload, &mut offset)?;
800
801 Ok((this, header.external_size() + payload.len()))
802 }
803}
804
805impl BaseBox for TkhdBox {
806 fn box_type(&self) -> BoxType {
807 Self::TYPE
808 }
809
810 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
811 Box::new(core::iter::empty())
812 }
813}
814
815impl FullBox for TkhdBox {
816 fn full_box_version(&self) -> u8 {
817 if self.creation_time.as_secs() > u32::MAX as u64
818 || self.modification_time.as_secs() > u32::MAX as u64
819 || self.duration > u32::MAX as u64
820 {
821 1
822 } else {
823 0
824 }
825 }
826
827 fn full_box_flags(&self) -> FullBoxFlags {
828 FullBoxFlags::from_flags([
829 (0, self.flag_track_enabled),
830 (1, self.flag_track_in_movie),
831 (2, self.flag_track_in_preview),
832 (3, self.flag_track_size_is_aspect_ratio),
833 ])
834 }
835}
836
837#[derive(Debug, Clone, PartialEq, Eq, Hash)]
839#[allow(missing_docs)]
840pub struct EdtsBox {
841 pub elst_box: Option<ElstBox>,
842 pub unknown_boxes: Vec<UnknownBox>,
843}
844
845impl EdtsBox {
846 pub const TYPE: BoxType = BoxType::Normal(*b"edts");
848}
849
850impl Encode for EdtsBox {
851 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
852 let header = BoxHeader::new_variable_size(Self::TYPE);
853 let mut offset = header.encode(buf)?;
854 if let Some(b) = &self.elst_box {
855 offset += b.encode(&mut buf[offset..])?;
856 }
857 for b in &self.unknown_boxes {
858 offset += b.encode(&mut buf[offset..])?;
859 }
860 header.finalize_box_size(&mut buf[..offset])?;
861 Ok(offset)
862 }
863}
864
865impl Decode for EdtsBox {
866 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
867 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
868 header.box_type.expect(Self::TYPE)?;
869
870 let mut offset = 0;
871 let mut elst_box = None;
872 let mut unknown_boxes = Vec::new();
873
874 while offset < payload.len() {
875 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
876 match child_header.box_type {
877 ElstBox::TYPE if elst_box.is_none() => {
878 elst_box = Some(ElstBox::decode_at(payload, &mut offset)?);
879 }
880 _ => {
881 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
882 }
883 }
884 }
885
886 Ok((
887 Self {
888 elst_box,
889 unknown_boxes,
890 },
891 header.external_size() + payload.len(),
892 ))
893 }
894}
895
896impl BaseBox for EdtsBox {
897 fn box_type(&self) -> BoxType {
898 Self::TYPE
899 }
900
901 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
902 Box::new(
903 core::iter::empty()
904 .chain(self.elst_box.iter().map(as_box_object))
905 .chain(self.unknown_boxes.iter().map(as_box_object)),
906 )
907 }
908}
909
910#[derive(Debug, Clone, PartialEq, Eq, Hash)]
912#[allow(missing_docs)]
913pub struct ElstEntry {
914 pub edit_duration: u64,
915 pub media_time: i64,
916 pub media_rate: FixedPointNumber<i16, i16>,
917}
918
919#[derive(Debug, Clone, PartialEq, Eq, Hash)]
921#[allow(missing_docs)]
922pub struct ElstBox {
923 pub entries: Vec<ElstEntry>,
924}
925
926impl ElstBox {
927 pub const TYPE: BoxType = BoxType::Normal(*b"elst");
929}
930
931impl Encode for ElstBox {
932 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
933 let header = BoxHeader::new_variable_size(Self::TYPE);
934 let mut offset = header.encode(buf)?;
935 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
936
937 let version = self.full_box_version();
938 offset += (self.entries.len() as u32).encode(&mut buf[offset..])?;
939 for entry in &self.entries {
940 if version == 1 {
941 offset += entry.edit_duration.encode(&mut buf[offset..])?;
942 offset += entry.media_time.encode(&mut buf[offset..])?;
943 } else {
944 offset += (entry.edit_duration as u32).encode(&mut buf[offset..])?;
945 offset += (entry.media_time as i32).encode(&mut buf[offset..])?;
946 }
947 offset += entry.media_rate.encode(&mut buf[offset..])?;
948 }
949 header.finalize_box_size(&mut buf[..offset])?;
950 Ok(offset)
951 }
952}
953
954impl Decode for ElstBox {
955 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
956 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
957 header.box_type.expect(Self::TYPE)?;
958
959 let mut offset = 0;
960 let full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
961
962 let mut entries = Vec::new();
963 let count = u32::decode_at(payload, &mut offset)?;
964 for _ in 0..count {
965 let edit_duration;
966 let media_time;
967 if full_header.version == 1 {
968 edit_duration = u64::decode_at(payload, &mut offset)?;
969 media_time = i64::decode_at(payload, &mut offset)?;
970 } else {
971 edit_duration = u32::decode_at(payload, &mut offset)? as u64;
972 media_time = i32::decode_at(payload, &mut offset)? as i64;
973 }
974 let media_rate = FixedPointNumber::decode_at(payload, &mut offset)?;
975 entries.push(ElstEntry {
976 edit_duration,
977 media_time,
978 media_rate,
979 });
980 }
981
982 Ok((Self { entries }, header.external_size() + payload.len()))
983 }
984}
985
986impl BaseBox for ElstBox {
987 fn box_type(&self) -> BoxType {
988 Self::TYPE
989 }
990
991 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
992 Box::new(core::iter::empty())
993 }
994}
995
996impl FullBox for ElstBox {
997 fn full_box_version(&self) -> u8 {
998 let large = self.entries.iter().any(|x| {
999 u32::try_from(x.edit_duration).is_err() || i32::try_from(x.media_time).is_err()
1000 });
1001 if large { 1 } else { 0 }
1002 }
1003
1004 fn full_box_flags(&self) -> FullBoxFlags {
1005 FullBoxFlags::new(0)
1006 }
1007}
1008
1009#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1011#[allow(missing_docs)]
1012pub struct MdiaBox {
1013 pub mdhd_box: MdhdBox,
1014 pub hdlr_box: HdlrBox,
1015 pub minf_box: MinfBox,
1016 pub unknown_boxes: Vec<UnknownBox>,
1017}
1018
1019impl MdiaBox {
1020 pub const TYPE: BoxType = BoxType::Normal(*b"mdia");
1022}
1023
1024impl Encode for MdiaBox {
1025 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1026 let header = BoxHeader::new_variable_size(Self::TYPE);
1027 let mut offset = header.encode(buf)?;
1028 offset += self.mdhd_box.encode(&mut buf[offset..])?;
1029 offset += self.hdlr_box.encode(&mut buf[offset..])?;
1030 offset += self.minf_box.encode(&mut buf[offset..])?;
1031 for b in &self.unknown_boxes {
1032 offset += b.encode(&mut buf[offset..])?;
1033 }
1034 header.finalize_box_size(&mut buf[..offset])?;
1035 Ok(offset)
1036 }
1037}
1038
1039impl Decode for MdiaBox {
1040 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1041 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1042 header.box_type.expect(Self::TYPE)?;
1043
1044 let mut offset = 0;
1045 let mut mdhd_box = None;
1046 let mut hdlr_box = None;
1047 let mut minf_box = None;
1048 let mut unknown_boxes = Vec::new();
1049
1050 while offset < payload.len() {
1051 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
1052 match child_header.box_type {
1053 MdhdBox::TYPE if mdhd_box.is_none() => {
1054 mdhd_box = Some(MdhdBox::decode_at(payload, &mut offset)?);
1055 }
1056 HdlrBox::TYPE if hdlr_box.is_none() => {
1057 hdlr_box = Some(HdlrBox::decode_at(payload, &mut offset)?);
1058 }
1059 MinfBox::TYPE if minf_box.is_none() => {
1060 minf_box = Some(MinfBox::decode_at(payload, &mut offset)?);
1061 }
1062 _ => {
1063 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
1064 }
1065 }
1066 }
1067
1068 Ok((
1069 Self {
1070 mdhd_box: check_mandatory_box(mdhd_box, "mdhd", "mdia")?,
1071 hdlr_box: check_mandatory_box(hdlr_box, "hdlr", "mdia")?,
1072 minf_box: check_mandatory_box(minf_box, "minf", "mdia")?,
1073 unknown_boxes,
1074 },
1075 header.external_size() + payload.len(),
1076 ))
1077 }
1078}
1079
1080impl BaseBox for MdiaBox {
1081 fn box_type(&self) -> BoxType {
1082 Self::TYPE
1083 }
1084
1085 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1086 Box::new(
1087 core::iter::empty()
1088 .chain(core::iter::once(&self.mdhd_box).map(as_box_object))
1089 .chain(core::iter::once(&self.hdlr_box).map(as_box_object))
1090 .chain(core::iter::once(&self.minf_box).map(as_box_object))
1091 .chain(self.unknown_boxes.iter().map(as_box_object)),
1092 )
1093 }
1094}
1095
1096#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1098#[allow(missing_docs)]
1099pub struct MdhdBox {
1100 pub creation_time: Mp4FileTime,
1101 pub modification_time: Mp4FileTime,
1102 pub timescale: NonZeroU32,
1103 pub duration: u64,
1104
1105 pub language: [u8; 3],
1107}
1108
1109impl MdhdBox {
1110 pub const TYPE: BoxType = BoxType::Normal(*b"mdhd");
1112
1113 pub const LANGUAGE_UNDEFINED: [u8; 3] = *b"und";
1115}
1116
1117impl Encode for MdhdBox {
1118 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1119 let header = BoxHeader::new_variable_size(Self::TYPE);
1120 let mut offset = header.encode(buf)?;
1121 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
1122 if self.full_box_version() == 1 {
1123 offset += self.creation_time.as_secs().encode(&mut buf[offset..])?;
1124 offset += self
1125 .modification_time
1126 .as_secs()
1127 .encode(&mut buf[offset..])?;
1128 offset += self.timescale.encode(&mut buf[offset..])?;
1129 offset += self.duration.encode(&mut buf[offset..])?;
1130 } else {
1131 offset += (self.creation_time.as_secs() as u32).encode(&mut buf[offset..])?;
1132 offset += (self.modification_time.as_secs() as u32).encode(&mut buf[offset..])?;
1133 offset += self.timescale.encode(&mut buf[offset..])?;
1134 offset += (self.duration as u32).encode(&mut buf[offset..])?;
1135 }
1136
1137 let mut language: u16 = 0;
1138 for l in &self.language {
1139 let Some(code) = l.checked_sub(0x60) else {
1140 return Err(Error::invalid_input(format!(
1141 "Invalid language code: {:?}",
1142 self.language
1143 )));
1144 };
1145 language = (language << 5) | code as u16;
1146 }
1147 offset += language.encode(&mut buf[offset..])?;
1148 offset += [0u8; 2].encode(&mut buf[offset..])?;
1149 header.finalize_box_size(&mut buf[..offset])?;
1150 Ok(offset)
1151 }
1152}
1153
1154impl Decode for MdhdBox {
1155 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1156 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1157 header.box_type.expect(Self::TYPE)?;
1158
1159 let mut offset = 0;
1160 let full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
1161
1162 let mut this = Self {
1163 creation_time: Mp4FileTime::default(),
1164 modification_time: Mp4FileTime::default(),
1165 timescale: NonZeroU32::MIN,
1166 duration: 0,
1167 language: Self::LANGUAGE_UNDEFINED,
1168 };
1169
1170 if full_header.version == 1 {
1171 this.creation_time =
1172 u64::decode_at(payload, &mut offset).map(Mp4FileTime::from_secs)?;
1173 this.modification_time =
1174 u64::decode_at(payload, &mut offset).map(Mp4FileTime::from_secs)?;
1175 this.timescale = NonZeroU32::decode_at(payload, &mut offset)?;
1176 this.duration = u64::decode_at(payload, &mut offset)?;
1177 } else {
1178 this.creation_time =
1179 u32::decode_at(payload, &mut offset).map(|v| Mp4FileTime::from_secs(v as u64))?;
1180 this.modification_time =
1181 u32::decode_at(payload, &mut offset).map(|v| Mp4FileTime::from_secs(v as u64))?;
1182 this.timescale = NonZeroU32::decode_at(payload, &mut offset)?;
1183 this.duration = u32::decode_at(payload, &mut offset).map(|v| v as u64)?;
1184 }
1185
1186 let language = u16::decode_at(payload, &mut offset)?;
1187 this.language = [
1188 ((language >> 10) & 0b11111) as u8 + 0x60,
1189 ((language >> 5) & 0b11111) as u8 + 0x60,
1190 (language & 0b11111) as u8 + 0x60,
1191 ];
1192
1193 let _ = <[u8; 2]>::decode_at(payload, &mut offset)?;
1194
1195 Ok((this, header.external_size() + payload.len()))
1196 }
1197}
1198
1199impl BaseBox for MdhdBox {
1200 fn box_type(&self) -> BoxType {
1201 Self::TYPE
1202 }
1203
1204 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1205 Box::new(core::iter::empty())
1206 }
1207}
1208
1209impl FullBox for MdhdBox {
1210 fn full_box_version(&self) -> u8 {
1211 if self.creation_time.as_secs() > u32::MAX as u64
1212 || self.modification_time.as_secs() > u32::MAX as u64
1213 || self.duration > u32::MAX as u64
1214 {
1215 1
1216 } else {
1217 0
1218 }
1219 }
1220
1221 fn full_box_flags(&self) -> FullBoxFlags {
1222 FullBoxFlags::new(0)
1223 }
1224}
1225
1226#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1228#[allow(missing_docs)]
1229pub struct HdlrBox {
1230 pub handler_type: [u8; 4],
1231
1232 pub name: Vec<u8>,
1240}
1241
1242impl HdlrBox {
1243 pub const TYPE: BoxType = BoxType::Normal(*b"hdlr");
1245
1246 pub const HANDLER_TYPE_SOUN: [u8; 4] = *b"soun";
1248
1249 pub const HANDLER_TYPE_VIDE: [u8; 4] = *b"vide";
1251}
1252
1253impl Encode for HdlrBox {
1254 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1255 let header = BoxHeader::new_variable_size(Self::TYPE);
1256 let mut offset = header.encode(buf)?;
1257 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
1258 offset += [0u8; 4].encode(&mut buf[offset..])?;
1259 offset += self.handler_type.encode(&mut buf[offset..])?;
1260 offset += [0u8; 4 * 3].encode(&mut buf[offset..])?;
1261 offset += self.name.encode(&mut buf[offset..])?;
1262 header.finalize_box_size(&mut buf[..offset])?;
1263 Ok(offset)
1264 }
1265}
1266
1267impl Decode for HdlrBox {
1268 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1269 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1270 header.box_type.expect(Self::TYPE)?;
1271
1272 let mut offset = 0;
1273 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
1274 let _ = <[u8; 4]>::decode_at(payload, &mut offset)?;
1275 let handler_type = <[u8; 4]>::decode_at(payload, &mut offset)?;
1276 let _ = <[u8; 4 * 3]>::decode_at(payload, &mut offset)?;
1277 let name = payload[offset..].to_vec();
1278
1279 Ok((
1280 Self { handler_type, name },
1281 header.external_size() + payload.len(),
1282 ))
1283 }
1284}
1285
1286impl BaseBox for HdlrBox {
1287 fn box_type(&self) -> BoxType {
1288 Self::TYPE
1289 }
1290
1291 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1292 Box::new(core::iter::empty())
1293 }
1294}
1295
1296impl FullBox for HdlrBox {
1297 fn full_box_version(&self) -> u8 {
1298 0
1299 }
1300
1301 fn full_box_flags(&self) -> FullBoxFlags {
1302 FullBoxFlags::new(0)
1303 }
1304}
1305
1306#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1308#[allow(missing_docs)]
1309pub struct MinfBox {
1310 pub smhd_or_vmhd_box: Either<SmhdBox, VmhdBox>,
1311 pub dinf_box: DinfBox,
1312 pub stbl_box: StblBox,
1313 pub unknown_boxes: Vec<UnknownBox>,
1314}
1315
1316impl MinfBox {
1317 pub const TYPE: BoxType = BoxType::Normal(*b"minf");
1319}
1320
1321impl Encode for MinfBox {
1322 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1323 let header = BoxHeader::new_variable_size(Self::TYPE);
1324 let mut offset = header.encode(buf)?;
1325 match &self.smhd_or_vmhd_box {
1326 Either::A(b) => offset += b.encode(&mut buf[offset..])?,
1327 Either::B(b) => offset += b.encode(&mut buf[offset..])?,
1328 }
1329 offset += self.dinf_box.encode(&mut buf[offset..])?;
1330 offset += self.stbl_box.encode(&mut buf[offset..])?;
1331 for b in &self.unknown_boxes {
1332 offset += b.encode(&mut buf[offset..])?;
1333 }
1334 header.finalize_box_size(&mut buf[..offset])?;
1335 Ok(offset)
1336 }
1337}
1338
1339impl Decode for MinfBox {
1340 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1341 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1342 header.box_type.expect(Self::TYPE)?;
1343
1344 let mut offset = 0;
1345 let mut smhd_box = None;
1346 let mut vmhd_box = None;
1347 let mut dinf_box = None;
1348 let mut stbl_box = None;
1349 let mut unknown_boxes = Vec::new();
1350
1351 while offset < payload.len() {
1352 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
1353 match child_header.box_type {
1354 SmhdBox::TYPE if smhd_box.is_none() => {
1355 smhd_box = Some(SmhdBox::decode_at(payload, &mut offset)?);
1356 }
1357 VmhdBox::TYPE if vmhd_box.is_none() => {
1358 vmhd_box = Some(VmhdBox::decode_at(payload, &mut offset)?);
1359 }
1360 DinfBox::TYPE if dinf_box.is_none() => {
1361 dinf_box = Some(DinfBox::decode_at(payload, &mut offset)?);
1362 }
1363 StblBox::TYPE if stbl_box.is_none() => {
1364 stbl_box = Some(StblBox::decode_at(payload, &mut offset)?);
1365 }
1366 _ => {
1367 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
1368 }
1369 }
1370 }
1371
1372 Ok((
1373 Self {
1374 smhd_or_vmhd_box: {
1375 let smhd = smhd_box.map(Either::A);
1376 let vmhd = vmhd_box.map(Either::B);
1377 check_mandatory_box(smhd.or(vmhd), "smhd' or 'vmhd", "box")?
1378 },
1379 dinf_box: check_mandatory_box(dinf_box, "dinf", "minf")?,
1380 stbl_box: check_mandatory_box(stbl_box, "stbl", "minf")?,
1381 unknown_boxes,
1382 },
1383 header.external_size() + payload.len(),
1384 ))
1385 }
1386}
1387
1388impl BaseBox for MinfBox {
1389 fn box_type(&self) -> BoxType {
1390 Self::TYPE
1391 }
1392
1393 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1394 Box::new(
1395 core::iter::empty()
1396 .chain(core::iter::once(&self.smhd_or_vmhd_box).map(as_box_object))
1397 .chain(core::iter::once(&self.dinf_box).map(as_box_object))
1398 .chain(core::iter::once(&self.stbl_box).map(as_box_object))
1399 .chain(self.unknown_boxes.iter().map(as_box_object)),
1400 )
1401 }
1402}
1403
1404#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
1406#[allow(missing_docs)]
1407pub struct SmhdBox {
1408 pub balance: FixedPointNumber<u8, u8>,
1409}
1410
1411impl SmhdBox {
1412 pub const TYPE: BoxType = BoxType::Normal(*b"smhd");
1414
1415 pub const DEFAULT_BALANCE: FixedPointNumber<u8, u8> = FixedPointNumber::new(0, 0);
1417}
1418
1419impl Encode for SmhdBox {
1420 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1421 let header = BoxHeader::new_variable_size(Self::TYPE);
1422 let mut offset = header.encode(buf)?;
1423 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
1424 offset += self.balance.encode(&mut buf[offset..])?;
1425 offset += [0u8; 2].encode(&mut buf[offset..])?;
1426 header.finalize_box_size(&mut buf[..offset])?;
1427 Ok(offset)
1428 }
1429}
1430
1431impl Decode for SmhdBox {
1432 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1433 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1434 header.box_type.expect(Self::TYPE)?;
1435
1436 let mut offset = 0;
1437 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
1438 let balance = FixedPointNumber::decode_at(payload, &mut offset)?;
1439 let _ = <[u8; 2]>::decode_at(payload, &mut offset)?;
1440
1441 Ok((Self { balance }, header.external_size() + payload.len()))
1442 }
1443}
1444
1445impl BaseBox for SmhdBox {
1446 fn box_type(&self) -> BoxType {
1447 Self::TYPE
1448 }
1449
1450 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1451 Box::new(core::iter::empty())
1452 }
1453}
1454
1455impl FullBox for SmhdBox {
1456 fn full_box_version(&self) -> u8 {
1457 0
1458 }
1459
1460 fn full_box_flags(&self) -> FullBoxFlags {
1461 FullBoxFlags::new(0)
1462 }
1463}
1464
1465#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
1467#[allow(missing_docs)]
1468pub struct VmhdBox {
1469 pub graphicsmode: u16,
1470 pub opcolor: [u16; 3],
1471}
1472
1473impl VmhdBox {
1474 pub const TYPE: BoxType = BoxType::Normal(*b"vmhd");
1476
1477 pub const DEFAULT_GRAPHICSMODE: u16 = 0;
1479
1480 pub const DEFAULT_OPCOLOR: [u16; 3] = [0, 0, 0];
1482}
1483
1484impl Encode for VmhdBox {
1485 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1486 let header = BoxHeader::new_variable_size(Self::TYPE);
1487 let mut offset = header.encode(buf)?;
1488 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
1489 offset += self.graphicsmode.encode(&mut buf[offset..])?;
1490 offset += self.opcolor.encode(&mut buf[offset..])?;
1491 header.finalize_box_size(&mut buf[..offset])?;
1492 Ok(offset)
1493 }
1494}
1495
1496impl Decode for VmhdBox {
1497 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1498 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1499 header.box_type.expect(Self::TYPE)?;
1500
1501 let mut offset = 0;
1502 let full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
1503 if full_header.flags.get() != 1 {
1504 return Err(Error::invalid_data(format!(
1505 "Unexpected FullBox header flags of 'vmhd' box: {}",
1506 full_header.flags.get()
1507 )));
1508 }
1509
1510 let graphicsmode = u16::decode_at(payload, &mut offset)?;
1511 let opcolor = <[u16; 3]>::decode_at(payload, &mut offset)?;
1512
1513 Ok((
1514 Self {
1515 graphicsmode,
1516 opcolor,
1517 },
1518 header.external_size() + payload.len(),
1519 ))
1520 }
1521}
1522
1523impl BaseBox for VmhdBox {
1524 fn box_type(&self) -> BoxType {
1525 Self::TYPE
1526 }
1527
1528 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1529 Box::new(core::iter::empty())
1530 }
1531}
1532
1533impl FullBox for VmhdBox {
1534 fn full_box_version(&self) -> u8 {
1535 0
1536 }
1537
1538 fn full_box_flags(&self) -> FullBoxFlags {
1539 FullBoxFlags::new(1)
1540 }
1541}
1542
1543#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1545#[allow(missing_docs)]
1546pub struct DinfBox {
1547 pub dref_box: DrefBox,
1548 pub unknown_boxes: Vec<UnknownBox>,
1549}
1550
1551impl DinfBox {
1552 pub const TYPE: BoxType = BoxType::Normal(*b"dinf");
1554
1555 pub const LOCAL_FILE: Self = Self {
1557 dref_box: DrefBox::LOCAL_FILE,
1558 unknown_boxes: Vec::new(),
1559 };
1560}
1561
1562impl Encode for DinfBox {
1563 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1564 let header = BoxHeader::new_variable_size(Self::TYPE);
1565 let mut offset = header.encode(buf)?;
1566 offset += self.dref_box.encode(&mut buf[offset..])?;
1567 for b in &self.unknown_boxes {
1568 offset += b.encode(&mut buf[offset..])?;
1569 }
1570 header.finalize_box_size(&mut buf[..offset])?;
1571 Ok(offset)
1572 }
1573}
1574
1575impl Decode for DinfBox {
1576 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1577 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1578 header.box_type.expect(Self::TYPE)?;
1579
1580 let mut offset = 0;
1581 let mut dref_box = None;
1582 let mut unknown_boxes = Vec::new();
1583
1584 while offset < payload.len() {
1585 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
1586 match child_header.box_type {
1587 DrefBox::TYPE if dref_box.is_none() => {
1588 dref_box = Some(DrefBox::decode_at(payload, &mut offset)?);
1589 }
1590 _ => {
1591 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
1592 }
1593 }
1594 }
1595
1596 Ok((
1597 Self {
1598 dref_box: check_mandatory_box(dref_box, "dref", "dinf")?,
1599 unknown_boxes,
1600 },
1601 header.external_size() + payload.len(),
1602 ))
1603 }
1604}
1605
1606impl BaseBox for DinfBox {
1607 fn box_type(&self) -> BoxType {
1608 Self::TYPE
1609 }
1610
1611 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1612 Box::new(
1613 core::iter::empty()
1614 .chain(core::iter::once(&self.dref_box).map(as_box_object))
1615 .chain(self.unknown_boxes.iter().map(as_box_object)),
1616 )
1617 }
1618}
1619
1620#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1622#[allow(missing_docs)]
1623pub struct DrefBox {
1624 pub url_box: Option<UrlBox>,
1625 pub unknown_boxes: Vec<UnknownBox>,
1626}
1627
1628impl DrefBox {
1629 pub const TYPE: BoxType = BoxType::Normal(*b"dref");
1631
1632 pub const LOCAL_FILE: Self = Self {
1634 url_box: Some(UrlBox::LOCAL_FILE),
1635 unknown_boxes: Vec::new(),
1636 };
1637}
1638
1639impl Encode for DrefBox {
1640 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1641 let header = BoxHeader::new_variable_size(Self::TYPE);
1642 let mut offset = header.encode(buf)?;
1643 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
1644 let entry_count = (self.url_box.is_some() as usize + self.unknown_boxes.len()) as u32;
1645 offset += entry_count.encode(&mut buf[offset..])?;
1646 if let Some(b) = &self.url_box {
1647 offset += b.encode(&mut buf[offset..])?;
1648 }
1649 for b in &self.unknown_boxes {
1650 offset += b.encode(&mut buf[offset..])?;
1651 }
1652 header.finalize_box_size(&mut buf[..offset])?;
1653 Ok(offset)
1654 }
1655}
1656
1657impl Decode for DrefBox {
1658 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1659 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1660 header.box_type.expect(Self::TYPE)?;
1661
1662 let mut offset = 0;
1663 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
1664 let entry_count = u32::decode_at(payload, &mut offset)?;
1665
1666 let mut url_box = None;
1667 let mut unknown_boxes = Vec::new();
1668
1669 for _ in 0..entry_count {
1670 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
1671 match child_header.box_type {
1672 UrlBox::TYPE if url_box.is_none() => {
1673 url_box = Some(UrlBox::decode_at(payload, &mut offset)?);
1674 }
1675 _ => {
1676 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
1677 }
1678 }
1679 }
1680
1681 Ok((
1682 Self {
1683 url_box,
1684 unknown_boxes,
1685 },
1686 header.external_size() + payload.len(),
1687 ))
1688 }
1689}
1690
1691impl BaseBox for DrefBox {
1692 fn box_type(&self) -> BoxType {
1693 Self::TYPE
1694 }
1695
1696 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1697 Box::new(
1698 core::iter::empty()
1699 .chain(self.url_box.iter().map(as_box_object))
1700 .chain(self.unknown_boxes.iter().map(as_box_object)),
1701 )
1702 }
1703}
1704
1705impl FullBox for DrefBox {
1706 fn full_box_version(&self) -> u8 {
1707 0
1708 }
1709
1710 fn full_box_flags(&self) -> FullBoxFlags {
1711 FullBoxFlags::new(0)
1712 }
1713}
1714
1715#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1717#[allow(missing_docs)]
1718pub struct UrlBox {
1719 pub location: Option<Utf8String>,
1720}
1721
1722impl UrlBox {
1723 pub const TYPE: BoxType = BoxType::Normal(*b"url ");
1725
1726 pub const LOCAL_FILE: Self = Self { location: None };
1728}
1729
1730impl Encode for UrlBox {
1731 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1732 let header = BoxHeader::new_variable_size(Self::TYPE);
1733 let mut offset = header.encode(buf)?;
1734 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
1735 if let Some(l) = &self.location {
1736 offset += l.encode(&mut buf[offset..])?;
1737 }
1738 header.finalize_box_size(&mut buf[..offset])?;
1739 Ok(offset)
1740 }
1741}
1742
1743impl Decode for UrlBox {
1744 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1745 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1746 header.box_type.expect(Self::TYPE)?;
1747
1748 let mut offset = 0;
1749 let full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
1750 let location = if full_header.flags.is_set(0) {
1751 None
1752 } else {
1753 Some(Utf8String::decode_at(payload, &mut offset)?)
1754 };
1755
1756 Ok((Self { location }, header.external_size() + payload.len()))
1757 }
1758}
1759
1760impl BaseBox for UrlBox {
1761 fn box_type(&self) -> BoxType {
1762 Self::TYPE
1763 }
1764
1765 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1766 Box::new(core::iter::empty())
1767 }
1768}
1769
1770impl FullBox for UrlBox {
1771 fn full_box_version(&self) -> u8 {
1772 0
1773 }
1774
1775 fn full_box_flags(&self) -> FullBoxFlags {
1776 FullBoxFlags::new(self.location.is_none() as u32)
1777 }
1778}
1779
1780#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1782#[allow(missing_docs)]
1783pub struct StblBox {
1784 pub stsd_box: StsdBox,
1785 pub stts_box: SttsBox,
1786 pub stsc_box: StscBox,
1787 pub stsz_box: StszBox,
1788 pub stco_or_co64_box: Either<StcoBox, Co64Box>,
1789 pub stss_box: Option<StssBox>,
1790 pub unknown_boxes: Vec<UnknownBox>,
1791}
1792
1793impl StblBox {
1794 pub const TYPE: BoxType = BoxType::Normal(*b"stbl");
1796}
1797
1798impl Encode for StblBox {
1799 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1800 let header = BoxHeader::new_variable_size(Self::TYPE);
1801 let mut offset = header.encode(buf)?;
1802 offset += self.stsd_box.encode(&mut buf[offset..])?;
1803 offset += self.stts_box.encode(&mut buf[offset..])?;
1804 offset += self.stsc_box.encode(&mut buf[offset..])?;
1805 offset += self.stsz_box.encode(&mut buf[offset..])?;
1806 match &self.stco_or_co64_box {
1807 Either::A(b) => offset += b.encode(&mut buf[offset..])?,
1808 Either::B(b) => offset += b.encode(&mut buf[offset..])?,
1809 }
1810 if let Some(b) = &self.stss_box {
1811 offset += b.encode(&mut buf[offset..])?;
1812 }
1813 for b in &self.unknown_boxes {
1814 offset += b.encode(&mut buf[offset..])?;
1815 }
1816 header.finalize_box_size(&mut buf[..offset])?;
1817 Ok(offset)
1818 }
1819}
1820
1821impl Decode for StblBox {
1822 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1823 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1824 header.box_type.expect(Self::TYPE)?;
1825
1826 let mut offset = 0;
1827 let mut stsd_box = None;
1828 let mut stts_box = None;
1829 let mut stsc_box = None;
1830 let mut stsz_box = None;
1831 let mut stco_box = None;
1832 let mut co64_box = None;
1833 let mut stss_box = None;
1834 let mut unknown_boxes = Vec::new();
1835
1836 while offset < payload.len() {
1837 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
1838 match child_header.box_type {
1839 StsdBox::TYPE if stsd_box.is_none() => {
1840 stsd_box = Some(StsdBox::decode_at(payload, &mut offset)?);
1841 }
1842 SttsBox::TYPE if stts_box.is_none() => {
1843 stts_box = Some(SttsBox::decode_at(payload, &mut offset)?);
1844 }
1845 StscBox::TYPE if stsc_box.is_none() => {
1846 stsc_box = Some(StscBox::decode_at(payload, &mut offset)?);
1847 }
1848 StszBox::TYPE if stsz_box.is_none() => {
1849 stsz_box = Some(StszBox::decode_at(payload, &mut offset)?);
1850 }
1851 StcoBox::TYPE if stco_box.is_none() => {
1852 stco_box = Some(StcoBox::decode_at(payload, &mut offset)?);
1853 }
1854 Co64Box::TYPE if co64_box.is_none() => {
1855 co64_box = Some(Co64Box::decode_at(payload, &mut offset)?);
1856 }
1857 StssBox::TYPE if stss_box.is_none() => {
1858 stss_box = Some(StssBox::decode_at(payload, &mut offset)?);
1859 }
1860 _ => {
1861 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
1862 }
1863 }
1864 }
1865
1866 Ok((
1867 Self {
1868 stsd_box: check_mandatory_box(stsd_box, "stsd", "stbl")?,
1869 stts_box: check_mandatory_box(stts_box, "stts", "stbl")?,
1870 stsc_box: check_mandatory_box(stsc_box, "stsc", "stbl")?,
1871 stsz_box: check_mandatory_box(stsz_box, "stsz", "stbl")?,
1872 stco_or_co64_box: check_mandatory_box(
1873 stco_box.map(Either::A).or(co64_box.map(Either::B)),
1874 "stco' or 'co64",
1875 "stbl",
1876 )?,
1877 stss_box,
1878 unknown_boxes,
1879 },
1880 header.external_size() + payload.len(),
1881 ))
1882 }
1883}
1884
1885impl BaseBox for StblBox {
1886 fn box_type(&self) -> BoxType {
1887 Self::TYPE
1888 }
1889
1890 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1891 Box::new(
1892 core::iter::empty()
1893 .chain(core::iter::once(&self.stsd_box).map(as_box_object))
1894 .chain(core::iter::once(&self.stts_box).map(as_box_object))
1895 .chain(core::iter::once(&self.stsc_box).map(as_box_object))
1896 .chain(core::iter::once(&self.stsz_box).map(as_box_object))
1897 .chain(core::iter::once(&self.stco_or_co64_box).map(as_box_object))
1898 .chain(self.stss_box.iter().map(as_box_object))
1899 .chain(self.unknown_boxes.iter().map(as_box_object)),
1900 )
1901 }
1902}
1903
1904impl AsRef<StblBox> for StblBox {
1905 fn as_ref(&self) -> &StblBox {
1906 self
1907 }
1908}
1909
1910#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1912#[allow(missing_docs)]
1913pub struct StsdBox {
1914 pub entries: Vec<SampleEntry>,
1915}
1916
1917impl StsdBox {
1918 pub const TYPE: BoxType = BoxType::Normal(*b"stsd");
1920}
1921
1922impl Encode for StsdBox {
1923 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
1924 let header = BoxHeader::new_variable_size(Self::TYPE);
1925 let mut offset = header.encode(buf)?;
1926 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
1927 let entry_count = (self.entries.len()) as u32;
1928 offset += entry_count.encode(&mut buf[offset..])?;
1929 for b in &self.entries {
1930 offset += b.encode(&mut buf[offset..])?;
1931 }
1932 header.finalize_box_size(&mut buf[..offset])?;
1933 Ok(offset)
1934 }
1935}
1936
1937impl Decode for StsdBox {
1938 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
1939 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
1940 header.box_type.expect(Self::TYPE)?;
1941
1942 let mut offset = 0;
1943 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
1944 let entry_count = u32::decode_at(payload, &mut offset)?;
1945
1946 let mut entries = Vec::new();
1947 for _ in 0..entry_count {
1948 entries.push(SampleEntry::decode_at(payload, &mut offset)?);
1949 }
1950
1951 Ok((Self { entries }, header.external_size() + payload.len()))
1952 }
1953}
1954
1955impl BaseBox for StsdBox {
1956 fn box_type(&self) -> BoxType {
1957 Self::TYPE
1958 }
1959
1960 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
1961 Box::new(self.entries.iter().map(as_box_object))
1962 }
1963}
1964
1965impl FullBox for StsdBox {
1966 fn full_box_version(&self) -> u8 {
1967 0
1968 }
1969
1970 fn full_box_flags(&self) -> FullBoxFlags {
1971 FullBoxFlags::new(0)
1972 }
1973}
1974
1975#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1977#[allow(missing_docs)]
1978pub enum SampleEntry {
1979 Avc1(Avc1Box),
1980 Hev1(Hev1Box),
1981 Vp08(Vp08Box),
1982 Vp09(Vp09Box),
1983 Av01(Av01Box),
1984 Opus(OpusBox),
1985 Mp4a(Mp4aBox),
1986 Unknown(UnknownBox),
1987}
1988
1989impl SampleEntry {
1990 pub fn audio_channel_count(&self) -> Option<u8> {
1994 match self {
1995 Self::Opus(b) => Some(b.audio.channelcount as u8),
1996 Self::Mp4a(b) => Some(b.audio.channelcount as u8),
1997 _ => None,
1998 }
1999 }
2000
2001 pub fn audio_sample_rate(&self) -> Option<u16> {
2011 match self {
2012 Self::Opus(b) => Some(b.audio.samplerate.integer),
2013 Self::Mp4a(b) => Some(b.audio.samplerate.integer),
2014 _ => None,
2015 }
2016 }
2017
2018 pub fn audio_sample_size(&self) -> Option<u16> {
2022 match self {
2023 Self::Opus(b) => Some(b.audio.samplesize),
2024 Self::Mp4a(b) => Some(b.audio.samplesize),
2025 _ => None,
2026 }
2027 }
2028
2029 pub fn video_resolution(&self) -> Option<(u16, u16)> {
2033 match self {
2034 Self::Avc1(b) => Some((b.visual.width, b.visual.height)),
2035 Self::Hev1(b) => Some((b.visual.width, b.visual.height)),
2036 Self::Vp08(b) => Some((b.visual.width, b.visual.height)),
2037 Self::Vp09(b) => Some((b.visual.width, b.visual.height)),
2038 Self::Av01(b) => Some((b.visual.width, b.visual.height)),
2039 _ => None,
2040 }
2041 }
2042
2043 fn inner_box(&self) -> &dyn BaseBox {
2044 match self {
2045 Self::Avc1(b) => b,
2046 Self::Hev1(b) => b,
2047 Self::Vp08(b) => b,
2048 Self::Vp09(b) => b,
2049 Self::Av01(b) => b,
2050 Self::Opus(b) => b,
2051 Self::Mp4a(b) => b,
2052 Self::Unknown(b) => b,
2053 }
2054 }
2055}
2056
2057impl Encode for SampleEntry {
2058 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
2059 match self {
2060 Self::Avc1(b) => b.encode(buf),
2061 Self::Hev1(b) => b.encode(buf),
2062 Self::Vp08(b) => b.encode(buf),
2063 Self::Vp09(b) => b.encode(buf),
2064 Self::Av01(b) => b.encode(buf),
2065 Self::Opus(b) => b.encode(buf),
2066 Self::Mp4a(b) => b.encode(buf),
2067 Self::Unknown(b) => b.encode(buf),
2068 }
2069 }
2070}
2071
2072impl Decode for SampleEntry {
2073 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
2074 let (header, _) = BoxHeader::decode(buf)?;
2075 match header.box_type {
2076 Avc1Box::TYPE => Avc1Box::decode(buf).map(|(b, n)| (Self::Avc1(b), n)),
2077 Hev1Box::TYPE => Hev1Box::decode(buf).map(|(b, n)| (Self::Hev1(b), n)),
2078 Vp08Box::TYPE => Vp08Box::decode(buf).map(|(b, n)| (Self::Vp08(b), n)),
2079 Vp09Box::TYPE => Vp09Box::decode(buf).map(|(b, n)| (Self::Vp09(b), n)),
2080 Av01Box::TYPE => Av01Box::decode(buf).map(|(b, n)| (Self::Av01(b), n)),
2081 OpusBox::TYPE => OpusBox::decode(buf).map(|(b, n)| (Self::Opus(b), n)),
2082 Mp4aBox::TYPE => Mp4aBox::decode(buf).map(|(b, n)| (Self::Mp4a(b), n)),
2083 _ => UnknownBox::decode(buf).map(|(b, n)| (Self::Unknown(b), n)),
2084 }
2085 }
2086}
2087
2088impl BaseBox for SampleEntry {
2089 fn box_type(&self) -> BoxType {
2090 self.inner_box().box_type()
2091 }
2092
2093 fn is_unknown_box(&self) -> bool {
2094 self.inner_box().is_unknown_box()
2095 }
2096
2097 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
2098 self.inner_box().children()
2099 }
2100}
2101
2102#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2104#[allow(missing_docs)]
2105pub struct VisualSampleEntryFields {
2106 pub data_reference_index: NonZeroU16,
2107 pub width: u16,
2108 pub height: u16,
2109 pub horizresolution: FixedPointNumber<u16, u16>,
2110 pub vertresolution: FixedPointNumber<u16, u16>,
2111 pub frame_count: u16,
2112 pub compressorname: [u8; 32],
2113 pub depth: u16,
2114}
2115
2116impl VisualSampleEntryFields {
2117 pub const DEFAULT_DATA_REFERENCE_INDEX: NonZeroU16 = NonZeroU16::MIN;
2119
2120 pub const DEFAULT_HORIZRESOLUTION: FixedPointNumber<u16, u16> = FixedPointNumber::new(0x48, 0);
2122
2123 pub const DEFAULT_VERTRESOLUTION: FixedPointNumber<u16, u16> = FixedPointNumber::new(0x48, 0);
2125
2126 pub const DEFAULT_FRAME_COUNT: u16 = 1;
2128
2129 pub const DEFAULT_DEPTH: u16 = 0x0018;
2131
2132 pub const NULL_COMPRESSORNAME: [u8; 32] = [0; 32];
2134}
2135
2136impl Encode for VisualSampleEntryFields {
2137 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
2138 let mut offset = 0;
2139 offset += [0u8; 6].encode(&mut buf[offset..])?;
2140 offset += self.data_reference_index.encode(&mut buf[offset..])?;
2141 offset += [0u8; 2 + 2 + 4 * 3].encode(&mut buf[offset..])?;
2142 offset += self.width.encode(&mut buf[offset..])?;
2143 offset += self.height.encode(&mut buf[offset..])?;
2144 offset += self.horizresolution.encode(&mut buf[offset..])?;
2145 offset += self.vertresolution.encode(&mut buf[offset..])?;
2146 offset += [0u8; 4].encode(&mut buf[offset..])?;
2147 offset += self.frame_count.encode(&mut buf[offset..])?;
2148 offset += self.compressorname.encode(&mut buf[offset..])?;
2149 offset += self.depth.encode(&mut buf[offset..])?;
2150 offset += (-1i16).encode(&mut buf[offset..])?;
2151 Ok(offset)
2152 }
2153}
2154
2155impl Decode for VisualSampleEntryFields {
2156 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
2157 let mut offset = 0;
2158 let _ = <[u8; 6]>::decode_at(buf, &mut offset)?;
2159 let data_reference_index = NonZeroU16::decode_at(buf, &mut offset)?;
2160 let _ = <[u8; 2 + 2 + 4 * 3]>::decode_at(buf, &mut offset)?;
2161 let width = u16::decode_at(buf, &mut offset)?;
2162 let height = u16::decode_at(buf, &mut offset)?;
2163 let horizresolution = FixedPointNumber::decode_at(buf, &mut offset)?;
2164 let vertresolution = FixedPointNumber::decode_at(buf, &mut offset)?;
2165 let _ = <[u8; 4]>::decode_at(buf, &mut offset)?;
2166 let frame_count = u16::decode_at(buf, &mut offset)?;
2167 let compressorname = <[u8; 32]>::decode_at(buf, &mut offset)?;
2168 let depth = u16::decode_at(buf, &mut offset)?;
2169 let _ = <[u8; 2]>::decode_at(buf, &mut offset)?;
2170 Ok((
2171 Self {
2172 data_reference_index,
2173 width,
2174 height,
2175 horizresolution,
2176 vertresolution,
2177 frame_count,
2178 compressorname,
2179 depth,
2180 },
2181 offset,
2182 ))
2183 }
2184}
2185
2186#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2188#[allow(missing_docs)]
2189pub struct Avc1Box {
2190 pub visual: VisualSampleEntryFields,
2191 pub avcc_box: AvccBox,
2192 pub unknown_boxes: Vec<UnknownBox>,
2193}
2194
2195impl Avc1Box {
2196 pub const TYPE: BoxType = BoxType::Normal(*b"avc1");
2198}
2199
2200impl Encode for Avc1Box {
2201 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
2202 let header = BoxHeader::new_variable_size(Self::TYPE);
2203 let mut offset = header.encode(buf)?;
2204 offset += self.visual.encode(&mut buf[offset..])?;
2205 offset += self.avcc_box.encode(&mut buf[offset..])?;
2206 for b in &self.unknown_boxes {
2207 offset += b.encode(&mut buf[offset..])?;
2208 }
2209 header.finalize_box_size(&mut buf[..offset])?;
2210 Ok(offset)
2211 }
2212}
2213
2214impl Decode for Avc1Box {
2215 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
2216 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
2217 header.box_type.expect(Self::TYPE)?;
2218
2219 let mut offset = 0;
2220 let visual = VisualSampleEntryFields::decode_at(payload, &mut offset)?;
2221
2222 let mut avcc_box = None;
2223 let mut unknown_boxes = Vec::new();
2224
2225 while offset < payload.len() {
2226 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
2227 match child_header.box_type {
2228 AvccBox::TYPE if avcc_box.is_none() => {
2229 avcc_box = Some(AvccBox::decode_at(payload, &mut offset)?);
2230 }
2231 _ => {
2232 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
2233 }
2234 }
2235 }
2236
2237 Ok((
2238 Self {
2239 visual,
2240 avcc_box: check_mandatory_box(avcc_box, "avcc", "avc1")?,
2241 unknown_boxes,
2242 },
2243 header.external_size() + payload.len(),
2244 ))
2245 }
2246}
2247
2248impl BaseBox for Avc1Box {
2249 fn box_type(&self) -> BoxType {
2250 Self::TYPE
2251 }
2252
2253 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
2254 Box::new(
2255 core::iter::empty()
2256 .chain(core::iter::once(&self.avcc_box).map(as_box_object))
2257 .chain(self.unknown_boxes.iter().map(as_box_object)),
2258 )
2259 }
2260}
2261
2262#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2264#[allow(missing_docs)]
2265pub struct AvccBox {
2266 pub avc_profile_indication: u8,
2267 pub profile_compatibility: u8,
2268 pub avc_level_indication: u8,
2269 pub length_size_minus_one: Uint<u8, 2>,
2270 pub sps_list: Vec<Vec<u8>>,
2271 pub pps_list: Vec<Vec<u8>>,
2272 pub chroma_format: Option<Uint<u8, 2>>,
2273 pub bit_depth_luma_minus8: Option<Uint<u8, 3>>,
2274 pub bit_depth_chroma_minus8: Option<Uint<u8, 3>>,
2275 pub sps_ext_list: Vec<Vec<u8>>,
2276}
2277
2278impl AvccBox {
2279 pub const TYPE: BoxType = BoxType::Normal(*b"avcC");
2281
2282 const CONFIGURATION_VERSION: u8 = 1;
2283}
2284
2285impl Encode for AvccBox {
2286 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
2287 let header = BoxHeader::new_variable_size(Self::TYPE);
2288 let mut offset = header.encode(buf)?;
2289
2290 offset += Self::CONFIGURATION_VERSION.encode(&mut buf[offset..])?;
2291 offset += self.avc_profile_indication.encode(&mut buf[offset..])?;
2292 offset += self.profile_compatibility.encode(&mut buf[offset..])?;
2293 offset += self.avc_level_indication.encode(&mut buf[offset..])?;
2294 offset += (0b1111_1100 | self.length_size_minus_one.get()).encode(&mut buf[offset..])?;
2295
2296 let sps_count =
2297 u8::try_from(self.sps_list.len()).map_err(|_| Error::invalid_input("Too many SPSs"))?;
2298 offset += (0b1110_0000 | sps_count).encode(&mut buf[offset..])?;
2299 for sps in &self.sps_list {
2300 let size =
2301 u16::try_from(sps.len()).map_err(|_| Error::invalid_input("Too long SPS"))?;
2302 offset += size.encode(&mut buf[offset..])?;
2303 offset += sps.encode(&mut buf[offset..])?;
2304 }
2305
2306 let pps_count =
2307 u8::try_from(self.pps_list.len()).map_err(|_| Error::invalid_input("Too many PPSs"))?;
2308 offset += pps_count.encode(&mut buf[offset..])?;
2309 for pps in &self.pps_list {
2310 let size =
2311 u16::try_from(pps.len()).map_err(|_| Error::invalid_input("Too long PPS"))?;
2312 offset += size.encode(&mut buf[offset..])?;
2313 offset += pps.encode(&mut buf[offset..])?;
2314 }
2315
2316 if !matches!(self.avc_profile_indication, 66 | 77 | 88) {
2317 let chroma_format = self.chroma_format.ok_or_else(|| {
2318 Error::invalid_input("Missing 'chroma_format' field in 'avcC' box")
2319 })?;
2320 let bit_depth_luma_minus8 = self.bit_depth_luma_minus8.ok_or_else(|| {
2321 Error::invalid_input("Missing 'bit_depth_luma_minus8' field in 'avcC' box")
2322 })?;
2323 let bit_depth_chroma_minus8 = self.bit_depth_chroma_minus8.ok_or_else(|| {
2324 Error::invalid_input("Missing 'bit_depth_chroma_minus8' field in 'avcC' box")
2325 })?;
2326 offset += (0b1111_1100 | chroma_format.get()).encode(&mut buf[offset..])?;
2327 offset += (0b1111_1000 | bit_depth_luma_minus8.get()).encode(&mut buf[offset..])?;
2328 offset += (0b1111_1000 | bit_depth_chroma_minus8.get()).encode(&mut buf[offset..])?;
2329
2330 let sps_ext_count = u8::try_from(self.sps_ext_list.len())
2331 .map_err(|_| Error::invalid_input("Too many SPS EXTs"))?;
2332 offset += sps_ext_count.encode(&mut buf[offset..])?;
2333 for sps_ext in &self.sps_ext_list {
2334 let size = u16::try_from(sps_ext.len())
2335 .map_err(|_| Error::invalid_input("Too long SPS EXT"))?;
2336 offset += size.encode(&mut buf[offset..])?;
2337 offset += sps_ext.encode(&mut buf[offset..])?;
2338 }
2339 }
2340
2341 header.finalize_box_size(&mut buf[..offset])?;
2342 Ok(offset)
2343 }
2344}
2345
2346impl Decode for AvccBox {
2347 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
2348 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
2349 header.box_type.expect(Self::TYPE)?;
2350
2351 let mut offset = 0;
2352 let configuration_version = u8::decode_at(payload, &mut offset)?;
2353 if configuration_version != Self::CONFIGURATION_VERSION {
2354 return Err(Error::invalid_data(format!(
2355 "Unsupported avcC configuration version: {configuration_version}"
2356 )));
2357 }
2358
2359 let avc_profile_indication = u8::decode_at(payload, &mut offset)?;
2360 let profile_compatibility = u8::decode_at(payload, &mut offset)?;
2361 let avc_level_indication = u8::decode_at(payload, &mut offset)?;
2362 let length_size_minus_one = Uint::from_bits(u8::decode_at(payload, &mut offset)?);
2363
2364 let sps_count =
2365 Uint::<u8, 5>::from_bits(u8::decode_at(payload, &mut offset)?).get() as usize;
2366 let mut sps_list = Vec::with_capacity(sps_count);
2367 for _ in 0..sps_count {
2368 let size = u16::decode_at(payload, &mut offset)? as usize;
2369 let sps = payload[offset..offset + size].to_vec();
2370 offset += size;
2371 sps_list.push(sps);
2372 }
2373
2374 let pps_count = u8::decode_at(payload, &mut offset)? as usize;
2375 let mut pps_list = Vec::with_capacity(pps_count);
2376 for _ in 0..pps_count {
2377 let size = u16::decode_at(payload, &mut offset)? as usize;
2378 let pps = payload[offset..offset + size].to_vec();
2379 offset += size;
2380 pps_list.push(pps);
2381 }
2382
2383 let mut chroma_format = None;
2384 let mut bit_depth_luma_minus8 = None;
2385 let mut bit_depth_chroma_minus8 = None;
2386 let mut sps_ext_list = Vec::new();
2387 if !matches!(avc_profile_indication, 66 | 77 | 88) {
2388 chroma_format = Some(Uint::from_bits(u8::decode_at(payload, &mut offset)?));
2389 bit_depth_luma_minus8 = Some(Uint::from_bits(u8::decode_at(payload, &mut offset)?));
2390 bit_depth_chroma_minus8 = Some(Uint::from_bits(u8::decode_at(payload, &mut offset)?));
2391
2392 let sps_ext_count = u8::decode_at(payload, &mut offset)? as usize;
2393 for _ in 0..sps_ext_count {
2394 let size = u16::decode_at(payload, &mut offset)? as usize;
2395 let sps_ext = payload[offset..offset + size].to_vec();
2396 offset += size;
2397 sps_ext_list.push(sps_ext);
2398 }
2399 }
2400
2401 Ok((
2402 Self {
2403 avc_profile_indication,
2404 profile_compatibility,
2405 avc_level_indication,
2406 length_size_minus_one,
2407 sps_list,
2408 pps_list,
2409 chroma_format,
2410 bit_depth_luma_minus8,
2411 bit_depth_chroma_minus8,
2412 sps_ext_list,
2413 },
2414 header.external_size() + payload.len(),
2415 ))
2416 }
2417}
2418
2419impl BaseBox for AvccBox {
2420 fn box_type(&self) -> BoxType {
2421 Self::TYPE
2422 }
2423
2424 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
2425 Box::new(core::iter::empty())
2426 }
2427}
2428
2429#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2431#[allow(missing_docs)]
2432pub struct Hev1Box {
2433 pub visual: VisualSampleEntryFields,
2434 pub hvcc_box: HvccBox,
2435 pub unknown_boxes: Vec<UnknownBox>,
2436}
2437
2438impl Hev1Box {
2439 pub const TYPE: BoxType = BoxType::Normal(*b"hev1");
2441}
2442
2443impl Encode for Hev1Box {
2444 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
2445 let header = BoxHeader::new_variable_size(Self::TYPE);
2446 let mut offset = header.encode(buf)?;
2447 offset += self.visual.encode(&mut buf[offset..])?;
2448 offset += self.hvcc_box.encode(&mut buf[offset..])?;
2449 for b in &self.unknown_boxes {
2450 offset += b.encode(&mut buf[offset..])?;
2451 }
2452 header.finalize_box_size(&mut buf[..offset])?;
2453 Ok(offset)
2454 }
2455}
2456
2457impl Decode for Hev1Box {
2458 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
2459 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
2460 header.box_type.expect(Self::TYPE)?;
2461
2462 let mut offset = 0;
2463 let visual = VisualSampleEntryFields::decode_at(payload, &mut offset)?;
2464
2465 let mut hvcc_box = None;
2466 let mut unknown_boxes = Vec::new();
2467
2468 while offset < payload.len() {
2469 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
2470 match child_header.box_type {
2471 HvccBox::TYPE if hvcc_box.is_none() => {
2472 hvcc_box = Some(HvccBox::decode_at(payload, &mut offset)?);
2473 }
2474 _ => {
2475 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
2476 }
2477 }
2478 }
2479
2480 Ok((
2481 Self {
2482 visual,
2483 hvcc_box: check_mandatory_box(hvcc_box, "hvcc", "hev1")?,
2484 unknown_boxes,
2485 },
2486 header.external_size() + payload.len(),
2487 ))
2488 }
2489}
2490
2491impl BaseBox for Hev1Box {
2492 fn box_type(&self) -> BoxType {
2493 Self::TYPE
2494 }
2495
2496 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
2497 Box::new(
2498 core::iter::empty()
2499 .chain(core::iter::once(&self.hvcc_box).map(as_box_object))
2500 .chain(self.unknown_boxes.iter().map(as_box_object)),
2501 )
2502 }
2503}
2504
2505#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2507#[allow(missing_docs)]
2508pub struct HvccNalUintArray {
2509 pub array_completeness: Uint<u8, 1, 7>,
2510 pub nal_unit_type: Uint<u8, 6, 0>,
2511 pub nalus: Vec<Vec<u8>>,
2512}
2513
2514#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2516#[allow(missing_docs)]
2517pub struct HvccBox {
2518 pub general_profile_space: Uint<u8, 2, 6>,
2519 pub general_tier_flag: Uint<u8, 1, 5>,
2520 pub general_profile_idc: Uint<u8, 5, 0>,
2521 pub general_profile_compatibility_flags: u32,
2522 pub general_constraint_indicator_flags: Uint<u64, 48>,
2523 pub general_level_idc: u8,
2524 pub min_spatial_segmentation_idc: Uint<u16, 12>,
2525 pub parallelism_type: Uint<u8, 2>,
2526 pub chroma_format_idc: Uint<u8, 2>,
2527 pub bit_depth_luma_minus8: Uint<u8, 3>,
2528 pub bit_depth_chroma_minus8: Uint<u8, 3>,
2529 pub avg_frame_rate: u16,
2530 pub constant_frame_rate: Uint<u8, 2, 6>,
2531 pub num_temporal_layers: Uint<u8, 3, 3>,
2532 pub temporal_id_nested: Uint<u8, 1, 2>,
2533 pub length_size_minus_one: Uint<u8, 2, 0>,
2534 pub nalu_arrays: Vec<HvccNalUintArray>,
2535}
2536
2537impl HvccBox {
2538 pub const TYPE: BoxType = BoxType::Normal(*b"hvcC");
2540
2541 const CONFIGURATION_VERSION: u8 = 1;
2542}
2543
2544impl Encode for HvccBox {
2545 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
2546 let header = BoxHeader::new_variable_size(Self::TYPE);
2547 let mut offset = header.encode(buf)?;
2548 offset += Self::CONFIGURATION_VERSION.encode(&mut buf[offset..])?;
2549 offset += (self.general_profile_space.to_bits()
2550 | self.general_tier_flag.to_bits()
2551 | self.general_profile_idc.to_bits())
2552 .encode(&mut buf[offset..])?;
2553 offset += self
2554 .general_profile_compatibility_flags
2555 .encode(&mut buf[offset..])?;
2556 offset += self.general_constraint_indicator_flags.get().to_be_bytes()[2..]
2557 .encode(&mut buf[offset..])?;
2558 offset += self.general_level_idc.encode(&mut buf[offset..])?;
2559 offset += (0b1111_0000_0000_0000 | self.min_spatial_segmentation_idc.to_bits())
2560 .encode(&mut buf[offset..])?;
2561 offset += (0b1111_1100 | self.parallelism_type.to_bits()).encode(&mut buf[offset..])?;
2562 offset += (0b1111_1100 | self.chroma_format_idc.to_bits()).encode(&mut buf[offset..])?;
2563 offset +=
2564 (0b1111_1000 | self.bit_depth_luma_minus8.to_bits()).encode(&mut buf[offset..])?;
2565 offset +=
2566 (0b1111_1000 | self.bit_depth_chroma_minus8.to_bits()).encode(&mut buf[offset..])?;
2567 offset += self.avg_frame_rate.encode(&mut buf[offset..])?;
2568 offset += (self.constant_frame_rate.to_bits()
2569 | self.num_temporal_layers.to_bits()
2570 | self.temporal_id_nested.to_bits()
2571 | self.length_size_minus_one.to_bits())
2572 .encode(&mut buf[offset..])?;
2573 offset += u8::try_from(self.nalu_arrays.len())
2574 .map_err(|_| {
2575 Error::invalid_input(format!("Too many NALU arrays: {}", self.nalu_arrays.len()))
2576 })?
2577 .encode(&mut buf[offset..])?;
2578 for nalu_array in &self.nalu_arrays {
2579 offset += (nalu_array.array_completeness.to_bits()
2580 | nalu_array.nal_unit_type.to_bits())
2581 .encode(&mut buf[offset..])?;
2582 offset += u16::try_from(nalu_array.nalus.len())
2583 .map_err(|_| {
2584 Error::invalid_input(format!("Too many NALUs: {}", nalu_array.nalus.len()))
2585 })?
2586 .encode(&mut buf[offset..])?;
2587 for nalu in &nalu_array.nalus {
2588 offset += u16::try_from(nalu.len())
2589 .map_err(|_| Error::invalid_input(format!("Too large NALU: {}", nalu.len())))?
2590 .encode(&mut buf[offset..])?;
2591 offset += nalu.encode(&mut buf[offset..])?;
2592 }
2593 }
2594 header.finalize_box_size(&mut buf[..offset])?;
2595 Ok(offset)
2596 }
2597}
2598
2599impl Decode for HvccBox {
2600 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
2601 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
2602 header.box_type.expect(Self::TYPE)?;
2603
2604 let mut offset = 0;
2605 let configuration_version = u8::decode_at(payload, &mut offset)?;
2606 if configuration_version != Self::CONFIGURATION_VERSION {
2607 return Err(Error::invalid_data(format!(
2608 "Unsupported hvcC version: {configuration_version}"
2609 )));
2610 }
2611
2612 let b = u8::decode_at(payload, &mut offset)?;
2613 let general_profile_space = Uint::from_bits(b);
2614 let general_tier_flag = Uint::from_bits(b);
2615 let general_profile_idc = Uint::from_bits(b);
2616
2617 let general_profile_compatibility_flags = u32::decode_at(payload, &mut offset)?;
2618
2619 let mut buf_constraint = [0; 8];
2620 buf_constraint[2..].copy_from_slice(&payload[offset..offset + 6]);
2621 offset += 6;
2622 let general_constraint_indicator_flags =
2623 Uint::from_bits(u64::from_be_bytes(buf_constraint));
2624
2625 let general_level_idc = u8::decode_at(payload, &mut offset)?;
2626 let min_spatial_segmentation_idc = Uint::from_bits(u16::decode_at(payload, &mut offset)?);
2627 let parallelism_type = Uint::from_bits(u8::decode_at(payload, &mut offset)?);
2628 let chroma_format_idc = Uint::from_bits(u8::decode_at(payload, &mut offset)?);
2629 let bit_depth_luma_minus8 = Uint::from_bits(u8::decode_at(payload, &mut offset)?);
2630 let bit_depth_chroma_minus8 = Uint::from_bits(u8::decode_at(payload, &mut offset)?);
2631 let avg_frame_rate = u16::decode_at(payload, &mut offset)?;
2632
2633 let b = u8::decode_at(payload, &mut offset)?;
2634 let constant_frame_rate = Uint::from_bits(b);
2635 let num_temporal_layers = Uint::from_bits(b);
2636 let temporal_id_nested = Uint::from_bits(b);
2637 let length_size_minus_one = Uint::from_bits(b);
2638
2639 let num_of_arrays = u8::decode_at(payload, &mut offset)?;
2640 let mut nalu_arrays = Vec::new();
2641 for _ in 0..num_of_arrays {
2642 let b = u8::decode_at(payload, &mut offset)?;
2643 let array_completeness = Uint::from_bits(b);
2644 let nal_unit_type = Uint::from_bits(b);
2645
2646 let num_nalus = u16::decode_at(payload, &mut offset)?;
2647 let mut nalus = Vec::new();
2648 for _ in 0..num_nalus {
2649 let nal_unit_length = u16::decode_at(payload, &mut offset)? as usize;
2650 let nal_unit = payload[offset..offset + nal_unit_length].to_vec();
2651 offset += nal_unit_length;
2652 nalus.push(nal_unit);
2653 }
2654 nalu_arrays.push(HvccNalUintArray {
2655 array_completeness,
2656 nal_unit_type,
2657 nalus,
2658 });
2659 }
2660
2661 Ok((
2662 Self {
2663 general_profile_space,
2664 general_tier_flag,
2665 general_profile_idc,
2666 general_profile_compatibility_flags,
2667 general_constraint_indicator_flags,
2668 general_level_idc,
2669 min_spatial_segmentation_idc,
2670 parallelism_type,
2671 chroma_format_idc,
2672 bit_depth_luma_minus8,
2673 bit_depth_chroma_minus8,
2674 avg_frame_rate,
2675 constant_frame_rate,
2676 num_temporal_layers,
2677 temporal_id_nested,
2678 length_size_minus_one,
2679 nalu_arrays,
2680 },
2681 header.external_size() + payload.len(),
2682 ))
2683 }
2684}
2685
2686impl BaseBox for HvccBox {
2687 fn box_type(&self) -> BoxType {
2688 Self::TYPE
2689 }
2690
2691 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
2692 Box::new(core::iter::empty())
2693 }
2694}
2695
2696#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2698#[allow(missing_docs)]
2699pub struct Vp08Box {
2700 pub visual: VisualSampleEntryFields,
2701 pub vpcc_box: VpccBox,
2702 pub unknown_boxes: Vec<UnknownBox>,
2703}
2704
2705impl Vp08Box {
2706 pub const TYPE: BoxType = BoxType::Normal(*b"vp08");
2708}
2709
2710impl Encode for Vp08Box {
2711 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
2712 let header = BoxHeader::new_variable_size(Self::TYPE);
2713 let mut offset = header.encode(buf)?;
2714 offset += self.visual.encode(&mut buf[offset..])?;
2715 offset += self.vpcc_box.encode(&mut buf[offset..])?;
2716 for b in &self.unknown_boxes {
2717 offset += b.encode(&mut buf[offset..])?;
2718 }
2719 header.finalize_box_size(&mut buf[..offset])?;
2720 Ok(offset)
2721 }
2722}
2723
2724impl Decode for Vp08Box {
2725 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
2726 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
2727 header.box_type.expect(Self::TYPE)?;
2728
2729 let mut offset = 0;
2730 let visual = VisualSampleEntryFields::decode_at(payload, &mut offset)?;
2731
2732 let mut vpcc_box = None;
2733 let mut unknown_boxes = Vec::new();
2734
2735 while offset < payload.len() {
2736 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
2737 match child_header.box_type {
2738 VpccBox::TYPE if vpcc_box.is_none() => {
2739 vpcc_box = Some(VpccBox::decode_at(payload, &mut offset)?);
2740 }
2741 _ => {
2742 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
2743 }
2744 }
2745 }
2746
2747 Ok((
2748 Self {
2749 visual,
2750 vpcc_box: check_mandatory_box(vpcc_box, "vpcC", "vp08")?,
2751 unknown_boxes,
2752 },
2753 header.external_size() + payload.len(),
2754 ))
2755 }
2756}
2757
2758impl BaseBox for Vp08Box {
2759 fn box_type(&self) -> BoxType {
2760 Self::TYPE
2761 }
2762
2763 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
2764 Box::new(
2765 core::iter::empty()
2766 .chain(core::iter::once(&self.vpcc_box).map(as_box_object))
2767 .chain(self.unknown_boxes.iter().map(as_box_object)),
2768 )
2769 }
2770}
2771
2772#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2774#[allow(missing_docs)]
2775pub struct Vp09Box {
2776 pub visual: VisualSampleEntryFields,
2777 pub vpcc_box: VpccBox,
2778 pub unknown_boxes: Vec<UnknownBox>,
2779}
2780
2781impl Vp09Box {
2782 pub const TYPE: BoxType = BoxType::Normal(*b"vp09");
2784}
2785
2786impl Encode for Vp09Box {
2787 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
2788 let header = BoxHeader::new_variable_size(Self::TYPE);
2789 let mut offset = header.encode(buf)?;
2790 offset += self.visual.encode(&mut buf[offset..])?;
2791 offset += self.vpcc_box.encode(&mut buf[offset..])?;
2792 for b in &self.unknown_boxes {
2793 offset += b.encode(&mut buf[offset..])?;
2794 }
2795 header.finalize_box_size(&mut buf[..offset])?;
2796 Ok(offset)
2797 }
2798}
2799
2800impl Decode for Vp09Box {
2801 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
2802 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
2803 header.box_type.expect(Self::TYPE)?;
2804
2805 let mut offset = 0;
2806 let visual = VisualSampleEntryFields::decode_at(payload, &mut offset)?;
2807
2808 let mut vpcc_box = None;
2809 let mut unknown_boxes = Vec::new();
2810
2811 while offset < payload.len() {
2812 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
2813 match child_header.box_type {
2814 VpccBox::TYPE if vpcc_box.is_none() => {
2815 vpcc_box = Some(VpccBox::decode_at(payload, &mut offset)?);
2816 }
2817 _ => {
2818 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
2819 }
2820 }
2821 }
2822
2823 Ok((
2824 Self {
2825 visual,
2826 vpcc_box: check_mandatory_box(vpcc_box, "vpcC", "vp09")?,
2827 unknown_boxes,
2828 },
2829 header.external_size() + payload.len(),
2830 ))
2831 }
2832}
2833
2834impl BaseBox for Vp09Box {
2835 fn box_type(&self) -> BoxType {
2836 Self::TYPE
2837 }
2838
2839 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
2840 Box::new(
2841 core::iter::empty()
2842 .chain(core::iter::once(&self.vpcc_box).map(as_box_object))
2843 .chain(self.unknown_boxes.iter().map(as_box_object)),
2844 )
2845 }
2846}
2847
2848#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2850#[allow(missing_docs)]
2851pub struct VpccBox {
2852 pub profile: u8,
2853 pub level: u8,
2854 pub bit_depth: Uint<u8, 4, 4>,
2855 pub chroma_subsampling: Uint<u8, 3, 1>,
2856 pub video_full_range_flag: Uint<u8, 1>,
2857 pub colour_primaries: u8,
2858 pub transfer_characteristics: u8,
2859 pub matrix_coefficients: u8,
2860 pub codec_initialization_data: Vec<u8>,
2861}
2862
2863impl VpccBox {
2864 pub const TYPE: BoxType = BoxType::Normal(*b"vpcC");
2866}
2867
2868impl Encode for VpccBox {
2869 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
2870 let header = BoxHeader::new_variable_size(Self::TYPE);
2871 let mut offset = header.encode(buf)?;
2872 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
2873 offset += self.profile.encode(&mut buf[offset..])?;
2874 offset += self.level.encode(&mut buf[offset..])?;
2875 offset += (self.bit_depth.to_bits()
2876 | self.chroma_subsampling.to_bits()
2877 | self.video_full_range_flag.to_bits())
2878 .encode(&mut buf[offset..])?;
2879 offset += self.colour_primaries.encode(&mut buf[offset..])?;
2880 offset += self.transfer_characteristics.encode(&mut buf[offset..])?;
2881 offset += self.matrix_coefficients.encode(&mut buf[offset..])?;
2882 offset += (self.codec_initialization_data.len() as u16).encode(&mut buf[offset..])?;
2883 offset += self.codec_initialization_data.encode(&mut buf[offset..])?;
2884 header.finalize_box_size(&mut buf[..offset])?;
2885 Ok(offset)
2886 }
2887}
2888
2889impl Decode for VpccBox {
2890 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
2891 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
2892 header.box_type.expect(Self::TYPE)?;
2893
2894 let mut offset = 0;
2895 let header_obj = FullBoxHeader::decode_at(payload, &mut offset)?;
2896 if header_obj.version != 1 {
2897 return Err(Error::invalid_data(format!(
2898 "Unexpected full box header version: box=vpcC, version={}",
2899 header_obj.version
2900 )));
2901 }
2902
2903 let profile = u8::decode_at(payload, &mut offset)?;
2904 let level = u8::decode_at(payload, &mut offset)?;
2905
2906 let b = u8::decode_at(payload, &mut offset)?;
2907 let bit_depth = Uint::from_bits(b);
2908 let chroma_subsampling = Uint::from_bits(b);
2909 let video_full_range_flag = Uint::from_bits(b);
2910 let colour_primaries = u8::decode_at(payload, &mut offset)?;
2911 let transfer_characteristics = u8::decode_at(payload, &mut offset)?;
2912 let matrix_coefficients = u8::decode_at(payload, &mut offset)?;
2913 let codec_init_size = u16::decode_at(payload, &mut offset)? as usize;
2914 let codec_initialization_data = payload[offset..offset + codec_init_size].to_vec();
2915
2916 Ok((
2917 Self {
2918 profile,
2919 level,
2920 bit_depth,
2921 chroma_subsampling,
2922 video_full_range_flag,
2923 colour_primaries,
2924 transfer_characteristics,
2925 matrix_coefficients,
2926 codec_initialization_data,
2927 },
2928 header.external_size() + payload.len(),
2929 ))
2930 }
2931}
2932
2933impl BaseBox for VpccBox {
2934 fn box_type(&self) -> BoxType {
2935 Self::TYPE
2936 }
2937
2938 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
2939 Box::new(core::iter::empty())
2940 }
2941}
2942
2943impl FullBox for VpccBox {
2944 fn full_box_version(&self) -> u8 {
2945 1
2946 }
2947
2948 fn full_box_flags(&self) -> FullBoxFlags {
2949 FullBoxFlags::new(0)
2950 }
2951}
2952
2953#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2955#[allow(missing_docs)]
2956pub struct Av01Box {
2957 pub visual: VisualSampleEntryFields,
2958 pub av1c_box: Av1cBox,
2959 pub unknown_boxes: Vec<UnknownBox>,
2960}
2961
2962impl Av01Box {
2963 pub const TYPE: BoxType = BoxType::Normal(*b"av01");
2965}
2966
2967impl Encode for Av01Box {
2968 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
2969 let header = BoxHeader::new_variable_size(Self::TYPE);
2970 let mut offset = header.encode(buf)?;
2971 offset += self.visual.encode(&mut buf[offset..])?;
2972 offset += self.av1c_box.encode(&mut buf[offset..])?;
2973 for b in &self.unknown_boxes {
2974 offset += b.encode(&mut buf[offset..])?;
2975 }
2976 header.finalize_box_size(&mut buf[..offset])?;
2977 Ok(offset)
2978 }
2979}
2980
2981impl Decode for Av01Box {
2982 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
2983 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
2984 header.box_type.expect(Self::TYPE)?;
2985
2986 let mut offset = 0;
2987 let visual = VisualSampleEntryFields::decode_at(payload, &mut offset)?;
2988
2989 let mut av1c_box = None;
2990 let mut unknown_boxes = Vec::new();
2991
2992 while offset < payload.len() {
2993 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
2994 match child_header.box_type {
2995 Av1cBox::TYPE if av1c_box.is_none() => {
2996 av1c_box = Some(Av1cBox::decode_at(payload, &mut offset)?);
2997 }
2998 _ => {
2999 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
3000 }
3001 }
3002 }
3003
3004 Ok((
3005 Self {
3006 visual,
3007 av1c_box: check_mandatory_box(av1c_box, "av1c", "av01")?,
3008 unknown_boxes,
3009 },
3010 header.external_size() + payload.len(),
3011 ))
3012 }
3013}
3014
3015impl BaseBox for Av01Box {
3016 fn box_type(&self) -> BoxType {
3017 Self::TYPE
3018 }
3019
3020 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3021 Box::new(
3022 core::iter::empty()
3023 .chain(core::iter::once(&self.av1c_box).map(as_box_object))
3024 .chain(self.unknown_boxes.iter().map(as_box_object)),
3025 )
3026 }
3027}
3028
3029#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3031#[allow(missing_docs)]
3032pub struct Av1cBox {
3033 pub seq_profile: Uint<u8, 3, 5>,
3034 pub seq_level_idx_0: Uint<u8, 5, 0>,
3035 pub seq_tier_0: Uint<u8, 1, 7>,
3036 pub high_bitdepth: Uint<u8, 1, 6>,
3037 pub twelve_bit: Uint<u8, 1, 5>,
3038 pub monochrome: Uint<u8, 1, 4>,
3039 pub chroma_subsampling_x: Uint<u8, 1, 3>,
3040 pub chroma_subsampling_y: Uint<u8, 1, 2>,
3041 pub chroma_sample_position: Uint<u8, 2, 0>,
3042 pub initial_presentation_delay_minus_one: Option<Uint<u8, 4, 0>>,
3043 pub config_obus: Vec<u8>,
3044}
3045
3046impl Av1cBox {
3047 pub const TYPE: BoxType = BoxType::Normal(*b"av1C");
3049
3050 const MARKER: Uint<u8, 1, 7> = Uint::new(1);
3051 const VERSION: Uint<u8, 7, 0> = Uint::new(1);
3052}
3053
3054impl Encode for Av1cBox {
3055 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3056 let header = BoxHeader::new_variable_size(Self::TYPE);
3057 let mut offset = header.encode(buf)?;
3058 offset += (Self::MARKER.to_bits() | Self::VERSION.to_bits()).encode(&mut buf[offset..])?;
3059 offset += (self.seq_profile.to_bits() | self.seq_level_idx_0.to_bits())
3060 .encode(&mut buf[offset..])?;
3061 offset += (self.seq_tier_0.to_bits()
3062 | self.high_bitdepth.to_bits()
3063 | self.twelve_bit.to_bits()
3064 | self.monochrome.to_bits()
3065 | self.chroma_subsampling_x.to_bits()
3066 | self.chroma_subsampling_y.to_bits()
3067 | self.chroma_sample_position.to_bits())
3068 .encode(&mut buf[offset..])?;
3069 if let Some(v) = self.initial_presentation_delay_minus_one {
3070 offset += (0b1_0000 | v.to_bits()).encode(&mut buf[offset..])?;
3071 } else {
3072 offset += 0u8.encode(&mut buf[offset..])?;
3073 }
3074 offset += self.config_obus.encode(&mut buf[offset..])?;
3075 header.finalize_box_size(&mut buf[..offset])?;
3076 Ok(offset)
3077 }
3078}
3079
3080impl Decode for Av1cBox {
3081 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3082 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3083 header.box_type.expect(Self::TYPE)?;
3084
3085 let mut offset = 0;
3086 let b = u8::decode_at(payload, &mut offset)?;
3087 let marker = Uint::from_bits(b);
3088 let version = Uint::from_bits(b);
3089 if marker != Self::MARKER {
3090 return Err(Error::invalid_data("Unexpected av1C marker"));
3091 }
3092 if version != Self::VERSION {
3093 return Err(Error::invalid_data(format!(
3094 "Unsupported av1C version: {}",
3095 version.get()
3096 )));
3097 }
3098
3099 let b = u8::decode_at(payload, &mut offset)?;
3100 let seq_profile = Uint::from_bits(b);
3101 let seq_level_idx_0 = Uint::from_bits(b);
3102
3103 let b = u8::decode_at(payload, &mut offset)?;
3104 let seq_tier_0 = Uint::from_bits(b);
3105 let high_bitdepth = Uint::from_bits(b);
3106 let twelve_bit = Uint::from_bits(b);
3107 let monochrome = Uint::from_bits(b);
3108 let chroma_subsampling_x = Uint::from_bits(b);
3109 let chroma_subsampling_y = Uint::from_bits(b);
3110 let chroma_sample_position = Uint::from_bits(b);
3111
3112 let b = u8::decode_at(payload, &mut offset)?;
3113 let initial_presentation_delay_minus_one = if Uint::<u8, 1, 4>::from_bits(b).get() == 1 {
3114 Some(Uint::from_bits(b))
3115 } else {
3116 None
3117 };
3118
3119 let config_obus = payload[offset..].to_vec();
3120
3121 Ok((
3122 Self {
3123 seq_profile,
3124 seq_level_idx_0,
3125 seq_tier_0,
3126 high_bitdepth,
3127 twelve_bit,
3128 monochrome,
3129 chroma_subsampling_x,
3130 chroma_subsampling_y,
3131 chroma_sample_position,
3132 initial_presentation_delay_minus_one,
3133 config_obus,
3134 },
3135 header.external_size() + payload.len(),
3136 ))
3137 }
3138}
3139
3140impl BaseBox for Av1cBox {
3141 fn box_type(&self) -> BoxType {
3142 Self::TYPE
3143 }
3144
3145 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3146 Box::new(core::iter::empty())
3147 }
3148}
3149
3150#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3152#[allow(missing_docs)]
3153pub struct SttsEntry {
3154 pub sample_count: u32,
3155 pub sample_delta: u32,
3156}
3157
3158#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3160#[allow(missing_docs)]
3161pub struct SttsBox {
3162 pub entries: Vec<SttsEntry>,
3163}
3164
3165impl SttsBox {
3166 pub const TYPE: BoxType = BoxType::Normal(*b"stts");
3168
3169 pub fn from_sample_deltas<I>(sample_deltas: I) -> Self
3171 where
3172 I: IntoIterator<Item = u32>,
3173 {
3174 let mut entries = Vec::<SttsEntry>::new();
3175 for sample_delta in sample_deltas {
3176 if let Some(last) = entries.last_mut()
3177 && last.sample_delta == sample_delta
3178 {
3179 last.sample_count += 1;
3180 continue;
3181 }
3182 entries.push(SttsEntry {
3183 sample_count: 1,
3184 sample_delta,
3185 });
3186 }
3187 Self { entries }
3188 }
3189}
3190
3191impl Encode for SttsBox {
3192 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3193 let header = BoxHeader::new_variable_size(Self::TYPE);
3194 let mut offset = header.encode(buf)?;
3195 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
3196 offset += (self.entries.len() as u32).encode(&mut buf[offset..])?;
3197 for entry in &self.entries {
3198 offset += entry.sample_count.encode(&mut buf[offset..])?;
3199 offset += entry.sample_delta.encode(&mut buf[offset..])?;
3200 }
3201 header.finalize_box_size(&mut buf[..offset])?;
3202 Ok(offset)
3203 }
3204}
3205
3206impl Decode for SttsBox {
3207 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3208 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3209 header.box_type.expect(Self::TYPE)?;
3210
3211 let mut offset = 0;
3212 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
3213 let count = u32::decode_at(payload, &mut offset)? as usize;
3214
3215 let mut entries = Vec::with_capacity(count);
3216 for _ in 0..count {
3217 entries.push(SttsEntry {
3218 sample_count: u32::decode_at(payload, &mut offset)?,
3219 sample_delta: u32::decode_at(payload, &mut offset)?,
3220 });
3221 }
3222
3223 Ok((Self { entries }, header.external_size() + payload.len()))
3224 }
3225}
3226
3227impl BaseBox for SttsBox {
3228 fn box_type(&self) -> BoxType {
3229 Self::TYPE
3230 }
3231
3232 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3233 Box::new(core::iter::empty())
3234 }
3235}
3236
3237impl FullBox for SttsBox {
3238 fn full_box_version(&self) -> u8 {
3239 0
3240 }
3241
3242 fn full_box_flags(&self) -> FullBoxFlags {
3243 FullBoxFlags::new(0)
3244 }
3245}
3246
3247#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3249#[allow(missing_docs)]
3250pub struct StscEntry {
3251 pub first_chunk: NonZeroU32,
3252 pub sample_per_chunk: u32,
3253 pub sample_description_index: NonZeroU32,
3254}
3255
3256#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3258#[allow(missing_docs)]
3259pub struct StscBox {
3260 pub entries: Vec<StscEntry>,
3261}
3262
3263impl StscBox {
3264 pub const TYPE: BoxType = BoxType::Normal(*b"stsc");
3266}
3267
3268impl Encode for StscBox {
3269 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3270 let header = BoxHeader::new_variable_size(Self::TYPE);
3271 let mut offset = header.encode(buf)?;
3272 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
3273 offset += (self.entries.len() as u32).encode(&mut buf[offset..])?;
3274 for entry in &self.entries {
3275 offset += entry.first_chunk.encode(&mut buf[offset..])?;
3276 offset += entry.sample_per_chunk.encode(&mut buf[offset..])?;
3277 offset += entry.sample_description_index.encode(&mut buf[offset..])?;
3278 }
3279 header.finalize_box_size(&mut buf[..offset])?;
3280 Ok(offset)
3281 }
3282}
3283
3284impl Decode for StscBox {
3285 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3286 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3287 header.box_type.expect(Self::TYPE)?;
3288
3289 let mut offset = 0;
3290 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
3291 let count = u32::decode_at(payload, &mut offset)?;
3292
3293 let mut entries = Vec::with_capacity(count as usize);
3294 for _ in 0..count {
3295 entries.push(StscEntry {
3296 first_chunk: NonZeroU32::decode_at(payload, &mut offset)?,
3297 sample_per_chunk: u32::decode_at(payload, &mut offset)?,
3298 sample_description_index: NonZeroU32::decode_at(payload, &mut offset)?,
3299 });
3300 }
3301
3302 Ok((Self { entries }, header.external_size() + payload.len()))
3303 }
3304}
3305
3306impl BaseBox for StscBox {
3307 fn box_type(&self) -> BoxType {
3308 Self::TYPE
3309 }
3310
3311 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3312 Box::new(core::iter::empty())
3313 }
3314}
3315
3316impl FullBox for StscBox {
3317 fn full_box_version(&self) -> u8 {
3318 0
3319 }
3320
3321 fn full_box_flags(&self) -> FullBoxFlags {
3322 FullBoxFlags::new(0)
3323 }
3324}
3325
3326#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3328#[allow(missing_docs)]
3329pub enum StszBox {
3330 Fixed {
3331 sample_size: NonZeroU32,
3332 sample_count: u32,
3333 },
3334 Variable {
3335 entry_sizes: Vec<u32>,
3336 },
3337}
3338
3339impl StszBox {
3340 pub const TYPE: BoxType = BoxType::Normal(*b"stsz");
3342}
3343
3344impl Encode for StszBox {
3345 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3346 let header = BoxHeader::new_variable_size(Self::TYPE);
3347 let mut offset = header.encode(buf)?;
3348 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
3349 match self {
3350 StszBox::Fixed {
3351 sample_size,
3352 sample_count,
3353 } => {
3354 offset += sample_size.get().encode(&mut buf[offset..])?;
3355 offset += sample_count.encode(&mut buf[offset..])?;
3356 }
3357 StszBox::Variable { entry_sizes } => {
3358 offset += 0u32.encode(&mut buf[offset..])?;
3359 offset += (entry_sizes.len() as u32).encode(&mut buf[offset..])?;
3360 for size in entry_sizes {
3361 offset += size.encode(&mut buf[offset..])?;
3362 }
3363 }
3364 }
3365 header.finalize_box_size(&mut buf[..offset])?;
3366 Ok(offset)
3367 }
3368}
3369
3370impl Decode for StszBox {
3371 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3372 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3373 header.box_type.expect(Self::TYPE)?;
3374
3375 let mut offset = 0;
3376 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
3377 let sample_size = u32::decode_at(payload, &mut offset)?;
3378 let sample_count = u32::decode_at(payload, &mut offset)?;
3379
3380 let stsz_box = if let Some(sample_size) = NonZeroU32::new(sample_size) {
3381 Self::Fixed {
3382 sample_size,
3383 sample_count,
3384 }
3385 } else {
3386 let mut entry_sizes = Vec::with_capacity(sample_count as usize);
3387 for _ in 0..sample_count {
3388 entry_sizes.push(u32::decode_at(payload, &mut offset)?);
3389 }
3390 Self::Variable { entry_sizes }
3391 };
3392
3393 Ok((stsz_box, header.external_size() + payload.len()))
3394 }
3395}
3396
3397impl BaseBox for StszBox {
3398 fn box_type(&self) -> BoxType {
3399 Self::TYPE
3400 }
3401
3402 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3403 Box::new(core::iter::empty())
3404 }
3405}
3406
3407impl FullBox for StszBox {
3408 fn full_box_version(&self) -> u8 {
3409 0
3410 }
3411
3412 fn full_box_flags(&self) -> FullBoxFlags {
3413 FullBoxFlags::new(0)
3414 }
3415}
3416
3417#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3419#[allow(missing_docs)]
3420pub struct StcoBox {
3421 pub chunk_offsets: Vec<u32>,
3422}
3423
3424impl StcoBox {
3425 pub const TYPE: BoxType = BoxType::Normal(*b"stco");
3427}
3428
3429impl Encode for StcoBox {
3430 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3431 let header = BoxHeader::new_variable_size(Self::TYPE);
3432 let mut offset = header.encode(buf)?;
3433 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
3434 offset += (self.chunk_offsets.len() as u32).encode(&mut buf[offset..])?;
3435 for offset_val in &self.chunk_offsets {
3436 offset += offset_val.encode(&mut buf[offset..])?;
3437 }
3438 header.finalize_box_size(&mut buf[..offset])?;
3439 Ok(offset)
3440 }
3441}
3442
3443impl Decode for StcoBox {
3444 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3445 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3446 header.box_type.expect(Self::TYPE)?;
3447
3448 let mut offset = 0;
3449 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
3450 let count = u32::decode_at(payload, &mut offset)?;
3451
3452 let mut chunk_offsets = Vec::with_capacity(count as usize);
3453 for _ in 0..count {
3454 chunk_offsets.push(u32::decode_at(payload, &mut offset)?);
3455 }
3456
3457 Ok((
3458 Self { chunk_offsets },
3459 header.external_size() + payload.len(),
3460 ))
3461 }
3462}
3463
3464impl BaseBox for StcoBox {
3465 fn box_type(&self) -> BoxType {
3466 Self::TYPE
3467 }
3468
3469 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3470 Box::new(core::iter::empty())
3471 }
3472}
3473
3474impl FullBox for StcoBox {
3475 fn full_box_version(&self) -> u8 {
3476 0
3477 }
3478
3479 fn full_box_flags(&self) -> FullBoxFlags {
3480 FullBoxFlags::new(0)
3481 }
3482}
3483
3484#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3486#[allow(missing_docs)]
3487pub struct Co64Box {
3488 pub chunk_offsets: Vec<u64>,
3489}
3490
3491impl Co64Box {
3492 pub const TYPE: BoxType = BoxType::Normal(*b"co64");
3494}
3495
3496impl Encode for Co64Box {
3497 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3498 let header = BoxHeader::new_variable_size(Self::TYPE);
3499 let mut offset = header.encode(buf)?;
3500 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
3501 offset += (self.chunk_offsets.len() as u32).encode(&mut buf[offset..])?;
3502 for offset_val in &self.chunk_offsets {
3503 offset += offset_val.encode(&mut buf[offset..])?;
3504 }
3505 header.finalize_box_size(&mut buf[..offset])?;
3506 Ok(offset)
3507 }
3508}
3509
3510impl Decode for Co64Box {
3511 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3512 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3513 header.box_type.expect(Self::TYPE)?;
3514
3515 let mut offset = 0;
3516 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
3517 let count = u32::decode_at(payload, &mut offset)?;
3518
3519 let mut chunk_offsets = Vec::with_capacity(count as usize);
3520 for _ in 0..count {
3521 chunk_offsets.push(u64::decode_at(payload, &mut offset)?);
3522 }
3523
3524 Ok((
3525 Self { chunk_offsets },
3526 header.external_size() + payload.len(),
3527 ))
3528 }
3529}
3530
3531impl BaseBox for Co64Box {
3532 fn box_type(&self) -> BoxType {
3533 Self::TYPE
3534 }
3535
3536 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3537 Box::new(core::iter::empty())
3538 }
3539}
3540
3541impl FullBox for Co64Box {
3542 fn full_box_version(&self) -> u8 {
3543 0
3544 }
3545
3546 fn full_box_flags(&self) -> FullBoxFlags {
3547 FullBoxFlags::new(0)
3548 }
3549}
3550
3551#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3553#[allow(missing_docs)]
3554pub struct StssBox {
3555 pub sample_numbers: Vec<NonZeroU32>,
3556}
3557
3558impl StssBox {
3559 pub const TYPE: BoxType = BoxType::Normal(*b"stss");
3561}
3562
3563impl Encode for StssBox {
3564 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3565 let header = BoxHeader::new_variable_size(Self::TYPE);
3566 let mut offset = header.encode(buf)?;
3567 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
3568 offset += (self.sample_numbers.len() as u32).encode(&mut buf[offset..])?;
3569 for offset_val in &self.sample_numbers {
3570 offset += offset_val.encode(&mut buf[offset..])?;
3571 }
3572 header.finalize_box_size(&mut buf[..offset])?;
3573 Ok(offset)
3574 }
3575}
3576
3577impl Decode for StssBox {
3578 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3579 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3580 header.box_type.expect(Self::TYPE)?;
3581
3582 let mut offset = 0;
3583 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
3584 let count = u32::decode_at(payload, &mut offset)?;
3585
3586 let mut sample_numbers = Vec::with_capacity(count as usize);
3587 for _ in 0..count {
3588 sample_numbers.push(NonZeroU32::decode_at(payload, &mut offset)?);
3589 }
3590
3591 Ok((
3592 Self { sample_numbers },
3593 header.external_size() + payload.len(),
3594 ))
3595 }
3596}
3597
3598impl BaseBox for StssBox {
3599 fn box_type(&self) -> BoxType {
3600 Self::TYPE
3601 }
3602
3603 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3604 Box::new(core::iter::empty())
3605 }
3606}
3607
3608impl FullBox for StssBox {
3609 fn full_box_version(&self) -> u8 {
3610 0
3611 }
3612
3613 fn full_box_flags(&self) -> FullBoxFlags {
3614 FullBoxFlags::new(0)
3615 }
3616}
3617
3618#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3620#[allow(missing_docs)]
3621pub struct OpusBox {
3622 pub audio: AudioSampleEntryFields,
3623 pub dops_box: DopsBox,
3624 pub unknown_boxes: Vec<UnknownBox>,
3625}
3626
3627impl OpusBox {
3628 pub const TYPE: BoxType = BoxType::Normal(*b"Opus");
3630}
3631
3632impl Encode for OpusBox {
3633 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3634 let header = BoxHeader::new_variable_size(Self::TYPE);
3635 let mut offset = header.encode(buf)?;
3636 offset += self.audio.encode(&mut buf[offset..])?;
3637 offset += self.dops_box.encode(&mut buf[offset..])?;
3638 for b in &self.unknown_boxes {
3639 offset += b.encode(&mut buf[offset..])?;
3640 }
3641 header.finalize_box_size(&mut buf[..offset])?;
3642 Ok(offset)
3643 }
3644}
3645
3646impl Decode for OpusBox {
3647 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3648 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3649 header.box_type.expect(Self::TYPE)?;
3650
3651 let mut offset = 0;
3652 let audio = AudioSampleEntryFields::decode_at(payload, &mut offset)?;
3653
3654 let mut dops_box = None;
3655 let mut unknown_boxes = Vec::new();
3656
3657 while offset < payload.len() {
3658 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
3659 match child_header.box_type {
3660 DopsBox::TYPE if dops_box.is_none() => {
3661 dops_box = Some(DopsBox::decode_at(payload, &mut offset)?);
3662 }
3663 _ => {
3664 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
3665 }
3666 }
3667 }
3668
3669 Ok((
3670 Self {
3671 audio,
3672 dops_box: check_mandatory_box(dops_box, "dops", "Opus")?,
3673 unknown_boxes,
3674 },
3675 header.external_size() + payload.len(),
3676 ))
3677 }
3678}
3679
3680impl BaseBox for OpusBox {
3681 fn box_type(&self) -> BoxType {
3682 Self::TYPE
3683 }
3684
3685 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3686 Box::new(
3687 core::iter::empty()
3688 .chain(core::iter::once(&self.dops_box).map(as_box_object))
3689 .chain(self.unknown_boxes.iter().map(as_box_object)),
3690 )
3691 }
3692}
3693
3694#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3696#[allow(missing_docs)]
3697pub struct Mp4aBox {
3698 pub audio: AudioSampleEntryFields,
3699 pub esds_box: EsdsBox,
3700 pub unknown_boxes: Vec<UnknownBox>,
3701}
3702
3703impl Mp4aBox {
3704 pub const TYPE: BoxType = BoxType::Normal(*b"mp4a");
3706}
3707
3708impl Encode for Mp4aBox {
3709 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3710 let header = BoxHeader::new_variable_size(Self::TYPE);
3711 let mut offset = header.encode(buf)?;
3712 offset += self.audio.encode(&mut buf[offset..])?;
3713 offset += self.esds_box.encode(&mut buf[offset..])?;
3714 for b in &self.unknown_boxes {
3715 offset += b.encode(&mut buf[offset..])?;
3716 }
3717 header.finalize_box_size(&mut buf[..offset])?;
3718 Ok(offset)
3719 }
3720}
3721
3722impl Decode for Mp4aBox {
3723 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3724 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3725 header.box_type.expect(Self::TYPE)?;
3726
3727 let mut offset = 0;
3728 let audio = AudioSampleEntryFields::decode_at(payload, &mut offset)?;
3729
3730 let mut esds_box = None;
3731 let mut unknown_boxes = Vec::new();
3732
3733 while offset < payload.len() {
3734 let (child_header, _) = BoxHeader::decode(&payload[offset..])?;
3735 match child_header.box_type {
3736 EsdsBox::TYPE if esds_box.is_none() => {
3737 esds_box = Some(EsdsBox::decode_at(payload, &mut offset)?);
3738 }
3739 _ => {
3740 unknown_boxes.push(UnknownBox::decode_at(payload, &mut offset)?);
3741 }
3742 }
3743 }
3744
3745 Ok((
3746 Self {
3747 audio,
3748 esds_box: check_mandatory_box(esds_box, "esds", "mp4a")?,
3749 unknown_boxes,
3750 },
3751 header.external_size() + payload.len(),
3752 ))
3753 }
3754}
3755
3756impl BaseBox for Mp4aBox {
3757 fn box_type(&self) -> BoxType {
3758 Self::TYPE
3759 }
3760
3761 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3762 Box::new(
3763 core::iter::empty()
3764 .chain(core::iter::once(&self.esds_box).map(as_box_object))
3765 .chain(self.unknown_boxes.iter().map(as_box_object)),
3766 )
3767 }
3768}
3769
3770#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3772#[allow(missing_docs)]
3773pub struct AudioSampleEntryFields {
3774 pub data_reference_index: NonZeroU16,
3775 pub channelcount: u16,
3776 pub samplesize: u16,
3777 pub samplerate: FixedPointNumber<u16, u16>,
3778}
3779
3780impl AudioSampleEntryFields {
3781 pub const DEFAULT_DATA_REFERENCE_INDEX: NonZeroU16 = NonZeroU16::MIN;
3783
3784 pub const DEFAULT_SAMPLESIZE: u16 = 16;
3786}
3787
3788impl Encode for AudioSampleEntryFields {
3789 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3790 let mut offset = 0;
3791 offset += [0u8; 6].encode(&mut buf[offset..])?;
3792 offset += self.data_reference_index.encode(&mut buf[offset..])?;
3793 offset += [0u8; 4 * 2].encode(&mut buf[offset..])?;
3794 offset += self.channelcount.encode(&mut buf[offset..])?;
3795 offset += self.samplesize.encode(&mut buf[offset..])?;
3796 offset += [0u8; 2].encode(&mut buf[offset..])?;
3797 offset += [0u8; 2].encode(&mut buf[offset..])?;
3798 offset += self.samplerate.encode(&mut buf[offset..])?;
3799 Ok(offset)
3800 }
3801}
3802
3803impl Decode for AudioSampleEntryFields {
3804 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3805 let mut offset = 0;
3806 let _ = <[u8; 6]>::decode_at(buf, &mut offset)?;
3807 let data_reference_index = NonZeroU16::decode_at(buf, &mut offset)?;
3808 let _ = <[u8; 4 * 2]>::decode_at(buf, &mut offset)?;
3809 let channelcount = u16::decode_at(buf, &mut offset)?;
3810 let samplesize = u16::decode_at(buf, &mut offset)?;
3811 let _ = <[u8; 2]>::decode_at(buf, &mut offset)?;
3812 let _ = <[u8; 2]>::decode_at(buf, &mut offset)?;
3813 let samplerate = FixedPointNumber::decode_at(buf, &mut offset)?;
3814 Ok((
3815 Self {
3816 data_reference_index,
3817 channelcount,
3818 samplesize,
3819 samplerate,
3820 },
3821 offset,
3822 ))
3823 }
3824}
3825
3826#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3828#[allow(missing_docs)]
3829pub struct DopsBox {
3830 pub output_channel_count: u8,
3831 pub pre_skip: u16,
3832 pub input_sample_rate: u32,
3833 pub output_gain: i16,
3834}
3835
3836impl DopsBox {
3837 pub const TYPE: BoxType = BoxType::Normal(*b"dOps");
3839
3840 const VERSION: u8 = 0;
3841}
3842
3843impl Encode for DopsBox {
3844 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3845 let header = BoxHeader::new_variable_size(Self::TYPE);
3846 let mut offset = header.encode(buf)?;
3847 offset += Self::VERSION.encode(&mut buf[offset..])?;
3848 offset += self.output_channel_count.encode(&mut buf[offset..])?;
3849 offset += self.pre_skip.encode(&mut buf[offset..])?;
3850 offset += self.input_sample_rate.encode(&mut buf[offset..])?;
3851 offset += self.output_gain.encode(&mut buf[offset..])?;
3852 offset += 0u8.encode(&mut buf[offset..])?; header.finalize_box_size(&mut buf[..offset])?;
3854 Ok(offset)
3855 }
3856}
3857
3858impl Decode for DopsBox {
3859 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3860 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3861 header.box_type.expect(Self::TYPE)?;
3862
3863 let mut offset = 0;
3864 let version = u8::decode_at(payload, &mut offset)?;
3865 if version != Self::VERSION {
3866 return Err(Error::invalid_data(format!(
3867 "Unsupported dOps version: {version}"
3868 )));
3869 }
3870
3871 let output_channel_count = u8::decode_at(payload, &mut offset)?;
3872 let pre_skip = u16::decode_at(payload, &mut offset)?;
3873 let input_sample_rate = u32::decode_at(payload, &mut offset)?;
3874 let output_gain = i16::decode_at(payload, &mut offset)?;
3875 let channel_mapping_family = u8::decode_at(payload, &mut offset)?;
3876 if channel_mapping_family != 0 {
3877 return Err(Error::unsupported(
3878 "`ChannelMappingFamily != 0` in 'dOps' box is not supported",
3879 ));
3880 }
3881
3882 Ok((
3883 Self {
3884 output_channel_count,
3885 pre_skip,
3886 input_sample_rate,
3887 output_gain,
3888 },
3889 header.external_size() + payload.len(),
3890 ))
3891 }
3892}
3893
3894impl BaseBox for DopsBox {
3895 fn box_type(&self) -> BoxType {
3896 Self::TYPE
3897 }
3898
3899 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3900 Box::new(core::iter::empty())
3901 }
3902}
3903
3904#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3906#[allow(missing_docs)]
3907pub struct EsdsBox {
3908 pub es: EsDescriptor,
3909}
3910
3911impl EsdsBox {
3912 pub const TYPE: BoxType = BoxType::Normal(*b"esds");
3914}
3915
3916impl Encode for EsdsBox {
3917 fn encode(&self, buf: &mut [u8]) -> Result<usize> {
3918 let header = BoxHeader::new_variable_size(Self::TYPE);
3919 let mut offset = header.encode(buf)?;
3920 offset += FullBoxHeader::from_box(self).encode(&mut buf[offset..])?;
3921 offset += self.es.encode(&mut buf[offset..])?;
3922 header.finalize_box_size(&mut buf[..offset])?;
3923 Ok(offset)
3924 }
3925}
3926
3927impl Decode for EsdsBox {
3928 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
3929 let (header, payload) = BoxHeader::decode_header_and_payload(buf)?;
3930 header.box_type.expect(Self::TYPE)?;
3931
3932 let mut offset = 0;
3933 let _full_header = FullBoxHeader::decode_at(payload, &mut offset)?;
3934 let es = EsDescriptor::decode_at(payload, &mut offset)?;
3935
3936 Ok((Self { es }, header.external_size() + payload.len()))
3937 }
3938}
3939
3940impl BaseBox for EsdsBox {
3941 fn box_type(&self) -> BoxType {
3942 Self::TYPE
3943 }
3944
3945 fn children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = &'a dyn BaseBox>> {
3946 Box::new(core::iter::empty())
3947 }
3948}
3949
3950impl FullBox for EsdsBox {
3951 fn full_box_version(&self) -> u8 {
3952 0
3953 }
3954
3955 fn full_box_flags(&self) -> FullBoxFlags {
3956 FullBoxFlags::new(0)
3957 }
3958}
3959
3960#[track_caller]
3961fn check_mandatory_box<T>(maybe_box: Option<T>, expected: &str, parent: &str) -> Result<T> {
3962 maybe_box.ok_or_else(|| {
3963 Error::invalid_data(format!(
3964 "Missing mandatory '{expected}' box in '{parent}' box"
3965 ))
3966 })
3967}