scuffle_mp4/boxes/
traits.rs

1use std::io;
2
3use byteorder::WriteBytesExt;
4use bytes::Bytes;
5
6use super::header::BoxHeader;
7
8pub trait BoxType {
9    const NAME: [u8; 4];
10
11    /// Parse a box from a byte stream. The basic header is already parsed.
12    fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self>
13    where
14        Self: Sized;
15
16    /// The size of the box without the basic header.
17    fn primitive_size(&self) -> u64;
18
19    /// Write the box to a byte stream. The basic header is already written.
20    fn primitive_mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()>;
21
22    /// Write the box to a byte stream.
23    fn mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
24        self.validate()?;
25
26        let size = self.size();
27        if size > u32::MAX as u64 {
28            writer.write_u32::<byteorder::BigEndian>(1)?;
29        } else {
30            writer.write_u32::<byteorder::BigEndian>(size as u32)?;
31        }
32
33        writer.write_all(&Self::NAME)?;
34
35        if size > u32::MAX as u64 {
36            writer.write_u64::<byteorder::BigEndian>(size)?;
37        }
38
39        self.primitive_mux(writer)
40    }
41
42    /// Size of the box including the basic header.
43    fn size(&self) -> u64 {
44        let primitive_size = self.primitive_size() + 8;
45
46        if primitive_size > u32::MAX as u64 {
47            primitive_size + 8
48        } else {
49            primitive_size
50        }
51    }
52
53    /// Validate the box.
54    fn validate(&self) -> io::Result<()> {
55        Ok(())
56    }
57}