scuffle_mp4/boxes/types/
stbl.rs

1use std::io;
2
3use bytes::{Buf, Bytes};
4
5use super::co64::Co64;
6use super::ctts::Ctts;
7use super::padb::Padb;
8use super::sbgp::Sbgp;
9use super::sdtp::Sdtp;
10use super::stco::Stco;
11use super::stdp::Stdp;
12use super::stsc::Stsc;
13use super::stsd::Stsd;
14use super::stsh::Stsh;
15use super::stss::Stss;
16use super::stsz::Stsz;
17use super::stts::Stts;
18use super::stz2::Stz2;
19use super::subs::Subs;
20use crate::boxes::DynBox;
21use crate::boxes::header::BoxHeader;
22use crate::boxes::traits::BoxType;
23
24#[derive(Debug, Clone, PartialEq)]
25/// Sample Table Box
26/// ISO/IEC 14496-12:2022(E) 8.5.1
27pub struct Stbl {
28    pub header: BoxHeader,
29    pub stsd: Stsd,
30    pub stts: Stts,
31    pub ctts: Option<Ctts>,
32    pub stsc: Stsc,
33    pub stsz: Option<Stsz>,
34    pub stz2: Option<Stz2>,
35    pub stco: Stco,
36    pub co64: Option<Co64>,
37    pub stss: Option<Stss>,
38    pub stsh: Option<Stsh>,
39    pub padb: Option<Padb>,
40    pub stdp: Option<Stdp>,
41    pub sdtp: Option<Sdtp>,
42    pub sbgp: Option<Sbgp>,
43    pub subs: Option<Subs>,
44    pub unknown: Vec<DynBox>,
45}
46
47impl Stbl {
48    pub fn new(stsd: Stsd, stts: Stts, stsc: Stsc, stco: Stco, stsz: Option<Stsz>) -> Self {
49        Self {
50            header: BoxHeader::new(Self::NAME),
51            stsd,
52            stts,
53            ctts: None,
54            stsc,
55            stsz,
56            stz2: None,
57            stco,
58            co64: None,
59            stss: None,
60            stsh: None,
61            padb: None,
62            stdp: None,
63            sdtp: None,
64            sbgp: None,
65            subs: None,
66            unknown: Vec::new(),
67        }
68    }
69}
70
71impl BoxType for Stbl {
72    const NAME: [u8; 4] = *b"stbl";
73
74    fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self> {
75        let mut reader = io::Cursor::new(data);
76        let mut stsd = None;
77        let mut stts = None;
78        let mut ctts = None;
79        let mut stsc = None;
80        let mut stsz = None;
81        let mut stz2 = None;
82        let mut stco = None;
83        let mut co64 = None;
84        let mut stss = None;
85        let mut stsh = None;
86        let mut padb = None;
87        let mut stdp = None;
88        let mut sdtp = None;
89        let mut sbgp = None;
90        let mut subs = None;
91        let mut unknown = Vec::new();
92
93        while reader.has_remaining() {
94            let dyn_box = DynBox::demux(&mut reader)?;
95
96            match dyn_box {
97                DynBox::Stsd(b) => {
98                    stsd = Some(*b);
99                }
100                DynBox::Stts(b) => {
101                    stts = Some(*b);
102                }
103                DynBox::Ctts(b) => {
104                    ctts = Some(*b);
105                }
106                DynBox::Stsc(b) => {
107                    stsc = Some(*b);
108                }
109                DynBox::Stsz(b) => {
110                    stsz = Some(*b);
111                }
112                DynBox::Stz2(b) => {
113                    stz2 = Some(*b);
114                }
115                DynBox::Stco(b) => {
116                    stco = Some(*b);
117                }
118                DynBox::Co64(b) => {
119                    co64 = Some(*b);
120                }
121                DynBox::Stss(b) => {
122                    stss = Some(*b);
123                }
124                DynBox::Stsh(b) => {
125                    stsh = Some(*b);
126                }
127                DynBox::Padb(b) => {
128                    padb = Some(*b);
129                }
130                DynBox::Stdp(b) => {
131                    stdp = Some(*b);
132                }
133                DynBox::Sdtp(b) => {
134                    sdtp = Some(*b);
135                }
136                DynBox::Sbgp(b) => {
137                    sbgp = Some(*b);
138                }
139                DynBox::Subs(b) => {
140                    subs = Some(*b);
141                }
142                _ => {
143                    unknown.push(dyn_box);
144                }
145            }
146        }
147
148        let stsd = stsd.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "stsd box not found in stbl box"))?;
149        let stts = stts.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "stts box not found in stbl box"))?;
150        let stsc = stsc.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "stsc box not found in stbl box"))?;
151        let stco = stco.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "stco box not found in stbl box"))?;
152
153        Ok(Self {
154            header,
155            stsd,
156            stts,
157            ctts,
158            stsc,
159            stsz,
160            stz2,
161            stco,
162            co64,
163            stss,
164            stsh,
165            padb,
166            stdp,
167            sdtp,
168            sbgp,
169            subs,
170            unknown,
171        })
172    }
173
174    fn primitive_size(&self) -> u64 {
175        let mut size = self.stsd.size();
176        size += self.stts.size();
177        size += self.ctts.as_ref().map(|b| b.size()).unwrap_or(0);
178        size += self.stsc.size();
179        size += self.stsz.as_ref().map(|b| b.size()).unwrap_or(0);
180        size += self.stz2.as_ref().map(|b| b.size()).unwrap_or(0);
181        size += self.stco.size();
182        size += self.co64.as_ref().map(|b| b.size()).unwrap_or(0);
183        size += self.stss.as_ref().map(|b| b.size()).unwrap_or(0);
184        size += self.stsh.as_ref().map(|b| b.size()).unwrap_or(0);
185        size += self.padb.as_ref().map(|b| b.size()).unwrap_or(0);
186        size += self.stdp.as_ref().map(|b| b.size()).unwrap_or(0);
187        size += self.sdtp.as_ref().map(|b| b.size()).unwrap_or(0);
188        size += self.sbgp.as_ref().map(|b| b.size()).unwrap_or(0);
189        size += self.subs.as_ref().map(|b| b.size()).unwrap_or(0);
190        size += self.unknown.iter().map(|b| b.size()).sum::<u64>();
191        size
192    }
193
194    fn primitive_mux<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
195        self.stsd.mux(writer)?;
196        self.stts.mux(writer)?;
197        if let Some(ctts) = &self.ctts {
198            ctts.mux(writer)?;
199        }
200        self.stsc.mux(writer)?;
201        if let Some(stsz) = &self.stsz {
202            stsz.mux(writer)?;
203        }
204        if let Some(stz2) = &self.stz2 {
205            stz2.mux(writer)?;
206        }
207        self.stco.mux(writer)?;
208        if let Some(co64) = &self.co64 {
209            co64.mux(writer)?;
210        }
211        if let Some(stss) = &self.stss {
212            stss.mux(writer)?;
213        }
214        if let Some(stsh) = &self.stsh {
215            stsh.mux(writer)?;
216        }
217        if let Some(padb) = &self.padb {
218            padb.mux(writer)?;
219        }
220        if let Some(stdp) = &self.stdp {
221            stdp.mux(writer)?;
222        }
223        if let Some(sdtp) = &self.sdtp {
224            sdtp.mux(writer)?;
225        }
226        if let Some(sbgp) = &self.sbgp {
227            sbgp.mux(writer)?;
228        }
229        if let Some(subs) = &self.subs {
230            subs.mux(writer)?;
231        }
232        for unknown in &self.unknown {
233            unknown.mux(writer)?;
234        }
235        Ok(())
236    }
237}