scuffle_mp4/boxes/types/
stbl.rs1use 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)]
25pub 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}