1use crate::*;
2
3ext! {
4 name: Mvhd,
5 versions: [0,1],
6 flags: {}
7}
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Mvhd {
12 pub creation_time: u64,
13 pub modification_time: u64,
14 pub timescale: u32,
15 pub duration: u64,
16
17 pub rate: FixedPoint<u16>,
18 pub volume: FixedPoint<u8>,
19
20 pub matrix: Matrix,
21 pub next_track_id: u32,
22}
23
24impl AtomExt for Mvhd {
25 const KIND_EXT: FourCC = FourCC::new(b"mvhd");
26
27 type Ext = MvhdExt;
28
29 fn decode_body_ext<B: Buf>(buf: &mut B, ext: MvhdExt) -> Result<Self> {
30 let (creation_time, modification_time, timescale, duration) = match ext.version {
31 MvhdVersion::V1 => (
32 u64::decode(buf)?,
33 u64::decode(buf)?,
34 u32::decode(buf)?,
35 u64::decode(buf)?,
36 ),
37 MvhdVersion::V0 => (
38 u32::decode(buf)? as u64,
39 u32::decode(buf)? as u64,
40 u32::decode(buf)?,
41 u32::decode(buf)? as u64,
42 ),
43 };
44
45 let rate = FixedPoint::decode(buf)?;
46 let volume = FixedPoint::decode(buf)?;
47
48 u16::decode(buf)?; u64::decode(buf)?; let matrix = Matrix::decode(buf)?;
52
53 <[u8; 24]>::decode(buf)?; let next_track_id = u32::decode(buf)?;
56
57 Ok(Mvhd {
58 creation_time,
59 modification_time,
60 timescale,
61 duration,
62 rate,
63 volume,
64 matrix,
65 next_track_id,
66 })
67 }
68
69 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<MvhdExt> {
70 self.creation_time.encode(buf)?;
71 self.modification_time.encode(buf)?;
72 self.timescale.encode(buf)?;
73 self.duration.encode(buf)?;
74
75 self.rate.encode(buf)?;
76 self.volume.encode(buf)?;
77
78 0u16.encode(buf)?; 0u64.encode(buf)?; self.matrix.encode(buf)?;
82
83 [0u8; 24].encode(buf)?; self.next_track_id.encode(buf)?;
86
87 Ok(MvhdVersion::V1.into())
88 }
89}
90
91impl Default for Mvhd {
92 fn default() -> Self {
93 Mvhd {
94 creation_time: 0,
95 modification_time: 0,
96 timescale: 1000,
97 duration: 0,
98 rate: Default::default(),
99 matrix: Default::default(),
100 volume: Default::default(),
101 next_track_id: 1,
102 }
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn test_mvhd32() {
112 let expected = Mvhd {
113 creation_time: 100,
114 modification_time: 200,
115 timescale: 1000,
116 duration: 634634,
117 rate: 1.into(),
118 volume: 1.into(),
119 matrix: Matrix::default(),
120 next_track_id: 1,
121 };
122
123 let mut buf = Vec::new();
124 expected.encode(&mut buf).unwrap();
125
126 let mut buf = buf.as_ref();
127 let decoded = Mvhd::decode(&mut buf).unwrap();
128 assert_eq!(decoded, expected);
129 }
130
131 #[test]
132 fn test_mvhd64() {
133 let expected = Mvhd {
134 creation_time: 100,
135 modification_time: 200,
136 timescale: 1000,
137 duration: 634634,
138 rate: 1.into(),
139 volume: 1.into(),
140 matrix: Matrix::default(),
141 next_track_id: 1,
142 };
143
144 let mut buf = Vec::new();
145 expected.encode(&mut buf).unwrap();
146
147 let mut buf = buf.as_ref();
148 let output = Mvhd::decode(&mut buf).unwrap();
149 assert_eq!(output, expected);
150 }
151}