mp4_atom/moov/trak/edts/
elst.rs1use 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}