mp4_atom/moov/trak/mdia/
mdhd.rs

1use crate::*;
2
3ext! {
4    name: Mdhd,
5    versions: [0, 1],
6    flags: {}
7}
8
9#[derive(Debug, Clone, PartialEq, Eq, Default)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Mdhd {
12    pub creation_time: u64,
13    pub modification_time: u64,
14    pub timescale: u32,
15    pub duration: u64,
16    pub language: String,
17}
18
19impl AtomExt for Mdhd {
20    type Ext = MdhdExt;
21
22    const KIND_EXT: FourCC = FourCC::new(b"mdhd");
23
24    fn decode_body_ext<B: Buf>(buf: &mut B, ext: MdhdExt) -> Result<Self> {
25        let (creation_time, modification_time, timescale, duration) = match ext.version {
26            MdhdVersion::V1 => (
27                u64::decode(buf)?,
28                u64::decode(buf)?,
29                u32::decode(buf)?,
30                u64::decode(buf)?,
31            ),
32            MdhdVersion::V0 => (
33                u32::decode(buf)? as u64,
34                u32::decode(buf)? as u64,
35                u32::decode(buf)?,
36                u32::decode(buf)? as u64,
37            ),
38        };
39
40        let language_code = u16::decode(buf)?;
41        let language = language_string(language_code);
42
43        u16::decode(buf)?; // pre-defined
44
45        Ok(Mdhd {
46            creation_time,
47            modification_time,
48            timescale,
49            duration,
50            language,
51        })
52    }
53
54    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<MdhdExt> {
55        self.creation_time.encode(buf)?;
56        self.modification_time.encode(buf)?;
57        self.timescale.encode(buf)?;
58        self.duration.encode(buf)?;
59
60        let language_code = language_code(&self.language);
61        (language_code).encode(buf)?;
62        0u16.encode(buf)?; // pre-defined
63
64        Ok(MdhdVersion::V1.into())
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn test_mdhd32() {
74        let expected = Mdhd {
75            creation_time: 100,
76            modification_time: 200,
77            timescale: 48000,
78            duration: 30439936,
79            language: String::from("und"),
80        };
81        let mut buf = Vec::new();
82        expected.encode(&mut buf).unwrap();
83
84        let mut buf = buf.as_ref();
85        let decoded = Mdhd::decode(&mut buf).unwrap();
86        assert_eq!(decoded, expected);
87    }
88
89    #[test]
90    fn test_mdhd64() {
91        let expected = Mdhd {
92            creation_time: 100,
93            modification_time: 200,
94            timescale: 48000,
95            duration: 30439936,
96            language: String::from("eng"),
97        };
98        let mut buf = Vec::new();
99        expected.encode(&mut buf).unwrap();
100
101        let mut buf = buf.as_ref();
102        let decoded = Mdhd::decode(&mut buf).unwrap();
103        assert_eq!(decoded, expected);
104    }
105}