scuffle_mp4/boxes/types/
vmhd.rs

1use std::io;
2
3use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
4use bytes::Bytes;
5
6use crate::boxes::header::{BoxHeader, FullBoxHeader};
7use crate::boxes::traits::BoxType;
8
9const OP_COLOR_SIZE: usize = 3;
10
11#[derive(Debug, Clone, PartialEq)]
12/// Video Media Header Box
13/// ISO/IEC 14496-12:2022(E) - 12.1.2
14pub struct Vmhd {
15    pub header: FullBoxHeader,
16
17    pub graphics_mode: u16,
18    pub opcolor: [u16; OP_COLOR_SIZE],
19}
20
21impl Default for Vmhd {
22    fn default() -> Self {
23        Self::new()
24    }
25}
26
27impl Vmhd {
28    pub fn new() -> Self {
29        Self {
30            header: FullBoxHeader::new(Self::NAME, 0, 1),
31            graphics_mode: 0,
32            opcolor: [0; OP_COLOR_SIZE],
33        }
34    }
35}
36
37impl BoxType for Vmhd {
38    const NAME: [u8; 4] = *b"vmhd";
39
40    fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self> {
41        let mut reader = io::Cursor::new(data);
42
43        let header = FullBoxHeader::demux(header, &mut reader)?;
44
45        let graphics_mode = reader.read_u16::<BigEndian>()?;
46
47        let mut opcolor = [0; OP_COLOR_SIZE];
48        for v in opcolor.iter_mut() {
49            *v = reader.read_u16::<BigEndian>()?;
50        }
51
52        Ok(Self {
53            header,
54            graphics_mode,
55            opcolor,
56        })
57    }
58
59    fn primitive_size(&self) -> u64 {
60        let size = self.header.size();
61        let size = size + 2; // graphics_mode
62        size + 2 * OP_COLOR_SIZE as u64 // opcolor
63    }
64
65    fn primitive_mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
66        self.header.mux(writer)?;
67
68        writer.write_u16::<BigEndian>(self.graphics_mode)?;
69
70        for i in 0..OP_COLOR_SIZE {
71            writer.write_u16::<BigEndian>(self.opcolor[i])?;
72        }
73
74        Ok(())
75    }
76}