codec_bitstream/
ivf.rs

1use crate::Codec;
2use bitstream_io::{ByteRead, ByteReader, LittleEndian};
3use std::io;
4use std::iter::repeat;
5
6#[derive(Debug, Clone)]
7pub struct Header {
8    pub fourcc: [u8; 4],
9    pub w: u16,
10    pub h: u16,
11    pub timebase_num: u32,
12    pub timebase_den: u32,
13    pub frames: u32,
14}
15
16impl Header {
17    pub fn codec(&self) -> Option<Codec> {
18        Codec::from_fourcc(self.fourcc)
19    }
20}
21
22pub fn read_header(r: impl io::Read) -> io::Result<(Header, usize)> {
23    let mut br = ByteReader::endian(r, LittleEndian);
24
25    let mut signature = [0u8; 4];
26    br.read_bytes(&mut signature)?;
27
28    if &signature != b"DKIF" {
29        return Err(io::ErrorKind::InvalidData.into());
30    }
31
32    let _version: u16 = br.read()?;
33    let length: u16 = br.read()?;
34    let mut fourcc = [0u8; 4];
35    br.read_bytes(&mut fourcc)?;
36
37    let w: u16 = br.read()?;
38    let h: u16 = br.read()?;
39
40    let timebase_den: u32 = br.read()?;
41    let timebase_num: u32 = br.read()?;
42
43    let frames: u32 = br.read()?;
44    let _unused: u32 = br.read()?;
45
46    Ok((
47        Header {
48            fourcc,
49            w,
50            h,
51            timebase_num,
52            timebase_den,
53            frames,
54        },
55        length as usize,
56    ))
57}
58
59/// Read a packet in `buf` and returns the packet presentation timestamp.
60pub fn read_packet(r: impl io::Read, buf: &mut Vec<u8>) -> io::Result<u64> {
61    let mut br = ByteReader::endian(r, LittleEndian);
62
63    let len: u32 = br.read()?;
64    let pts: u64 = br.read()?;
65    // buf.clear();
66    buf.reserve(len as usize);
67    if buf.len() < len as usize {
68        buf.extend(repeat(0).take(len as usize - buf.len()));
69    } else if buf.len() > len as usize {
70        buf.truncate(len as usize);
71    }
72
73    br.read_bytes(buf)?;
74
75    Ok(pts)
76}