mp4_atom/moov/trak/edts/
elst.rs

1use crate::*;
2
3ext! {
4    name: Elst,
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 Elst {
12    pub entries: Vec<ElstEntry>,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Default)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct ElstEntry {
18    pub segment_duration: u64,
19    pub media_time: u64,
20    pub media_rate: u16,
21    pub media_rate_fraction: u16,
22}
23
24impl AtomExt for Elst {
25    type Ext = ElstExt;
26
27    const KIND_EXT: FourCC = FourCC::new(b"elst");
28
29    fn decode_body_ext<B: Buf>(buf: &mut B, ext: ElstExt) -> Result<Self> {
30        let entry_count = u32::decode(buf)?;
31
32        let mut entries = Vec::new();
33        for _ in 0..entry_count {
34            let (segment_duration, media_time) = match ext.version {
35                ElstVersion::V1 => (u64::decode(buf)?, u64::decode(buf)?),
36                ElstVersion::V0 => (u32::decode(buf)? as u64, u32::decode(buf)? as u64),
37            };
38
39            let entry = ElstEntry {
40                segment_duration,
41                media_time,
42                media_rate: u16::decode(buf)?,
43                media_rate_fraction: u16::decode(buf)?,
44            };
45            entries.push(entry);
46        }
47
48        Ok(Elst { entries })
49    }
50
51    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<ElstExt> {
52        (self.entries.len() as u32).encode(buf)?;
53
54        for entry in self.entries.iter() {
55            entry.segment_duration.encode(buf)?;
56            entry.media_time.encode(buf)?;
57            entry.media_rate.encode(buf)?;
58            entry.media_rate_fraction.encode(buf)?;
59        }
60
61        Ok(ElstVersion::V1.into())
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_elst32() {
71        let expected = Elst {
72            entries: vec![ElstEntry {
73                segment_duration: 634634,
74                media_time: 0,
75                media_rate: 1,
76                media_rate_fraction: 0,
77            }],
78        };
79        let mut buf = Vec::new();
80        expected.encode(&mut buf).unwrap();
81
82        let mut buf = buf.as_ref();
83        let decoded = Elst::decode(&mut buf).unwrap();
84        assert_eq!(decoded, expected);
85    }
86
87    #[test]
88    fn test_elst64() {
89        let expected = Elst {
90            entries: vec![ElstEntry {
91                segment_duration: 634634,
92                media_time: 0,
93                media_rate: 1,
94                media_rate_fraction: 0,
95            }],
96        };
97        let mut buf = Vec::new();
98        expected.encode(&mut buf).unwrap();
99
100        let mut buf = buf.as_ref();
101        let decoded = Elst::decode(&mut buf).unwrap();
102        assert_eq!(decoded, expected);
103    }
104}