Skip to main content

mp4/mp4box/
mfhd.rs

1use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
2use serde::Serialize;
3use std::io::{Read, Seek, Write};
4
5use crate::mp4box::*;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
8pub struct MfhdBox {
9    pub version: u8,
10    pub flags: u32,
11    pub sequence_number: u32,
12}
13
14impl Default for MfhdBox {
15    fn default() -> Self {
16        MfhdBox {
17            version: 0,
18            flags: 0,
19            sequence_number: 1,
20        }
21    }
22}
23
24impl MfhdBox {
25    pub fn get_type(&self) -> BoxType {
26        BoxType::MfhdBox
27    }
28
29    pub fn get_size(&self) -> u64 {
30        HEADER_SIZE + HEADER_EXT_SIZE + 4
31    }
32}
33
34impl Mp4Box for MfhdBox {
35    fn box_type(&self) -> BoxType {
36        self.get_type()
37    }
38
39    fn box_size(&self) -> u64 {
40        self.get_size()
41    }
42
43    fn to_json(&self) -> Result<String> {
44        Ok(serde_json::to_string(&self).unwrap())
45    }
46
47    fn summary(&self) -> Result<String> {
48        let s = format!("sequence_number={}", self.sequence_number);
49        Ok(s)
50    }
51}
52
53impl<R: Read + Seek> ReadBox<&mut R> for MfhdBox {
54    fn read_box(reader: &mut R, size: u64) -> Result<Self> {
55        let start = box_start(reader)?;
56
57        let (version, flags) = read_box_header_ext(reader)?;
58        let sequence_number = reader.read_u32::<BigEndian>()?;
59
60        skip_bytes_to(reader, start + size)?;
61
62        Ok(MfhdBox {
63            version,
64            flags,
65            sequence_number,
66        })
67    }
68}
69
70impl<W: Write> WriteBox<&mut W> for MfhdBox {
71    fn write_box(&self, writer: &mut W) -> Result<u64> {
72        let size = self.box_size();
73        BoxHeader::new(self.box_type(), size).write(writer)?;
74
75        write_box_header_ext(writer, self.version, self.flags)?;
76        writer.write_u32::<BigEndian>(self.sequence_number)?;
77
78        Ok(size)
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85    use crate::mp4box::BoxHeader;
86    use std::io::Cursor;
87
88    #[test]
89    fn test_mfhd() {
90        let src_box = MfhdBox {
91            version: 0,
92            flags: 0,
93            sequence_number: 1,
94        };
95        let mut buf = Vec::new();
96        src_box.write_box(&mut buf).unwrap();
97        assert_eq!(buf.len(), src_box.box_size() as usize);
98
99        let mut reader = Cursor::new(&buf);
100        let header = BoxHeader::read(&mut reader).unwrap();
101        assert_eq!(header.name, BoxType::MfhdBox);
102        assert_eq!(src_box.box_size(), header.size);
103
104        let dst_box = MfhdBox::read_box(&mut reader, header.size).unwrap();
105        assert_eq!(src_box, dst_box);
106    }
107}