vp9_parser/ivf/
mod.rs

1//! IVF container parsing.
2
3use 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/// IVF is a simple container format for raw VP9 data.
15#[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    /// Creates a new IVF using the given reader.
26    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    /// The initial width of the video.
71    pub fn width(&self) -> u16 {
72        self.header.width
73    }
74
75    /// The initial height of the video.
76    pub fn height(&self) -> u16 {
77        self.header.height
78    }
79
80    /// The framerate of the video (frame_rate_rate * frame_rate_scale).
81    ///
82    /// Example:
83    /// 24 fps with a scale of 1000 -> 24000
84    pub fn frame_rate_rate(&self) -> u32 {
85        self.header.frame_rate_rate
86    }
87
88    /// Divider of the seconds.
89    pub fn frame_rate_scale(&self) -> u32 {
90        self.header.frame_rate_scale
91    }
92
93    /// Number of frames stored inside the IVF. A frame can contain a frame or a super frame.
94    pub fn frame_count(&self) -> u32 {
95        self.header.frame_count
96    }
97
98    /// Reads the next frame inside the IVF. Returns `None` if the end of the file has been reached.
99    ///
100    /// A frame contains a VP9 bitstream packet which can contain either a normal frame or a super frame.
101    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/// The IVF Header.
126#[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/// Frame inside an IVF.
141///
142/// A frame can contain a VP9 bitstream packet which contains either a frame or a super frame.
143#[derive(Debug, Clone)]
144pub struct Frame {
145    /// The timestamp of the frame.
146    pub timestamp: u64,
147    /// The data packet of the frame.
148    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}