1use crate::*;
2
3ext! {
4 name: Emsg,
5 versions: [0, 1],
6 flags: {}
7}
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum EmsgTimestamp {
12 Relative(u32),
13 Absolute(u64),
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub struct Emsg {
19 pub timescale: u32,
20 pub presentation_time: EmsgTimestamp,
21 pub event_duration: u32,
22 pub id: u32,
23 pub scheme_id_uri: String,
24 pub value: String,
25 pub message_data: Vec<u8>,
26}
27
28impl AtomExt for Emsg {
29 const KIND_EXT: FourCC = FourCC::new(b"emsg");
30
31 type Ext = EmsgExt;
32
33 fn decode_body_ext<B: Buf>(buf: &mut B, ext: EmsgExt) -> Result<Self> {
34 Ok(match ext.version {
35 EmsgVersion::V0 => Emsg {
36 scheme_id_uri: String::decode(buf)?,
37 value: String::decode(buf)?,
38 timescale: u32::decode(buf)?,
39 presentation_time: EmsgTimestamp::Relative(u32::decode(buf)?),
40 event_duration: u32::decode(buf)?,
41 id: u32::decode(buf)?,
42 message_data: Vec::decode(buf)?,
43 },
44 EmsgVersion::V1 => Emsg {
45 timescale: u32::decode(buf)?,
46 presentation_time: EmsgTimestamp::Absolute(u64::decode(buf)?),
47 event_duration: u32::decode(buf)?,
48 id: u32::decode(buf)?,
49 scheme_id_uri: String::decode(buf)?,
50 value: String::decode(buf)?,
51 message_data: Vec::decode(buf)?,
52 },
53 })
54 }
55
56 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<EmsgExt> {
57 Ok(match self.presentation_time {
58 EmsgTimestamp::Absolute(presentation_time) => {
59 self.timescale.encode(buf)?;
60 presentation_time.encode(buf)?;
61 self.event_duration.encode(buf)?;
62 self.id.encode(buf)?;
63 self.scheme_id_uri.as_str().encode(buf)?;
64 self.value.as_str().encode(buf)?;
65 self.message_data.encode(buf)?;
66
67 EmsgVersion::V1.into()
68 }
69 EmsgTimestamp::Relative(presentation_time) => {
70 self.scheme_id_uri.as_str().encode(buf)?;
71 self.value.as_str().encode(buf)?;
72 self.timescale.encode(buf)?;
73 presentation_time.encode(buf)?;
74 self.event_duration.encode(buf)?;
75 self.id.encode(buf)?;
76 self.message_data.encode(buf)?;
77
78 EmsgVersion::V0.into()
79 }
80 })
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_emsg_version0() {
90 let decoded = Emsg {
91 timescale: 48000,
92 event_duration: 200,
93 presentation_time: EmsgTimestamp::Relative(100),
94 id: 8,
95 scheme_id_uri: String::from("foo"),
96 value: String::from("foo"),
97 message_data: [1, 2, 3].into(),
98 };
99
100 let mut buf = Vec::new();
101 decoded.encode(&mut buf).unwrap();
102
103 let output = Emsg::decode(&mut buf.as_slice()).unwrap();
104 assert_eq!(decoded, output);
105 }
106
107 #[test]
108 fn test_emsg_version1() {
109 let decoded = Emsg {
110 presentation_time: EmsgTimestamp::Absolute(50000),
111 timescale: 48000,
112 event_duration: 200,
113 id: 8,
114 scheme_id_uri: String::from("foo"),
115 value: String::from("foo"),
116 message_data: [3, 2, 1].into(),
117 };
118
119 let mut buf = Vec::new();
120 decoded.encode(&mut buf).unwrap();
121
122 let output = Emsg::decode(&mut buf.as_slice()).unwrap();
123 assert_eq!(decoded, output);
124 }
125}