Skip to main content

mkv_parser_kit/
ebml_types.rs

1// Copyright (C) The Strand-Braid Authors
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4#[derive(Debug)]
5pub enum BoxData {
6    String(String),
7    // uses unicode string for storage as convenience. data are ASCII.
8    AsciiString(String),
9    DateTime(chrono::DateTime<chrono::Utc>),
10    UnsignedInt(u32),
11    Float(f32),
12    Float64(f64),
13    SimpleBlockData(BlockData),
14    // uses unicode string for storage as convenience. data are [u8;4] ASCII.
15    UncompressedFourCC(String),
16}
17
18/// A block of frame data. Typically corresponds to one frame.
19#[derive(Debug)]
20pub struct BlockData {
21    /// the start position of the data.
22    pub start: u64,
23    /// the size of the data.
24    pub size: u64,
25    pub is_keyframe: bool,
26    pub is_invisible: bool,
27    pub is_discardable: bool,
28    pub track_number: u64,
29    pub timestamp: i16,
30}
31
32pub struct EbmlElement {
33    /// the ID of the EBML element
34    pub(crate) tag: Tag,
35    /// the position of the start of the EBML element
36    pub(crate) position: u64,
37    /// the full size (header + data) of the EBML element
38    pub(crate) full_size: u64,
39    /// the data size of the EBML element
40    pub(crate) data_size: u64,
41    /// for master blocks, the children elements
42    pub(crate) children: Vec<EbmlElement>,
43    pub(crate) box_data: Option<BoxData>,
44}
45
46impl EbmlElement {
47    #[inline]
48    pub fn tag(&self) -> Tag {
49        self.tag
50    }
51    #[inline]
52    pub fn position(&self) -> u64 {
53        self.position
54    }
55    #[inline]
56    pub fn full_size(&self) -> u64 {
57        self.full_size
58    }
59    #[inline]
60    pub fn data_size(&self) -> u64 {
61        self.data_size
62    }
63    #[inline]
64    pub fn box_data(&self) -> Option<&BoxData> {
65        self.box_data.as_ref()
66    }
67    #[inline]
68    pub fn children(&self) -> &[EbmlElement] {
69        &self.children
70    }
71}
72
73#[derive(PartialEq, Eq, Clone, Copy)]
74pub struct Hex32(u32);
75
76impl std::fmt::Debug for Hex32 {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        write!(f, "0x{:x}", self.0)
79    }
80}
81
82macro_rules! impl_tags {
83    ( $( ($name:ident, $val:expr_2021, $dtype:expr_2021) ),* ) => {
84        #[derive(Debug, PartialEq, Eq, Clone, Copy)]
85        pub enum Tag {
86            $(
87                $name,
88            )*
89            Other(Hex32),
90        }
91
92        impl Tag {
93            pub fn dtype(&self) -> u8 {
94                use Tag::*;
95                match self {
96                    $(
97                        $name => $dtype,
98                    )*
99                    Other(_) => b'b',
100                }
101            }
102        }
103
104        impl From<u32> for Tag {
105            fn from(id: u32) -> Tag {
106                use Tag::*;
107                match id {
108                    $(
109                        $val => $name,
110                    )*
111                    id => Other(Hex32(id)),
112                }
113            }
114        }
115
116
117    };
118}
119
120// See https://www.matroska.org/technical/elements.html
121// https://github.com/ietf-wg-cellar/matroska-specification/blob/master/ebml_matroska.xml
122
123impl_tags!(
124    // These are not in Matroska spec (but in EBML spec?)
125    (EBML, 0x1a45_dfa3, b'm'),
126    (DocType, 0x4282, b'b'),
127    (DocTypeReadVersion, 0x4285, b'b'),
128    (Version, 0x4286, b'b'),
129    (DocTypeVersion, 0x4287, b'b'),
130    (ReadVersion, 0x42F7, b'b'),
131    // These are in matroska spec
132    (EBMLMaxIDLength, 0x42F2, b'u'),
133    (EBMLMaxSizeLength, 0x42F3, b'u'),
134    // Cues
135    (Cues, 0x1c53_bb6b, b'm'),
136    (CuePoint, 0xbb, b'b'),
137    // Top-level singletons
138    (Void, 0xEC, b'b'),
139    (Info, 0x1549_A966, b'm'),
140    // Segments
141    (Segment, 0x1853_8067, b'm'),
142    (SeekHead, 0x114D_9B74, b'b'),
143    (Seek, 0x4DBB, b'b'),
144    (SeekID, 0x53AB, b'b'),
145    (SeekPosition, 0x53AC, b'b'),
146    (TimestampScale, 0x2ad7b1, b'u'),
147    (Duration, 0x4489, b'f'),
148    (DateUTC, 0x4461, b'd'),
149    (Title, 0x7BA9, b'8'),
150    (MuxingApp, 0x4D80, b'8'),
151    (WritingApp, 0x5741, b'8'),
152    // Tracks
153    (Tracks, 0x1654_ae6b, b'm'),
154    (TrackEntry, 0xAE, b'm'),
155    (TrackNumber, 0xD7, b'b'),
156    (TrackUID, 0x73c5, b'b'),
157    (TrackType, 0x83, b'b'),
158    (CodecID, 0x86, b's'),
159    (Video, 0xe0, b'm'),
160    (PixelWidth, 0xB0, b'u'),
161    (PixelHeight, 0xBA, b'u'),
162    (UncompressedFourCC, 0x2eb524, b'b'),
163    (GammaValue, 0x2fb523, b'f'),
164    // Cluster
165    (Cluster, 0x1F43_B675, b'm'),
166    (Timestamp, 0xE7, b'u'),
167    (SimpleBlock, 0xA3, b'b')
168);