shiguredo_mp4/
boxes.rs

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