Skip to main content

mp4_atom/moov/trak/mdia/minf/
vmhd.rs

1use crate::*;
2
3#[derive(Default)]
4pub(crate) struct VmhdExt;
5
6impl Ext for VmhdExt {
7    fn encode(&self) -> Result<u32> {
8        // ISO/IEC 14496-12 requires vmhd to use version 0 and flags 1.
9        Ok(1)
10    }
11
12    fn decode(_: u32) -> Result<Self> {
13        Ok(Self)
14    }
15}
16
17#[derive(Debug, Clone, PartialEq, Eq, Default)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub struct Vmhd {
20    pub graphics_mode: u16,
21    pub op_color: RgbColor,
22}
23
24#[derive(Debug, Clone, PartialEq, Eq, Default)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26pub struct RgbColor {
27    pub red: u16,
28    pub green: u16,
29    pub blue: u16,
30}
31
32impl AtomExt for Vmhd {
33    type Ext = VmhdExt;
34
35    const KIND_EXT: FourCC = FourCC::new(b"vmhd");
36
37    fn decode_body_ext<B: Buf>(buf: &mut B, _ext: VmhdExt) -> Result<Self> {
38        let graphics_mode = u16::decode(buf)?;
39        let op_color = RgbColor {
40            red: u16::decode(buf)?,
41            green: u16::decode(buf)?,
42            blue: u16::decode(buf)?,
43        };
44
45        Ok(Vmhd {
46            graphics_mode,
47            op_color,
48        })
49    }
50
51    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<VmhdExt> {
52        self.graphics_mode.encode(buf)?;
53        self.op_color.red.encode(buf)?;
54        self.op_color.green.encode(buf)?;
55        self.op_color.blue.encode(buf)?;
56
57        Ok(VmhdExt)
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    const ENCODED_VMHD: &[u8] = &[
66        0x00, 0x00, 0x00, 0x14, b'v', b'm', b'h', b'd', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
67        0x00, 0x00, 0x00, 0x00, 0x00,
68    ];
69
70    #[test]
71    fn test_vmhd_encode() {
72        let expected = Vmhd {
73            graphics_mode: 0,
74            op_color: RgbColor {
75                red: 0,
76                green: 0,
77                blue: 0,
78            },
79        };
80        let mut buf = Vec::new();
81        expected.encode(&mut buf).unwrap();
82
83        assert_eq!(buf.as_slice(), ENCODED_VMHD);
84    }
85
86    #[test]
87    fn test_vmhd_decode() {
88        let mut buf = std::io::Cursor::new(ENCODED_VMHD);
89        let decoded = Vmhd::decode(&mut buf).unwrap();
90
91        let expected = Vmhd {
92            graphics_mode: 0,
93            op_color: RgbColor {
94                red: 0,
95                green: 0,
96                blue: 0,
97            },
98        };
99        assert_eq!(decoded, expected);
100    }
101}