scuffle_mp4/boxes/types/
moof.rs

1use std::io;
2
3use bytes::{Buf, Bytes};
4
5use super::mfhd::Mfhd;
6use super::traf::Traf;
7use crate::boxes::DynBox;
8use crate::boxes::header::BoxHeader;
9use crate::boxes::traits::BoxType;
10
11#[derive(Debug, Clone, PartialEq)]
12/// Movie Fragment Box
13/// ISO/IEC 14496-12:2022(E) - 8.8.4
14pub struct Moof {
15    pub header: BoxHeader,
16    pub mfhd: Mfhd,
17    pub traf: Vec<Traf>,
18    pub unknown: Vec<DynBox>,
19}
20
21impl Moof {
22    pub fn new(mfhd: Mfhd, traf: Vec<Traf>) -> Self {
23        Self {
24            header: BoxHeader::new(Self::NAME),
25            mfhd,
26            traf,
27            unknown: Vec::new(),
28        }
29    }
30}
31
32impl BoxType for Moof {
33    const NAME: [u8; 4] = *b"moof";
34
35    fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self> {
36        let mut reader = io::Cursor::new(data);
37
38        let mut unknown = Vec::new();
39
40        let mut traf = Vec::new();
41        let mut mfhd = None;
42
43        while reader.has_remaining() {
44            let box_ = DynBox::demux(&mut reader)?;
45            match box_ {
46                DynBox::Mfhd(b) => {
47                    mfhd = Some(*b);
48                }
49                DynBox::Traf(b) => {
50                    traf.push(*b);
51                }
52                _ => unknown.push(box_),
53            }
54        }
55
56        let mfhd = mfhd.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "moof box must contain mfhd box"))?;
57
58        Ok(Self {
59            header,
60            mfhd,
61            traf,
62            unknown,
63        })
64    }
65
66    fn primitive_size(&self) -> u64 {
67        self.mfhd.size()
68            + self.traf.iter().map(|box_| box_.size()).sum::<u64>()
69            + self.unknown.iter().map(|box_| box_.size()).sum::<u64>()
70    }
71
72    fn primitive_mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
73        self.mfhd.mux(writer)?;
74
75        for box_ in &self.traf {
76            box_.mux(writer)?;
77        }
78
79        for box_ in &self.unknown {
80            box_.mux(writer)?;
81        }
82
83        Ok(())
84    }
85}