1mod mvex;
2mod mvhd;
3mod trak;
4mod udta;
5
6pub use mvex::*;
7pub use mvhd::*;
8pub use trak::*;
9pub use udta::*;
10
11use crate::*;
12
13#[derive(Debug, Clone, PartialEq, Default)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct Moov {
16 pub mvhd: Mvhd,
17 pub meta: Option<Meta>,
18 pub mvex: Option<Mvex>,
19 pub trak: Vec<Trak>,
20 pub udta: Option<Udta>,
21}
22
23impl Atom for Moov {
24 const KIND: FourCC = FourCC::new(b"moov");
25
26 nested! {
27 required: [ Mvhd ],
28 optional: [ Meta, Mvex, Udta ],
29 multiple: [ Trak ],
30 }
31}
32
33#[cfg(test)]
34mod test {
35 use super::*;
36
37 #[test]
38 fn test_meta() {
39 const ENCODED: &[u8] = &[
40 0x00, 0x00, 0x03, 0x3A, 0x6D, 0x6F, 0x6F, 0x76, 0x00, 0x00, 0x00, 0x6C, 0x6D, 0x76,
41 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xEF, 0xCF, 0xD6, 0xE0, 0xEF, 0xCF, 0xD6,
42 0x00, 0x01, 0x5F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x8D, 0x6D, 0x65, 0x74, 0x61, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x68, 0x64, 0x6C, 0x72, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x49, 0x44, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x49, 0x44, 0x33, 0x32,
52 0x00, 0x00, 0x00, 0x00, 0x15, 0xC7, 0x49, 0x44, 0x33, 0x04, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x49, 0x50, 0x52, 0x49, 0x56, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x68, 0x74,
54 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2E, 0x63,
55 0x6F, 0x6D, 0x2F, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x2F, 0x73, 0x68, 0x61, 0x6B,
56 0x61, 0x2D, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65, 0x72, 0x00, 0x76, 0x32, 0x2E,
57 0x36, 0x2E, 0x31, 0x2D, 0x36, 0x33, 0x34, 0x61, 0x66, 0x36, 0x35, 0x2D, 0x72, 0x65,
58 0x6C, 0x65, 0x61, 0x73, 0x65, 0x00, 0x00, 0x02, 0x01, 0x74, 0x72, 0x61, 0x6B, 0x00,
59 0x00, 0x00, 0x5C, 0x74, 0x6B, 0x68, 0x64, 0x00, 0x00, 0x00, 0x07, 0xE0, 0xEF, 0xCF,
60 0xD6, 0xE0, 0xEF, 0xCF, 0xD6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x07,
65 0x80, 0x00, 0x00, 0x04, 0x38, 0x00, 0x00, 0x00, 0x00, 0x01, 0x79, 0x6D, 0x64, 0x69,
66 0x61, 0x00, 0x00, 0x00, 0x20, 0x6D, 0x64, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0xE0,
67 0xEF, 0xCF, 0xD6, 0xE0, 0xEF, 0xCF, 0xD6, 0x00, 0x01, 0x5F, 0x90, 0x00, 0x00, 0x00,
68 0x00, 0x55, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x68, 0x64, 0x6C, 0x72, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x64, 0x65, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x69, 0x64, 0x65, 0x6F,
71 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00, 0x00, 0x00, 0x01, 0x24, 0x6D, 0x69,
72 0x6E, 0x66, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6E, 0x66, 0x00, 0x00, 0x00, 0x1C,
73 0x64, 0x72, 0x65, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
74 0x00, 0x0C, 0x75, 0x72, 0x6C, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4,
75 0x73, 0x74, 0x62, 0x6C, 0x00, 0x00, 0x00, 0x98, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x61, 0x76, 0x63, 0x31,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x04, 0x38,
79 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
80 0x0A, 0x41, 0x56, 0x43, 0x20, 0x43, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x32, 0x61, 0x76,
83 0x63, 0x43, 0x01, 0x64, 0x00, 0x28, 0xFF, 0xE1, 0x00, 0x1A, 0x67, 0x64, 0x00, 0x28,
84 0xAC, 0xD9, 0x40, 0x78, 0x02, 0x27, 0xE5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00,
85 0x00, 0x03, 0x00, 0xF0, 0x3C, 0x60, 0xC6, 0x58, 0x01, 0x00, 0x05, 0x68, 0xEB, 0xEC,
86 0xB2, 0x2C, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x73, 0x63, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x74, 0x73, 0x7A,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x10, 0x73, 0x74, 0x63, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x14, 0x76, 0x6D, 0x68, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x65, 0x64, 0x74, 0x73,
93 0x00, 0x00, 0x00, 0x1C, 0x65, 0x6C, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x70, 0x00, 0x01, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x38, 0x6D, 0x76, 0x65, 0x78, 0x00, 0x00, 0x00, 0x10, 0x6D, 0x65,
96 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB9, 0x31, 0x50, 0x00, 0x00, 0x00, 0x20,
97 0x74, 0x72, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
98 0x00, 0x01, 0x00, 0x00, 0x0B, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 ];
100
101 let decoded = Moov::decode(&mut &ENCODED[..]).unwrap();
102 assert_eq!(
103 decoded,
104 Moov {
105 mvhd: Mvhd {
106 creation_time: 3773812694,
107 modification_time: 3773812694,
108 timescale: 90000,
109 rate: 1.into(),
110 volume: 1.into(),
111 next_track_id: 2,
112 ..Default::default()
113 },
114 meta: Some(Meta {
115 hdlr: Hdlr {
116 handler: FourCC::new(b"ID32"),
117 name: "".into()
118 },
119 items: vec![Any::Unknown(
120 FourCC::new(b"ID32"),
121 vec![
122 0, 0, 0, 0, 21, 199, 73, 68, 51, 4, 0, 0, 0, 0, 0, 73, 80, 82, 73, 86,
123 0, 0, 0, 63, 0, 0, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116,
124 104, 117, 98, 46, 99, 111, 109, 47, 103, 111, 111, 103, 108, 101, 47,
125 115, 104, 97, 107, 97, 45, 112, 97, 99, 107, 97, 103, 101, 114, 0, 118,
126 50, 46, 54, 46, 49, 45, 54, 51, 52, 97, 102, 54, 53, 45, 114, 101, 108,
127 101, 97, 115, 101
128 ]
129 )]
130 }),
131 mvex: Some(Mvex {
132 mehd: Some(Mehd {
133 fragment_duration: 28914000
134 }),
135 trex: vec![Trex {
136 track_id: 1,
137 default_sample_description_index: 1,
138 default_sample_duration: 3000,
139 ..Default::default()
140 }]
141 }),
142 trak: vec![Trak {
143 tkhd: Tkhd {
144 creation_time: 3773812694,
145 modification_time: 3773812694,
146 track_id: 1,
147 enabled: true,
148 width: 1920.into(),
149 height: 1080.into(),
150 ..Default::default()
151 },
152 edts: Some(Edts {
153 elst: Some(Elst {
154 entries: vec![ElstEntry {
155 media_time: 6000,
156 media_rate: 1,
157 ..Default::default()
158 }]
159 })
160 }),
161 meta: None,
162 mdia: Mdia {
163 mdhd: Mdhd {
164 creation_time: 3773812694,
165 modification_time: 3773812694,
166 timescale: 90000,
167 duration: 0,
168 language: "und".to_string(),
169 },
170 hdlr: Hdlr {
171 handler: b"vide".into(),
172 name: "VideoHandler".to_string(),
173 },
174 minf: Minf {
175 vmhd: Some(Vmhd {
176 graphics_mode: 0,
177 op_color: RgbColor {
178 red: 0,
179 green: 0,
180 blue: 0
181 }
182 }),
183 dinf: Dinf {
184 dref: Dref {
185 urls: vec![Url::default()]
186 }
187 },
188 stbl: Stbl {
189 stsd: Stsd {
190 codecs: vec![Avc1 {
191 visual: Visual {
192 data_reference_index: 1,
193 width: 1920,
194 height: 1080,
195 horizresolution: 72.into(),
196 vertresolution: 72.into(),
197 frame_count: 1,
198 compressor: "AVC Coding".into(),
199 depth: 24,
200 },
201 avcc: Avcc {
202 configuration_version: 1,
203 avc_profile_indication: 100,
204 profile_compatibility: 0,
205 avc_level_indication: 40,
206 length_size: 4,
207 sequence_parameter_sets: vec![vec![
208 103, 100, 0, 40, 172, 217, 64, 120, 2, 39, 229,
209 132, 0, 0, 3, 0, 4, 0, 0, 3, 0, 240, 60, 96, 198,
210 88
211 ]],
212 picture_parameter_sets: vec![vec![
213 104, 235, 236, 178, 44
214 ]],
215 ext: None,
216 },
217 btrt: None,
218 colr: None,
219 pasp: None,
220 taic: None,
221 fiel: None,
222 }
223 .into()],
224 },
225 stco: Some(Stco::default()),
226 ..Default::default()
227 },
228 ..Default::default()
229 }
230 },
231 senc: None,
232 udta: None
233 }],
234 udta: None,
235 }
236 )
237 }
238}