1use std::{
4 convert::{TryFrom, TryInto},
5 io::Read,
6};
7
8pub use error::IvfError;
9
10mod error;
11
12type Result<T> = std::result::Result<T, IvfError>;
13
14#[derive(Debug, Clone)]
16pub struct Ivf<R> {
17 reader: R,
18 header: IvfHeader,
19
20 size_buffer: [u8; 4],
21 timestamp_buffer: [u8; 8],
22}
23
24impl<R: Read> Ivf<R> {
25 pub fn new(mut reader: R) -> Result<Self> {
27 let mut d = vec![0u8; std::mem::size_of::<IvfHeader>()];
28 reader.read_exact(&mut d)?;
29
30 let header = IvfHeader {
31 signature: [d[0], d[1], d[2], d[3]],
32 version: u16::from_le_bytes(d[4..=5].try_into()?),
33 length: u16::from_le_bytes(d[6..=7].try_into()?),
34 four_cc: [d[8], d[9], d[10], d[11]],
35 width: u16::from_le_bytes(d[12..=13].try_into()?),
36 height: u16::from_le_bytes(d[14..=15].try_into()?),
37 frame_rate_rate: u32::from_le_bytes(d[16..=19].try_into()?),
38 frame_rate_scale: u32::from_le_bytes(d[20..=23].try_into()?),
39 frame_count: u32::from_le_bytes(d[24..=27].try_into()?),
40 _reserved: [d[28], d[29], d[30], d[31]],
41 };
42
43 if header.signature != [0x44, 0x4B, 0x49, 0x46] {
44 return Err(IvfError::InvalidHeader("invalid signature".to_owned()));
45 }
46
47 if header.version != 0 {
48 return Err(IvfError::InvalidHeader("invalid version".to_owned()));
49 }
50
51 if header.length != 32 {
52 return Err(IvfError::InvalidHeader("invalid length".to_owned()));
53 }
54
55 if header.four_cc != [0x56, 0x50, 0x39, 0x30] {
56 return Err(IvfError::InvalidHeader(format!(
57 "invalid four_cc: {:?}",
58 header.four_cc
59 )));
60 }
61
62 Ok(Self {
63 reader,
64 header,
65 size_buffer: [0u8; 4],
66 timestamp_buffer: [0u8; 8],
67 })
68 }
69
70 pub fn width(&self) -> u16 {
72 self.header.width
73 }
74
75 pub fn height(&self) -> u16 {
77 self.header.height
78 }
79
80 pub fn frame_rate_rate(&self) -> u32 {
85 self.header.frame_rate_rate
86 }
87
88 pub fn frame_rate_scale(&self) -> u32 {
90 self.header.frame_rate_scale
91 }
92
93 pub fn frame_count(&self) -> u32 {
95 self.header.frame_count
96 }
97
98 pub fn read_frame(&mut self) -> Result<Option<Frame>> {
102 if self.reader.read_exact(&mut self.size_buffer).is_err() {
103 return Ok(None);
104 }
105 if self.reader.read_exact(&mut self.timestamp_buffer).is_err() {
106 return Err(IvfError::UnexpectedFileEnding);
107 }
108
109 let size = usize::try_from(u32::from_le_bytes(self.size_buffer))?;
110 let timestamp = u64::from_le_bytes(self.timestamp_buffer);
111
112 let mut data = vec![0u8; size];
113
114 if self.reader.read_exact(&mut data).is_err() {
115 return Err(IvfError::UnexpectedFileEnding);
116 }
117
118 Ok(Some(Frame {
119 timestamp,
120 packet: data,
121 }))
122 }
123}
124
125#[derive(Debug, Clone)]
127struct IvfHeader {
128 signature: [u8; 4],
129 version: u16,
130 length: u16,
131 four_cc: [u8; 4],
132 width: u16,
133 height: u16,
134 frame_rate_rate: u32,
135 frame_rate_scale: u32,
136 frame_count: u32,
137 _reserved: [u8; 4],
138}
139
140#[derive(Debug, Clone)]
144pub struct Frame {
145 pub timestamp: u64,
147 pub packet: Vec<u8>,
149}
150
151#[cfg(test)]
152mod tests {
153 #![allow(clippy::unwrap_used)]
154 #![allow(clippy::panic)]
155
156 use std::io::Cursor;
157
158 use super::*;
159
160 #[test]
161 fn parse_ivf_header() {
162 let header: Vec<u8> = vec![
163 0x44, 0x4B, 0x49, 0x46, 0x00, 0x00, 0x20, 0x00, 0x56, 0x50, 0x39, 0x30, 0xB0, 0x00,
164 0x90, 0x00, 0x30, 0x75, 0x00, 0x00, 0xE8, 0x03, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x98, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00,
167 ];
168 let cursor = Cursor::new(header);
169
170 let ivf = Ivf::new(cursor).unwrap();
171
172 assert_eq!(ivf.width(), 176);
173 assert_eq!(ivf.height(), 144);
174 assert_eq!(ivf.frame_rate_rate(), 30000);
175 assert_eq!(ivf.frame_rate_scale(), 1000);
176 assert_eq!(ivf.frame_count(), 29);
177 }
178
179 #[test]
180 fn iter_ivf() {
181 let data: Vec<u8> = vec![
182 0x44, 0x4B, 0x49, 0x46, 0x00, 0x00, 0x20, 0x00, 0x56, 0x50, 0x39, 0x30, 0xB0, 0x00,
183 0x90, 0x00, 0x30, 0x75, 0x00, 0x00, 0xE8, 0x03, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0xF0, 0x08, 0x00, 0x9D, 0x01, 0x2A, 0xB0, 0x00, 0x90, 0x00, 0x0B, 0xC7,
186 0x08, 0x85, 0x85, 0x88, 0x85, 0x84, 0x88, 0x74, 0x82, 0x00, 0x06, 0xA6, 0x5F, 0x5A,
187 0xEA, 0x42, 0x91, 0xAE, 0xF7, 0xB6, 0xFB, 0x41, 0x22, 0x4F, 0xC7, 0xAC, 0xCB, 0xD6,
188 0xBA, 0x0C, 0x17, 0x4D, 0x59, 0x0A, 0x3B, 0xD3, 0x6E, 0x61, 0xB6, 0x2F, 0xD5, 0xE4,
189 0xA8, 0xF6, 0x14, 0x7B, 0x14, 0xCE, 0x81, 0xB7, 0x98, 0x21, 0x76, 0xDB, 0x4A, 0xC2,
190 0x86, 0xD1, 0x69, 0xA4, 0x61, 0xA1, 0x8D, 0xD4, 0x84, 0x82, 0xA8, 0x7F, 0x00, 0x06,
191 0x00, 0x00, 0xFE, 0xEC, 0x22, 0xCC, 0x00, 0x00, 0xEB, 0x0D, 0x20, 0x61, 0x77, 0x0F,
192 0xE4, 0x00, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x71, 0x04, 0x00, 0x2F, 0x13, 0xF8, 0x00, 0x18, 0x00, 0x1D, 0xCA, 0xB7, 0xF4, 0x00,
194 0x01, 0x2F, 0x2D, 0x0E, 0x45, 0xE5, 0xA1, 0xC4, 0x97, 0xDF, 0xF9, 0x99, 0xE2, 0x46,
195 0xA7, 0xB1, 0x51, 0x64, 0x42, 0x10, 0x6B, 0x3F, 0x0D, 0x00, 0x09, 0x00, 0x00, 0xFE,
196 0xE6, 0xC8, 0x09, 0xFB, 0xFB, 0xA3, 0x38, 0x00, 0xA8, 0xE3, 0x00, 0xA2, 0x5A, 0x83,
197 0x40, 0x45, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1,
198 0x05, 0x00, 0x2F, 0x13, 0xF8, 0x00, 0x18, 0x6F, 0x9B, 0x9F, 0xE2, 0xEB, 0x0A, 0xD9,
199 0x1D, 0x1C, 0x30, 0x01, 0x3D, 0x9A, 0x38, 0x3A, 0x2E, 0xE0, 0x02, 0xA3, 0xFB, 0x06,
200 0xE1, 0xDC, 0x12, 0x83, 0x7E, 0x67, 0x40, 0x5C, 0x67, 0xF0, 0x2A, 0x87, 0x83, 0xD3,
201 0xD8, 0xB2, 0x10, 0x18, 0x9C, 0xA8, 0x0A, 0x00, 0x00, 0xFE, 0xE6, 0xC7, 0xB2, 0x02,
202 0x54, 0x76, 0x1E, 0x64, 0x00, 0xD1, 0x20, 0x96, 0x1D, 0x41, 0x98, 0xC0, 0x43, 0x00,
203 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x05, 0x00, 0x2F,
204 0x13, 0xF8, 0x00, 0x18, 0x89, 0x19, 0x05, 0xAE, 0xAA, 0x1D, 0xF8, 0x00, 0xA5, 0xB5,
205 0xBC, 0xD0, 0x9E, 0x13, 0xC2, 0xBF, 0x22, 0x8F, 0x1E, 0x00, 0x4B, 0x7F, 0x62, 0xAA,
206 0x31, 0x6D, 0xB2, 0x38, 0x68, 0x92, 0x94, 0x80, 0xE0, 0x12, 0xBD, 0x4D, 0x52, 0xF3,
207 0x50, 0x68, 0x09, 0x00, 0x00, 0xFE, 0x8A, 0x35, 0x89, 0xE1, 0x91, 0x58, 0xBA, 0x00,
208 0x28, 0xD4, 0x44, 0xC3, 0xC8, 0x56, 0xC0, 0x5D, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0x07, 0x00, 0x2F, 0x13, 0xB0, 0x00, 0x18, 0x54,
210 0x26, 0xD7, 0xB8, 0x2B, 0x68, 0x62, 0xF0, 0xC0, 0x0B, 0x0C, 0x4B, 0x2C, 0xA4, 0x5F,
211 0x60, 0x61, 0x76, 0x25, 0x06, 0xC2, 0xDB, 0xB9, 0x6D, 0x70, 0x00, 0x3E, 0x73, 0x07,
212 0x93, 0x7F, 0xC5, 0xDB, 0xC2, 0xA5, 0x35, 0x59, 0x52, 0x66, 0x5F, 0xEB, 0x0A, 0xB5,
213 0x6E, 0xD3, 0xC8, 0x0C, 0xF3, 0x94, 0x1B, 0x07, 0x2A, 0xBF, 0xC5, 0x8F, 0x94, 0xBD,
214 0x18, 0x0E, 0x00, 0x00, 0xFE, 0xA0, 0xAA, 0xF5, 0x13, 0xFE, 0xB6, 0x60, 0xE2, 0xF5,
215 0xA2, 0xF4, 0x70, 0x00, 0x7E, 0xB4, 0x1F, 0x62, 0x2D, 0x60, 0xB4, 0x80, 0x11, 0x00,
216 0x3B, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x04,
217 0x00, 0x2F, 0x13, 0xF8, 0x00, 0x18, 0x00, 0x20, 0xFA, 0xB7, 0xF4, 0x00, 0x02, 0xDE,
218 0xC8, 0x63, 0x04, 0x31, 0x82, 0x19, 0x1C, 0x5A, 0xEF, 0x70, 0x99, 0x27, 0x5E, 0x2C,
219 0xE9, 0x99, 0x41, 0x63, 0xED, 0x1F, 0xFA, 0x89, 0x04, 0x00, 0x09, 0x00, 0x00, 0xFE,
220 0x8A, 0x5D, 0xCE, 0xA7, 0x3D, 0x38, 0x88, 0xE0, 0x48, 0x93, 0x47, 0x06, 0x83, 0x98,
221 0x00, 0x4A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1,
222 0x05, 0x00, 0x2F, 0x13, 0xBC, 0x00, 0x18, 0x00, 0x23, 0xE4, 0x1F, 0xF4, 0x00, 0x08,
223 0x12, 0xBB, 0xB0, 0x2F, 0x6E, 0xA2, 0xF7, 0x5A, 0xCA, 0x97, 0xC3, 0xA2, 0x64, 0x6B,
224 0xA2, 0xAF, 0x09, 0x5B, 0x16, 0xC9, 0x14, 0xD5, 0x1F, 0x9D, 0x85, 0x6A, 0xF5, 0xE2,
225 0x34, 0x6B, 0x65, 0xCA, 0x69, 0x32, 0x00, 0x0B, 0x00, 0x00, 0xFE, 0x9D, 0x42, 0xFB,
226 0xF5, 0x2F, 0x33, 0x34, 0x38, 0x2E, 0x80, 0x3B, 0x93, 0xDE, 0xCF, 0xE1, 0xC6, 0x24,
227 0xFE, 0xE4, 0x38, 0x46, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x51, 0x06, 0x00, 0x2F, 0x13, 0xF8, 0x00, 0x18, 0x00, 0x1F, 0x34, 0x67, 0xF4,
229 0x00, 0x03, 0x1C, 0x7D, 0x12, 0xFB, 0x7D, 0x14, 0xD9, 0xB0, 0x59, 0x37, 0xAD, 0x91,
230 0x74, 0xDC, 0x3A, 0x1E, 0x02, 0x2E, 0x0C, 0x01, 0x9C, 0x26, 0x41, 0x93, 0x4C, 0x89,
231 0x7C, 0x89, 0x7D, 0xBE, 0x68, 0xD1, 0x02, 0xEE, 0xEB, 0x1D, 0xF5, 0x00, 0x08, 0x00,
232 0x00, 0xFE, 0x8A, 0x5D, 0xD8, 0x9C, 0xA9, 0xC4, 0x00, 0x48, 0xC4, 0xAE, 0xE9, 0x63,
233 0x00, 0x4D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91,
234 0x06, 0x00, 0x2F, 0x13, 0xC4, 0x00, 0x18, 0x56, 0x7A, 0x82, 0x51, 0x4F, 0x8F, 0x34,
235 0x00, 0xC4, 0x36, 0x8D, 0x88, 0x6D, 0x1B, 0xF2, 0xCB, 0xAC, 0x7E, 0xA8, 0x04, 0xE4,
236 0x72, 0x2B, 0xBC, 0x7F, 0x1C, 0xE0, 0x5C, 0x23, 0x87, 0xA8, 0x44, 0x33, 0x46, 0x26,
237 0x57, 0xCC, 0x5D, 0x8B, 0xAC, 0x7F, 0x47, 0xEB, 0xE2, 0xAE, 0x4E, 0x00, 0x0A, 0x00,
238 0x00, 0xFE, 0x9B, 0x32, 0xDB, 0x8E, 0xDB, 0x41, 0xDF, 0x22, 0x00, 0x88, 0xB4, 0x7A,
239 0x9C, 0x09, 0x8B, 0x51, 0xDA, 0xC0, 0x43, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x71, 0x05, 0x00, 0x2F, 0x13, 0xF8, 0x00, 0x18, 0x59, 0x08,
241 0x83, 0x91, 0xD1, 0x1E, 0xD8, 0x00, 0xF5, 0x1A, 0xCE, 0xEF, 0x51, 0xAC, 0xEF, 0x12,
242 0x5A, 0x6E, 0x76, 0x76, 0x76, 0x76, 0x3A, 0x28, 0x44, 0x5C, 0x87, 0xE2, 0x61, 0x54,
243 0x38, 0x6F, 0xFD, 0xC5, 0x2C, 0x89, 0xF7, 0x40, 0x0B, 0x00, 0x00, 0xFE, 0x8A, 0x5F,
244 0xCA, 0x08, 0xD0, 0xBF, 0x58, 0x17, 0xDF, 0x00, 0x34, 0xF8, 0x3A, 0xCF, 0x65, 0x2F,
245 0x00, 0x4E, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
246 0x07, 0x00, 0x24, 0x13, 0xC8, 0x00, 0x18, 0x42, 0xE9, 0x04, 0x51, 0xB1, 0x3E, 0x50,
247 0x00, 0x88, 0xB4, 0x02, 0x6D, 0xF1, 0xE7, 0x9B, 0x31, 0x23, 0x97, 0xDC, 0xDF, 0xB3,
248 0xD8, 0x6A, 0x3A, 0xDC, 0xDB, 0xE2, 0x52, 0x99, 0xD2, 0x14, 0x51, 0x8A, 0x80, 0x41,
249 0xA7, 0x61, 0x20, 0x13, 0x66, 0xA8, 0x84, 0x38, 0x98, 0xA2, 0x1C, 0xB5, 0x76, 0x22,
250 0x87, 0x2D, 0xE8, 0x07, 0x00, 0x00, 0xFE, 0x98, 0xF5, 0xB4, 0x02, 0x59, 0xF0, 0x32,
251 0x67, 0xA8, 0x7B, 0x89, 0x41, 0x5F, 0x30, 0x45, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00,
252 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x05, 0x00, 0x2D, 0x13, 0xF8, 0x00, 0x18, 0x00,
253 0x25, 0x1B, 0xEF, 0xF4, 0x00, 0x09, 0x73, 0x8F, 0x9E, 0x61, 0x51, 0x9D, 0xF7, 0xB6,
254 0x74, 0xC9, 0x3C, 0x82, 0xDE, 0x83, 0xE6, 0x78, 0x1E, 0xCD, 0x0C, 0x88, 0x9E, 0x55,
255 0x08, 0x83, 0xD3, 0xA3, 0xFC, 0x3A, 0x0E, 0x64, 0xC0, 0x0B, 0x00, 0x00, 0xFE, 0x8A,
256 0x64, 0x98, 0x14, 0xE4, 0x05, 0xBF, 0xBF, 0xF8, 0x00, 0x32, 0x4C, 0x8F, 0xAF, 0xFC,
257 0x59, 0x0C, 0x14, 0x80, 0x52, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x71, 0x06, 0x00, 0x2D, 0x13, 0xD4, 0x00, 0x18, 0x00, 0x25, 0x94, 0xDF,
259 0xF4, 0x00, 0x0C, 0x2D, 0xF8, 0x8D, 0xF8, 0x8D, 0xF8, 0x50, 0xE2, 0x85, 0x68, 0x73,
260 0x4B, 0xD8, 0x0E, 0xD1, 0x79, 0x5C, 0x28, 0xE8, 0xFD, 0x66, 0xB7, 0x4D, 0xCC, 0x91,
261 0x72, 0x98, 0xBF, 0xE6, 0x4A, 0xED, 0xF1, 0x99, 0xBD, 0x6D, 0x13, 0xE3, 0xAC, 0x00,
262 0x0D, 0x00, 0x00, 0xFE, 0x96, 0x81, 0xAC, 0x7D, 0xC5, 0xC1, 0xC2, 0x20, 0x85, 0x57,
263 0x2A, 0x00, 0x38, 0x23, 0xF8, 0x4A, 0x90, 0x9E, 0x7E, 0x71, 0x01, 0xAE, 0x08, 0x00,
264 0x45, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x06,
265 0x00, 0x2D, 0x13, 0xF8, 0x00, 0x18, 0x00, 0x20, 0x6D, 0x27, 0xF4, 0x00, 0x05, 0x01,
266 0xF3, 0x43, 0xAA, 0xED, 0x27, 0x82, 0x2C, 0x46, 0x6A, 0xB7, 0x52, 0x45, 0x6E, 0x6E,
267 0x23, 0xF1, 0xF5, 0x20, 0xE7, 0x91, 0x7B, 0x74, 0xB1, 0x5A, 0x76, 0xE3, 0x31, 0xBF,
268 0xA2, 0xC2, 0x7E, 0xB5, 0x0B, 0x77, 0x6A, 0xC0, 0x00, 0x07, 0x00, 0x00, 0xFE, 0x8A,
269 0x64, 0x3D, 0xA3, 0x59, 0xA0, 0x95, 0xCD, 0xD4, 0xC0, 0xDF, 0x20, 0x4D, 0x00, 0x00,
270 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0x05, 0x00, 0x2D, 0x13,
271 0xDC, 0x00, 0x18, 0x00, 0x25, 0x4C, 0x97, 0xF4, 0x00, 0x0B, 0x05, 0x26, 0x3D, 0x7D,
272 0x38, 0xD8, 0x5B, 0xFE, 0x32, 0x5E, 0x74, 0xD4, 0x40, 0xB5, 0x2B, 0xA6, 0x65, 0x98,
273 0x45, 0xE4, 0xF8, 0x88, 0x92, 0x49, 0x5A, 0xCB, 0xF6, 0x77, 0x94, 0x20, 0x86, 0xBA,
274 0x37, 0x00, 0x0E, 0x00, 0x00, 0xFE, 0x93, 0xD4, 0xC4, 0x2D, 0x8C, 0x35, 0xD6, 0xC2,
275 0x6E, 0xEB, 0x00, 0x34, 0x00, 0x42, 0x46, 0x3A, 0x22, 0x42, 0x7A, 0xA9, 0x01, 0x59,
276 0xAC, 0x00, 0x43, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x31, 0x05, 0x00, 0x2D, 0x13, 0xF8, 0x00, 0x18, 0x43, 0xF7, 0x05, 0xB0, 0x41, 0xDE,
278 0x50, 0x01, 0x84, 0x02, 0x3A, 0x02, 0x28, 0xB0, 0x5B, 0x5C, 0xC8, 0x32, 0x5A, 0xEE,
279 0x67, 0x88, 0x78, 0x26, 0x86, 0xAB, 0x60, 0x8A, 0x95, 0x82, 0xD6, 0x96, 0xAC, 0xE4,
280 0xD0, 0xC0, 0x0B, 0x00, 0x00, 0xFE, 0x8A, 0x67, 0x94, 0xAD, 0x2B, 0x08, 0x21, 0xCC,
281 0x63, 0xE0, 0x3B, 0x93, 0x80, 0x20, 0x8F, 0x85, 0xFC, 0x7D, 0x38, 0x4A, 0x00, 0x00,
282 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0x05, 0x00, 0x2D, 0x13,
283 0xF8, 0x14, 0x60, 0x00, 0x98, 0x35, 0x5F, 0xD0, 0x00, 0x3B, 0x02, 0x23, 0xBF, 0xAE,
284 0x09, 0xD8, 0x8C, 0xD1, 0xCC, 0x2F, 0x69, 0xE9, 0xA7, 0x36, 0xE5, 0x6B, 0x2A, 0x7F,
285 0xDC, 0x57, 0x35, 0xD2, 0xB7, 0xF6, 0x5F, 0xBC, 0xBD, 0xEF, 0x9F, 0xC8, 0x02, 0xB3,
286 0x12, 0x11, 0xFE, 0x0A, 0x00, 0x00, 0xFE, 0x8A, 0x65, 0x7B, 0x08, 0x69, 0xD3, 0x20,
287 0x00, 0xF0, 0x14, 0x7D, 0xB2, 0x75, 0x56, 0xEC, 0x9B, 0xFB, 0xBD, 0x23, 0x00, 0x52,
288 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x07, 0x00,
289 0x22, 0x13, 0xF8, 0x00, 0x18, 0x00, 0x24, 0x8E, 0x17, 0xF4, 0x00, 0x0D, 0x75, 0xFA,
290 0xA6, 0x16, 0xE9, 0x1E, 0x71, 0x44, 0xDE, 0xC0, 0x78, 0x5B, 0x3B, 0xC7, 0x56, 0x1C,
291 0x97, 0xEB, 0x4B, 0x23, 0xD9, 0x1B, 0x61, 0xA5, 0x87, 0x3C, 0x04, 0x8D, 0x86, 0xA0,
292 0x78, 0x80, 0x29, 0x32, 0xC0, 0x46, 0x8C, 0xC8, 0xDA, 0xE9, 0x9D, 0x8E, 0x39, 0xF7,
293 0xD0, 0x0A, 0x00, 0x00, 0xFE, 0x8A, 0x5D, 0x7C, 0x9F, 0x53, 0x9E, 0x4E, 0x60, 0x00,
294 0x88, 0xB4, 0x46, 0x8F, 0x62, 0x66, 0xE1, 0x06, 0xC0, 0x78, 0x00, 0x00, 0x00, 0x12,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0A, 0x00, 0x9D, 0x01, 0x2A, 0xB0,
296 0x00, 0x90, 0x00, 0x0B, 0xC7, 0x08, 0x85, 0x85, 0x88, 0x85, 0x84, 0x88, 0x7F, 0x02,
297 0x22, 0x46, 0x41, 0x31, 0xBE, 0x71, 0xBB, 0x79, 0x3F, 0x11, 0x19, 0xBA, 0xF2, 0x2D,
298 0x21, 0xDC, 0x87, 0x72, 0x14, 0x39, 0x81, 0x98, 0x97, 0x6D, 0x0E, 0x98, 0x8A, 0xC4,
299 0x20, 0xD2, 0xEB, 0x8B, 0xBA, 0x4F, 0xF6, 0xDE, 0x2B, 0x47, 0x6B, 0x49, 0xE2, 0xEE,
300 0x93, 0xFD, 0xB7, 0x9D, 0xC7, 0x2C, 0xC4, 0x6A, 0x08, 0x7C, 0x42, 0x91, 0x2F, 0xD5,
301 0xFE, 0x7A, 0x2C, 0x30, 0x9C, 0x98, 0x98, 0xF6, 0xB8, 0x82, 0x7E, 0x20, 0x9C, 0x3F,
302 0xF5, 0xE3, 0xEE, 0x00, 0xC6, 0x00, 0x09, 0x00, 0x00, 0xFE, 0x8A, 0x5B, 0x97, 0x22,
303 0x2F, 0x26, 0x03, 0xC0, 0x5C, 0x55, 0xE5, 0x4C, 0xDA, 0xF0, 0xE7, 0x7C, 0xED, 0x7C,
304 0xE0, 0x4B, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
305 0x05, 0x00, 0x2F, 0x13, 0xF8, 0x00, 0x18, 0x6F, 0x9B, 0xF2, 0x1F, 0xFE, 0x7D, 0xE1,
306 0x90, 0x15, 0x69, 0x87, 0x00, 0x63, 0x13, 0x18, 0x98, 0xC4, 0xC6, 0x26, 0x31, 0x34,
307 0x9D, 0x72, 0xC7, 0x19, 0xBC, 0x5F, 0x32, 0x22, 0x72, 0x62, 0xDB, 0xC6, 0x37, 0x39,
308 0xC6, 0xD0, 0x0F, 0x00, 0x00, 0xFE, 0x8A, 0x5D, 0xD9, 0x8E, 0x72, 0x7A, 0x02, 0x13,
309 0x07, 0x12, 0xC2, 0x54, 0xF2, 0x00, 0x34, 0xD1, 0xF1, 0x0A, 0xF3, 0x46, 0x11, 0x85,
310 0xDD, 0xA0, 0x3B, 0x80, 0x44, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x31, 0x05, 0x00, 0x2F, 0x13, 0xF8, 0x00, 0x18, 0x56, 0x7A, 0x82, 0xA3,
312 0xFA, 0xF7, 0x34, 0x00, 0xCC, 0xC1, 0x91, 0xF4, 0x99, 0x83, 0x23, 0xE6, 0x84, 0x5C,
313 0xBD, 0xF8, 0xAD, 0xE1, 0xAB, 0x00, 0xF0, 0xCA, 0x04, 0x82, 0x29, 0xB2, 0xDA, 0xC3,
314 0xB6, 0x9E, 0x2C, 0x38, 0x0B, 0x00, 0x00, 0xFE, 0x8A, 0x5E, 0x67, 0x54, 0x04, 0x82,
315 0x38, 0x18, 0x05, 0x00, 0x39, 0x7D, 0x53, 0x81, 0x80, 0x9E, 0x86, 0x00, 0xB0, 0x00,
316 0x44, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x04,
317 0x00, 0x2F, 0x13, 0xF8, 0x00, 0x18, 0x56, 0x82, 0x81, 0x2B, 0x0B, 0x7B, 0xAA, 0x00,
318 0x51, 0x2F, 0x83, 0x77, 0xC1, 0x25, 0x51, 0x2F, 0x80, 0x65, 0x02, 0xC4, 0x75, 0x93,
319 0x7E, 0x5A, 0xB6, 0x3A, 0x18, 0x39, 0xD0, 0xDD, 0xE3, 0x00, 0x0A, 0x00, 0x00, 0xFE,
320 0x8A, 0x57, 0x42, 0x16, 0x36, 0xDC, 0xE6, 0xDB, 0x60, 0x7E, 0xB4, 0x86, 0xB5, 0xAA,
321 0xD0, 0xFE, 0x76, 0xDE, 0xB6, 0xDD, 0x05, 0xEE, 0x68, 0x00, 0x49, 0x00, 0x00, 0x00,
322 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x05, 0x00, 0x19, 0x13, 0xF8,
323 0x00, 0x18, 0x00, 0x26, 0xCC, 0x1F, 0xF4, 0x00, 0x0C, 0x3A, 0x9B, 0x49, 0x37, 0x36,
324 0x92, 0x6E, 0xE0, 0xDB, 0xA3, 0x95, 0xE4, 0x8F, 0xA8, 0x7B, 0xE7, 0xDD, 0x21, 0x9A,
325 0xB9, 0x8C, 0xD5, 0x76, 0x48, 0x33, 0x69, 0x45, 0x3D, 0xC0, 0x36, 0xF6, 0x98, 0x00,
326 0x0B, 0x00, 0x00, 0xFE, 0x8A, 0x5D, 0xD2, 0xC1, 0x5B, 0x70, 0x07, 0xDE, 0x78, 0x00,
327 0x33, 0x2A, 0xEF, 0x0C, 0x06, 0x7B, 0x71, 0xF3, 0x9F, 0x87, 0x90, 0x4A, 0x00, 0x00,
328 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x05, 0x00, 0x19, 0x13,
329 0xF8, 0x00, 0x18, 0x00, 0x28, 0x34, 0x67, 0xF4, 0x00, 0x0F, 0xE4, 0xAB, 0x0D, 0xDC,
330 0x9A, 0xED, 0xBE, 0x68, 0x47, 0xF9, 0xE0, 0x36, 0x5D, 0xA4, 0x69, 0xE2, 0x24, 0xD8,
331 0x5A, 0x85, 0x84, 0xA5, 0x3A, 0xAB, 0xF1, 0x2A, 0x5C, 0x21, 0xBE, 0x3F, 0x4B, 0x00,
332 0x0B, 0x00, 0x00, 0xFE, 0x8A, 0x5A, 0xB8, 0x23, 0x9C, 0xB8, 0x03, 0x2B, 0x9A, 0xC0,
333 0x3B, 0x43, 0x66, 0xD0, 0x17, 0x86, 0x01, 0x95, 0xB7, 0xD1, 0x49, 0xD0, 0x00, 0x4B,
334 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x05, 0x00,
335 0x19, 0x13, 0xF8, 0x00, 0x18, 0x56, 0x07, 0x02, 0xA4, 0x0A, 0xE7, 0x34, 0x01, 0x0A,
336 0xA4, 0xBB, 0x9B, 0x0F, 0xCD, 0x7F, 0x14, 0xBC, 0x50, 0x67, 0xCA, 0x67, 0x81, 0xAB,
337 0x74, 0x30, 0x15, 0xE3, 0x7C, 0x71, 0x20, 0xA7, 0x68, 0x4F, 0x54, 0x50, 0x99, 0xD2,
338 0xA6, 0x64, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x8A, 0x4A, 0x31, 0xA1, 0xB5, 0xB8, 0x3C,
339 0x86, 0xD6, 0xB4, 0x00, 0x10, 0x34, 0x2D, 0x04, 0x63, 0x7F, 0x0E, 0x3D, 0x6D, 0x85,
340 0xBA, 0xC0, 0x47, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x31, 0x06, 0x00, 0x2B, 0x13, 0xF8, 0x14, 0x60, 0x00, 0x79, 0x0E, 0x9F, 0xD0, 0x00,
342 0x07, 0xBD, 0xEF, 0x7B, 0xDE, 0xF7, 0xBF, 0x4E, 0x29, 0xF6, 0x5C, 0xA1, 0xFA, 0x8C,
343 0xB2, 0x37, 0xD1, 0xD0, 0xDB, 0x9E, 0x8A, 0x3A, 0xB8, 0x50, 0x82, 0xAE, 0x7F, 0x40,
344 0x94, 0x85, 0x8A, 0xE7, 0x5E, 0x8B, 0x5B, 0x96, 0x89, 0x00, 0x09, 0x00, 0x00, 0xFE,
345 0x8A, 0x52, 0x52, 0x89, 0xE4, 0x40, 0x9D, 0x40, 0x01, 0x91, 0x2B, 0x61, 0xE8, 0xAC,
346 0x00, 0x4D, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1,
347 0x05, 0x00, 0x3F, 0x13, 0xF8, 0x00, 0x18, 0x00, 0x29, 0xE3, 0x77, 0xF4, 0x00, 0x0F,
348 0xCA, 0xB2, 0x2F, 0x30, 0xB6, 0xFF, 0x2A, 0xC4, 0xAD, 0xC3, 0x21, 0xF7, 0x9D, 0xC3,
349 0x98, 0xBF, 0xAE, 0xEC, 0xA2, 0xBE, 0x94, 0xAA, 0x86, 0x66, 0xC2, 0xFA, 0xFD, 0x96,
350 0x1C, 0x44, 0x5F, 0x2B, 0x80, 0x0B, 0x00, 0x00, 0xFE, 0x8A, 0x56, 0x87, 0x37, 0x56,
351 0xB7, 0xBB, 0x62, 0x04, 0x30, 0x3B, 0x91, 0x08, 0x68, 0xE6, 0x64, 0x06, 0xF9, 0x72,
352 0xC1, 0x3B, 0x0D, 0x25, 0x72, 0xA0, 0x51, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0xD1, 0x05, 0x00, 0x29, 0x13, 0xF8, 0x00, 0x18, 0x00, 0x27,
354 0x73, 0xA7, 0xF4, 0x00, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xD3, 0x26,
355 0x20, 0x6D, 0xF9, 0x61, 0x5D, 0x1C, 0x03, 0x95, 0x51, 0xEE, 0x51, 0x6A, 0x4C, 0x1E,
356 0x24, 0xF5, 0x42, 0x3A, 0x7F, 0xFE, 0x36, 0x46, 0x71, 0xC3, 0x10, 0x0E, 0x00, 0x00,
357 0xFE, 0x8A, 0x59, 0xD1, 0x1F, 0xF8, 0xD6, 0xDE, 0xD0, 0x66, 0xA7, 0x47, 0x2A, 0x00,
358 0x34, 0x35, 0x7F, 0xA3, 0x78, 0x20, 0x2B, 0x64, 0xFB, 0xB7, 0x95, 0xCC, 0x8B, 0xE8,
359 0x40, 0x5B, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
360 0x06, 0x00, 0x3D, 0x13, 0xF8, 0x00, 0x18, 0x43, 0x70, 0x05, 0xCB, 0x85, 0x5E, 0x50,
361 0x02, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC6, 0xFE, 0xB3, 0xD5, 0x73, 0x8E, 0xC1,
362 0x76, 0xD6, 0x60, 0xAD, 0x50, 0x60, 0xBC, 0xB5, 0x76, 0x2C, 0x25, 0x64, 0x9B, 0xA4,
363 0xDB, 0xC0, 0x10, 0x3A, 0x44, 0x13, 0x79, 0x47, 0x89, 0xE8, 0x10, 0x00, 0x00, 0xFE,
364 0x8A, 0xE9, 0xB8, 0x95, 0xED, 0x5C, 0xB6, 0x6B, 0x0C, 0x01, 0x58, 0xE4, 0xA9, 0xD4,
365 0x00, 0xA1, 0x27, 0x30, 0x2F, 0x70, 0xDF, 0x8E, 0xB7, 0xEC, 0x61, 0x42, 0x52, 0x47,
366 0xA6, 0x29, 0xEC, 0xE7, 0xE0, 0x00,
367 ];
368
369 let cursor = Cursor::new(data);
370 let mut ivf = Ivf::new(cursor).unwrap();
371
372 assert_eq!(ivf.width(), 176);
373 assert_eq!(ivf.height(), 144);
374 assert_eq!(ivf.frame_rate_rate(), 30000);
375 assert_eq!(ivf.frame_rate_scale(), 1000);
376 assert_eq!(ivf.frame_count(), 29);
377
378 let mut first = true;
379
380 let mut count = 0;
381 while let Some(frame) = ivf.read_frame().unwrap() {
382 if first {
383 assert_eq!(frame.timestamp, 0);
384 first = false;
385 } else {
386 assert_ne!(frame.timestamp, 0);
387 }
388
389 assert_ne!(frame.packet.len(), 0);
390 count += 1;
391 }
392
393 assert_eq!(count, 29);
394 }
395}