mp4_atom/moov/trak/mdia/minf/stbl/stsd/
sv3d.rs1use crate::*;
2
3use super::spatial::{
4 decode_children, decode_slot, decode_variant, encode_kept, ignore_trailing, spatial_children,
5};
6
7#[derive(Debug, Clone, PartialEq, Default)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15#[cfg_attr(feature = "serde", serde(default))]
16pub struct Sv3d {
17 pub svhd: Option<Svhd>,
18 pub proj: Option<Proj>,
19 pub unknown: Vec<Any>,
21}
22
23impl Eq for Sv3d {}
24
25impl Atom for Sv3d {
26 const KIND: FourCC = FourCC::new(b"sv3d");
27
28 spatial_children! { svhd: Svhd, proj: Proj }
29}
30
31#[derive(Debug, Clone, PartialEq, Eq, Default)]
33#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
34pub struct Svhd {
35 pub metadata_source: String,
36}
37
38impl AtomExt for Svhd {
39 type Ext = FullBoxV0;
40
41 const KIND_EXT: FourCC = FourCC::new(b"svhd");
42
43 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: FullBoxV0) -> Result<Self> {
44 let metadata_source = String::decode(buf)?;
45 ignore_trailing(Self::KIND_EXT, buf);
46 Ok(Svhd { metadata_source })
47 }
48
49 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<FullBoxV0> {
50 self.metadata_source.as_str().encode(buf)?;
51 Ok(FullBoxV0)
52 }
53}
54
55#[derive(Debug, Clone, PartialEq, Default)]
60#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
61#[cfg_attr(feature = "serde", serde(default))]
62pub struct Proj {
63 pub prhd: Option<Prhd>,
64 pub kind: Option<ProjKind>,
65 pub unknown: Vec<Any>,
67}
68
69impl Eq for Proj {}
70
71impl Atom for Proj {
72 const KIND: FourCC = FourCC::new(b"proj");
73
74 fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
75 let mut proj = Proj::default();
76 decode_children(buf, |kind, body| match kind {
79 Prhd::KIND => decode_slot(Self::KIND, &mut proj.prhd, body, &mut proj.unknown),
80 Equi::KIND => decode_variant(
81 Self::KIND,
82 &mut proj.kind,
83 body,
84 &mut proj.unknown,
85 ProjKind::Equi,
86 ),
87 Cbmp::KIND => decode_variant(
88 Self::KIND,
89 &mut proj.kind,
90 body,
91 &mut proj.unknown,
92 ProjKind::Cbmp,
93 ),
94 Mshp::KIND => decode_variant(
95 Self::KIND,
96 &mut proj.kind,
97 body,
98 &mut proj.unknown,
99 ProjKind::Mshp,
100 ),
101 kind => proj.unknown.push(Any::Unknown(kind, body.to_vec())),
102 })?;
103 Ok(proj)
104 }
105
106 fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
107 self.prhd.encode(buf)?;
108 encode_kept(&self.unknown, |kind| kind == Prhd::KIND, buf)?;
109 match &self.kind {
110 Some(ProjKind::Equi(atom)) => atom.encode(buf)?,
111 Some(ProjKind::Cbmp(atom)) => atom.encode(buf)?,
112 Some(ProjKind::Mshp(atom)) => atom.encode(buf)?,
113 None => {}
114 }
115 encode_kept(
116 &self.unknown,
117 |kind| matches!(kind, Equi::KIND | Cbmp::KIND | Mshp::KIND),
118 buf,
119 )?;
120 encode_kept(
121 &self.unknown,
122 |kind| !matches!(kind, Prhd::KIND | Equi::KIND | Cbmp::KIND | Mshp::KIND),
123 buf,
124 )
125 }
126}
127
128#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
131#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
132pub struct Prhd {
133 pub pose_yaw_degrees: i32,
134 pub pose_pitch_degrees: i32,
135 pub pose_roll_degrees: i32,
136}
137
138impl AtomExt for Prhd {
139 type Ext = FullBoxV0;
140
141 const KIND_EXT: FourCC = FourCC::new(b"prhd");
142
143 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: FullBoxV0) -> Result<Self> {
144 let prhd = Prhd {
145 pose_yaw_degrees: i32::decode(buf)?,
146 pose_pitch_degrees: i32::decode(buf)?,
147 pose_roll_degrees: i32::decode(buf)?,
148 };
149 ignore_trailing(Self::KIND_EXT, buf);
150 Ok(prhd)
151 }
152
153 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<FullBoxV0> {
154 self.pose_yaw_degrees.encode(buf)?;
155 self.pose_pitch_degrees.encode(buf)?;
156 self.pose_roll_degrees.encode(buf)?;
157 Ok(FullBoxV0)
158 }
159}
160
161#[derive(Debug, Clone, PartialEq, Eq)]
162#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
163#[non_exhaustive]
164pub enum ProjKind {
165 Equi(Equi),
166 Cbmp(Cbmp),
167 Mshp(Mshp),
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
174#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
175pub struct Equi {
176 pub projection_bounds_top: u32,
177 pub projection_bounds_bottom: u32,
178 pub projection_bounds_left: u32,
179 pub projection_bounds_right: u32,
180}
181
182impl AtomExt for Equi {
183 type Ext = FullBoxV0;
184
185 const KIND_EXT: FourCC = FourCC::new(b"equi");
186
187 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: FullBoxV0) -> Result<Self> {
188 let equi = Equi {
189 projection_bounds_top: u32::decode(buf)?,
190 projection_bounds_bottom: u32::decode(buf)?,
191 projection_bounds_left: u32::decode(buf)?,
192 projection_bounds_right: u32::decode(buf)?,
193 };
194 ignore_trailing(Self::KIND_EXT, buf);
195 Ok(equi)
196 }
197
198 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<FullBoxV0> {
199 self.projection_bounds_top.encode(buf)?;
200 self.projection_bounds_bottom.encode(buf)?;
201 self.projection_bounds_left.encode(buf)?;
202 self.projection_bounds_right.encode(buf)?;
203 Ok(FullBoxV0)
204 }
205}
206
207#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
209#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
210pub struct Cbmp {
211 pub layout: u32,
212 pub padding: u32,
213}
214
215impl AtomExt for Cbmp {
216 type Ext = FullBoxV0;
217
218 const KIND_EXT: FourCC = FourCC::new(b"cbmp");
219
220 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: FullBoxV0) -> Result<Self> {
221 let cbmp = Cbmp {
222 layout: u32::decode(buf)?,
223 padding: u32::decode(buf)?,
224 };
225 ignore_trailing(Self::KIND_EXT, buf);
226 Ok(cbmp)
227 }
228
229 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<FullBoxV0> {
230 self.layout.encode(buf)?;
231 self.padding.encode(buf)?;
232 Ok(FullBoxV0)
233 }
234}
235
236#[derive(Debug, Clone, PartialEq, Eq)]
242#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
243pub struct Mshp {
244 pub crc: u32,
245 pub encoding_four_cc: FourCC,
246 pub data: Vec<u8>,
247}
248
249impl AtomExt for Mshp {
250 type Ext = FullBoxV0;
251
252 const KIND_EXT: FourCC = FourCC::new(b"mshp");
253
254 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: FullBoxV0) -> Result<Self> {
255 Ok(Mshp {
256 crc: u32::decode(buf)?,
257 encoding_four_cc: FourCC::decode(buf)?,
258 data: Vec::decode(buf)?,
259 })
260 }
261
262 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<FullBoxV0> {
263 self.crc.encode(buf)?;
264 self.encoding_four_cc.encode(buf)?;
265 self.data.encode(buf)?;
266 Ok(FullBoxV0)
267 }
268}