scuffle_mp4/boxes/types/
mehd.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
9#[derive(Debug, Clone, PartialEq)]
10/// Movie Extends Header Box
11/// ISO/IEC 14496-12:2022(E) - 8.8.2
12pub struct Mehd {
13    pub header: FullBoxHeader,
14    pub fragment_duration: u64,
15}
16
17impl BoxType for Mehd {
18    const NAME: [u8; 4] = *b"mehd";
19
20    fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self> {
21        let mut reader = io::Cursor::new(data);
22
23        let header = FullBoxHeader::demux(header, &mut reader)?;
24
25        let fragment_duration = if header.version == 1 {
26            reader.read_u64::<BigEndian>()?
27        } else {
28            reader.read_u32::<BigEndian>()? as u64
29        };
30
31        Ok(Self {
32            header,
33            fragment_duration,
34        })
35    }
36
37    fn primitive_size(&self) -> u64 {
38        self.header.size()
39            + if self.header.version == 1 {
40                8 // fragment_duration
41            } else {
42                4 // fragment_duration
43            }
44    }
45
46    fn primitive_mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
47        self.header.mux(writer)?;
48
49        if self.header.version == 1 {
50            writer.write_u64::<BigEndian>(self.fragment_duration)?;
51        } else {
52            writer.write_u32::<BigEndian>(self.fragment_duration as u32)?;
53        }
54
55        Ok(())
56    }
57
58    fn validate(&self) -> io::Result<()> {
59        if self.header.version > 1 {
60            return Err(io::Error::new(io::ErrorKind::InvalidData, "mehd version must be 0 or 1"));
61        }
62
63        if self.header.version == 0 && self.fragment_duration > u32::MAX as u64 {
64            return Err(io::Error::new(
65                io::ErrorKind::InvalidData,
66                "mehd fragment_duration must be less than 2^32",
67            ));
68        }
69
70        Ok(())
71    }
72}