Skip to main content

mp4_atom/moov/trak/mdia/minf/stbl/stsd/
metx.rs

1use crate::*;
2
3/// XMLMetaDataSampleEntry ('metx'), used for XML-based timed metadata tracks.
4///
5/// See ISO/IEC 14496-12 Section 12.3.3.2.
6#[derive(Debug, Clone, PartialEq, Eq)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct Metx {
9    pub metadata: MetaData,
10    pub content_encoding: String,
11    pub namespace: String,
12    pub schema_location: String,
13    pub btrt: Option<Btrt>,
14}
15
16impl Atom for Metx {
17    const KIND: FourCC = FourCC::new(b"metx");
18
19    fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
20        let metadata = MetaData::decode(buf)?;
21
22        let content_encoding = String::decode(buf)?;
23        let namespace = String::decode(buf)?;
24        let schema_location = String::decode(buf)?;
25
26        let mut btrt = None;
27        while let Some(atom) = Any::decode_maybe(buf)? {
28            match atom {
29                Any::Btrt(atom) => btrt = atom.into(),
30                unknown => Self::decode_unknown(&unknown)?,
31            }
32        }
33        skip_trailing_padding(buf);
34
35        Ok(Self {
36            metadata,
37            content_encoding,
38            namespace,
39            schema_location,
40            btrt,
41        })
42    }
43
44    fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
45        self.metadata.encode(buf)?;
46
47        self.content_encoding.as_str().encode(buf)?;
48        self.namespace.as_str().encode(buf)?;
49        self.schema_location.as_str().encode(buf)?;
50        self.btrt.encode(buf)?;
51        Ok(())
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_metx_roundtrip() {
61        let metx = Metx {
62            metadata: MetaData {
63                data_reference_index: 1,
64            },
65            content_encoding: "".into(),
66            namespace: "urn:example:namespace".into(),
67            schema_location: "https://example.com/schema.xsd".into(),
68            btrt: Some(Btrt {
69                buffer_size_db: 1,
70                max_bitrate: 2000,
71                avg_bitrate: 400,
72            }),
73        };
74
75        let mut buf = Vec::new();
76        metx.encode(&mut buf).unwrap();
77
78        let decoded = Metx::decode(&mut buf.as_slice()).expect("failed to decode metx");
79        assert_eq!(decoded, metx);
80    }
81
82    #[test]
83    fn test_metx_roundtrip_no_schema_location() {
84        let metx = Metx {
85            metadata: MetaData {
86                data_reference_index: 1,
87            },
88            content_encoding: "".into(),
89            namespace: "https://example.com/ns".into(),
90            schema_location: "".into(),
91            btrt: None,
92        };
93
94        let mut buf = Vec::new();
95        metx.encode(&mut buf).unwrap();
96
97        let decoded = Metx::decode(&mut buf.as_slice()).expect("failed to decode metx");
98        assert_eq!(decoded, metx);
99    }
100}