mpeg2ts_reader/descriptor/mod.rs
1//! Descriptors provide metadata about an element of a Transport Stream.
2//!
3//! For example, a descriptor may be used to specify the language of an audio track. Use of
4//! specific descriptors is often not mandatory (many streams do not describe the language of their
5//! audio).
6//!
7//! The syntax
8//! of specific PSI tables often allows descriptors to be attached to the table itself, or to
9//! entries within the table.
10//!
11//! # Extensions
12//!
13//! Descriptors are a point of extension, with a range of descriptor types defined by the core
14//! standard, and further descriptor types defined by standards based upon transport streams. In
15//! order to support this extension, while avoiding allocations (a la `dyn Trait`),
16//! descriptor-related types and methods within this crate have a type-parameter so that calling
17//! code which wants to use externally-defined descriptors can supply a type which supports them.
18//!
19//! So for example code using [`PmtSection`](..//demultiplex/struct.PmtSection.html) will need to
20//! specify the `Descriptor` implementation to be produced,
21//!
22//! ```
23//! # use mpeg2ts_reader::psi::pmt::PmtSection;
24//! # use mpeg2ts_reader::descriptor::CoreDescriptors;
25//! # let data = [0; 4];
26//! let pmt = PmtSection::from_bytes(&data).unwrap();
27//! // type parameter to descriptors() is inferred from the use of CoreDescriptors below
28//! for d in pmt.descriptors() {
29//! if let Ok(CoreDescriptors::Registration(reg)) = d {
30//! println!("registration_descriptor {:?}", reg.format_identifier());
31//! }
32//! }
33//! ```
34
35pub mod avcvideo;
36pub mod iso_639_language;
37pub mod max_bitrate;
38pub mod registration;
39
40use self::avcvideo::AvcVideoDescriptor;
41use self::iso_639_language::Iso639LanguageDescriptor;
42use self::max_bitrate::MaximumBitrateDescriptor;
43use self::registration::RegistrationDescriptor;
44use std::fmt;
45use std::marker;
46
47/// Trait allowing users of this trait to supply their own implementation of descriptor parsing.
48///
49/// The default implementation provided by this crate is
50/// [`CoreDescriptors`](enum.CoreDescriptors.html), which will only provide support for descriptor
51/// types directly defined by _ISO/IEC 13818-1_. To support descriptors from other standards,
52/// an alternative implementation of this trait may be passed as a type parameter to methods such as
53/// [`PmtSection::descriptors()`](..//demultiplex/struct.PmtSection.html#method.descriptors).
54///
55/// The [`descriptor_enum!{}`](../macro.descriptor_enum.html) macro can be used to help create
56/// implementations of this trait.
57pub trait Descriptor<'buf>: Sized {
58 /// Create an object that that can wrap and parse the type of descriptor at the start of the
59 /// given slice.
60 fn from_bytes(buf: &'buf [u8]) -> Result<Self, DescriptorError>;
61}
62
63/// Builds an enum to encapsulate all possible implementations of
64/// [`Descriptor`](descriptor/trait.Descriptor.html) that you want to be able to handle in your
65/// application.
66///
67/// The list of variants is supplied in the macro body together with the 'tag' values of each
68/// option. The macro will generate an implementation of `descriptor::Descriptor` whose
69/// `from_bytes()` function will return the variant for the tag value found within the input
70/// buffer.
71///
72/// ```
73/// # use mpeg2ts_reader::*;
74/// use mpeg2ts_reader::descriptor::*;
75///
76/// struct MySpecialDescriptor<'buf> {
77/// # buf: &'buf [u8],
78/// // ...
79/// };
80/// impl<'buf> MySpecialDescriptor<'buf> {
81/// pub fn new(tag: u8, payload: &'buf [u8]) -> Result<Self, DescriptorError> {
82/// # Ok(MySpecialDescriptor { buf: payload })
83/// // ...
84/// }
85/// }
86///
87/// descriptor_enum! {
88/// // you could #[derive(Debug)] here if you wanted
89/// MyOwnDescriptors {
90/// /// descriptor tag values `0`, `1` and `57` to `62` inclusive are marked as reserved
91/// /// by _ISO/IEC 13818-1_. If any of these tag values are found,
92/// /// MyOwnDescriptors::from_bytes() will return MyOwnDescriptors::Reserved.
93/// Reserved 0|1|57..=62 => UnknownDescriptor,
94/// Other 2..=56|63..=254 => UnknownDescriptor,
95/// /// When MyOwnDescriptors::from_bytes() finds the value 255, it will return the
96/// /// MyOwnDescriptors::MySpecialPrivate variant, which will in turn wrap an instance
97/// /// of MySpecialDescriptor.
98/// MySpecialPrivate 255 => MySpecialDescriptor,
99/// }
100/// }
101/// ```
102#[macro_export]
103macro_rules! descriptor_enum {
104 (
105 $(#[$outer:meta])*
106 $name:ident {
107 $(
108 $(#[$inner:ident $($args:tt)*])*
109 $case_name:ident $($tags:pat_param)|* => $t:ident
110 ),*,
111 }
112 ) => {
113 $(#[$outer])*
114 pub enum $name<'buf> {
115 $(
116 $(#[$inner $($args)*])*
117 $case_name($t<'buf>),
118 )*
119 }
120 impl<'buf> $crate::descriptor::Descriptor<'buf> for $name<'buf> {
121 fn from_bytes(buf: &'buf[u8]) -> Result<Self, $crate::descriptor::DescriptorError> {
122 if buf.len() < 2 {
123 return Err($crate::descriptor::DescriptorError::BufferTooShort{ buflen: buf.len() })
124 }
125 let tag = buf[0];
126 let len = buf[1] as usize;
127 let tag_end = len + 2;
128 if tag_end > buf.len() {
129 return Err($crate::descriptor::DescriptorError::TagTooLongForBuffer{ taglen: len, buflen: buf.len() })
130 }
131 let payload = &buf[2..tag_end];
132 match tag {
133 $( $( $tags )|* => Ok($name::$case_name($t::new(tag, payload)?)), )*
134 }
135 }
136 }
137 }
138}
139
140/// Catch-all type for when there is no explicit handling for the given descriptor type.
141pub struct UnknownDescriptor<'buf> {
142 /// the descriptor's identifying 'tag' value; different types of descriptors are assigned
143 /// different tag values
144 pub tag: u8,
145 /// the descriptor's payload bytes
146 pub payload: &'buf [u8],
147}
148impl<'buf> UnknownDescriptor<'buf> {
149 /// Constructor, in the form required for use with the
150 /// [`descriptor_enum!{}`](../macro.descriptor_enum.html) macro.
151 pub fn new(tag: u8, payload: &'buf [u8]) -> Result<UnknownDescriptor<'buf>, DescriptorError> {
152 Ok(UnknownDescriptor { tag, payload })
153 }
154}
155impl<'buf> fmt::Debug for UnknownDescriptor<'buf> {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
157 f.debug_struct("UnknownDescriptor")
158 .field("tag", &self.tag)
159 .field("len", &self.payload.len())
160 .finish()
161 }
162}
163
164descriptor_enum! {
165 /// Default implementation of [`Descriptor`](trait.Descriptor.html) covering descriptor types
166 /// from _ISO/IEC 13818-1_.
167 ///
168 /// **NB** coverage of the range of descriptors from the spec with descriptor-type-specific
169 /// Rust types is currently incomplete, with those variants currently containing
170 /// `UnknownDescriptor` needing to be changed to have type-specific implementations in some
171 /// future release of this crate.
172 #[derive(Debug)]
173 CoreDescriptors {
174 /// descriptor tag values `0`, `1` and `57` to `62` inclusive are marked as reserved by _ISO/IEC 13818-1_.
175 Reserved 0|1|57..=62 => UnknownDescriptor,
176 /// The `video_stream_descriptor()` syntax element from _ISO/IEC 13818-1_.
177 VideoStream 2 => UnknownDescriptor,
178 /// The `audio_stream_descriptor()` syntax element from _ISO/IEC 13818-1_.
179 AudioStream 3 => UnknownDescriptor,
180 /// The `hierarchy_descriptor()` syntax element from _ISO/IEC 13818-1_.
181 Hierarchy 4 => UnknownDescriptor,
182 /// The `registration_descriptor()` syntax element from _ISO/IEC 13818-1_.
183 Registration 5 => RegistrationDescriptor,
184 /// The `data_stream_alignment_descriptor()` syntax element from _ISO/IEC 13818-1_.
185 DataStreamAlignment 6 => UnknownDescriptor,
186 /// The `target_background_grid_descriptor()` syntax element from _ISO/IEC 13818-1_.
187 TargetBackgroundGrid 7 => UnknownDescriptor,
188 /// The `video_window_descriptor()` syntax element from _ISO/IEC 13818-1_.
189 VideoWindow 8 => UnknownDescriptor,
190 /// The `CA_descriptor()` syntax element from _ISO/IEC 13818-1_ ("Conditional Access").
191 CA 9 => UnknownDescriptor,
192 /// The `ISO_639_language_descriptor()` syntax element from _ISO/IEC 13818-1_.
193 ISO639Language 10 => Iso639LanguageDescriptor,
194 /// The `system_clock_descriptor()` syntax element from _ISO/IEC 13818-1_.
195 SystemClock 11 => UnknownDescriptor,
196 /// The `multiplex_buffer_utilization_descriptor()` syntax element from _ISO/IEC 13818-1_.
197 MultiplexBufferUtilization 12 => UnknownDescriptor,
198 /// The `copyright_descriptor()` syntax element from _ISO/IEC 13818-1_.
199 Copyright 13 => UnknownDescriptor,
200 /// The `maximum_bitrate_descriptor()` syntax element from _ISO/IEC 13818-1_.
201 MaximumBitrate 14 => MaximumBitrateDescriptor,
202 /// The `private_data_indicator_descriptor()` syntax element from _ISO/IEC 13818-1_.
203 PrivateDataIndicator 15 => UnknownDescriptor,
204 /// The `smoothing_buffer_descriptor()` syntax element from _ISO/IEC 13818-1_.
205 SmoothingBuffer 16 => UnknownDescriptor,
206 /// The `STD_descriptor()` syntax element from _ISO/IEC 13818-1_.
207 STD 17 => UnknownDescriptor,
208 /// The `ibp_descriptor()` syntax element from _ISO/IEC 13818-1_.
209 IBP 18 => UnknownDescriptor,
210 /// descriptor tag values `19` to `26` inclusive are marked as reserved by _ISO IEC 13818-6_ (NB a different standard than the one supported by this crate).
211 IsoIec13818dash6 19..=26 => UnknownDescriptor,
212 /// The `MPEG-4_video_descriptor()` syntax element from _ISO/IEC 13818-1_.
213 MPEG4Video 27 => UnknownDescriptor,
214 /// The `MPEG-4_audio_descriptor()` syntax element from _ISO/IEC 13818-1_.
215 MPEG4Audio 28 => UnknownDescriptor,
216 /// The `IOD_descriptor()` syntax element from _ISO/IEC 13818-1_ ("Initial Object Descriptor").
217 IOD 29 => UnknownDescriptor,
218 /// The `SL_descriptor()` syntax element from _ISO/IEC 13818-1_ ("Synchronization Layer").
219 SL 30 => UnknownDescriptor,
220 /// The `FMC_descriptor()` syntax element from _ISO/IEC 13818-1_ ("FlexMux Channel").
221 FMC 31 => UnknownDescriptor,
222 /// The `External_ES_ID_descriptor()` syntax element from _ISO/IEC 13818-1_.
223 ExternalESID 32 => UnknownDescriptor,
224 /// The `Muxcode_descriptor()` syntax element from _ISO/IEC 13818-1_.
225 MuxCode 33 => UnknownDescriptor,
226 /// The `FmxBufferSize_descriptor()` syntax element from _ISO/IEC 13818-1_ ("FlexMux buffer").
227 FmxBufferSize 34 => UnknownDescriptor,
228 /// The `MultiplexBuffer_descriptor()` syntax element from _ISO/IEC 13818-1_.
229 MultiplexBuffer 35 => UnknownDescriptor,
230 /// The `content_labeling_descriptor()` syntax element from _ISO/IEC 13818-1_.
231 MontentLabeling 36 => UnknownDescriptor,
232 /// The `metadata_pointer_descriptor()` syntax element from _ISO/IEC 13818-1_.
233 MetadataPointer 37 => UnknownDescriptor,
234 /// The `metadata_descriptor()` syntax element from _ISO/IEC 13818-1_.
235 Metadata 38 => UnknownDescriptor,
236 /// The `metadata_STD_descriptor()` syntax element from _ISO/IEC 13818-1_.
237 MetadataStd 39 => UnknownDescriptor,
238 /// The `AVC_video_descriptor()` syntax element from _ISO/IEC 13818-1_.
239 AvcVideo 40 => AvcVideoDescriptor,
240 /// The `IPMP_descriptor()` syntax element defined in _ISO/IEC 13818-11_.
241 IPMP 41 => UnknownDescriptor,
242 /// The `AVC_timing_and_HRD_descriptor()` syntax element from _ISO/IEC 13818-1_.
243 AvcTimingAndHrd 42 => UnknownDescriptor,
244 /// The `MPEG-2_AAC_audio_descriptor()` syntax element from _ISO/IEC 13818-1_.
245 Mpeg2AacAudio 43 => UnknownDescriptor,
246 /// The `FlexMuxTiming_descriptor()` syntax element from _ISO/IEC 13818-1_.
247 FlexMuxTiming 44 => UnknownDescriptor,
248 /// The `MPEG-4_text_descriptor()` syntax element from _ISO/IEC 13818-1_.
249 Mpeg4Text 45 => UnknownDescriptor,
250 /// The `MPEG-4_audio_extension_descriptor()` syntax element from _ISO/IEC 13818-1_.
251 Mpeg4AudioExtension 46 => UnknownDescriptor,
252 /// The `Auxiliary_video_stream_descriptor()` syntax element from _ISO/IEC 13818-1_.
253 AuxiliaryVideoStream 47 => UnknownDescriptor,
254 /// The `SVC extension descriptor()` syntax element from _ISO/IEC 13818-1_.
255 SvcExtension 48 => UnknownDescriptor,
256 /// The `MVC extension descriptor()` syntax element from _ISO/IEC 13818-1_.
257 MvcExtension 49 => UnknownDescriptor,
258 /// The `J2K video descriptor()` syntax element from _ISO/IEC 13818-1_.
259 J2kVideo 50 => UnknownDescriptor,
260 /// The `MVC operation point descriptor()` syntax element from _ISO/IEC 13818-1_.
261 MvcOperationPoint 51 => UnknownDescriptor,
262 /// The `MPEG2_stereoscopic_video_format_descriptor()` syntax element from _ISO/IEC 13818-1_.
263 Mpeg2StereoscopicVideoFormat 52 => UnknownDescriptor,
264 /// The `Stereoscopic_program_info_descriptor()` syntax element from _ISO/IEC 13818-1_.
265 StereoscopicProgramInfo 53 => UnknownDescriptor,
266 /// The `Stereoscopic_video_info_descriptor()` syntax element from _ISO/IEC 13818-1_.
267 StereoscopicVideoInfo 54 => UnknownDescriptor,
268 /// The `Transport_profile_descriptor()` syntax element from _ISO/IEC 13818-1_.
269 TransportProfile 55 => UnknownDescriptor,
270 /// The `HEVC video descriptor()` syntax element from _ISO/IEC 13818-1_.
271 HevcVideo 56 => UnknownDescriptor,
272 /// The `Extension_descriptor()` syntax element from _ISO/IEC 13818-1_.
273 Extension 63 => UnknownDescriptor,
274 /// descriptor tag values `64` to `255` inclusive are marked for 'use private' use by _ISO/IEC 13818-1_.
275 UserPrivate 64..=255 => UnknownDescriptor,
276 }
277}
278
279/// Iterator over the descriptor elements in a given byte slice.
280pub struct DescriptorIter<'buf, Desc>
281where
282 Desc: Descriptor<'buf>,
283{
284 buf: &'buf [u8],
285 phantom: marker::PhantomData<Desc>,
286}
287impl<'buf, Desc> DescriptorIter<'buf, Desc>
288where
289 Desc: Descriptor<'buf>,
290{
291 /// Create an iterator over all the descriptors in the given slice
292 pub fn new(buf: &'buf [u8]) -> DescriptorIter<'buf, Desc> {
293 DescriptorIter {
294 buf,
295 phantom: marker::PhantomData,
296 }
297 }
298}
299impl<'buf, Desc> Iterator for DescriptorIter<'buf, Desc>
300where
301 Desc: Descriptor<'buf>,
302{
303 type Item = Result<Desc, DescriptorError>;
304
305 fn next(&mut self) -> Option<Self::Item> {
306 if self.buf.is_empty() {
307 return None;
308 }
309 if self.buf.len() < 2 {
310 let buflen = self.buf.len();
311 // ensure anther call to next() will yield None,
312 self.buf = &self.buf[0..0];
313 Some(Err(DescriptorError::BufferTooShort { buflen }))
314 } else {
315 let tag = self.buf[0];
316 let len = self.buf[1] as usize;
317 let remaining_size = self.buf.len() - 2;
318 if len > remaining_size {
319 // ensure anther call to next() will yield None,
320 self.buf = &self.buf[0..0];
321 Some(Err(DescriptorError::NotEnoughData {
322 tag,
323 actual: remaining_size,
324 expected: len,
325 }))
326 } else {
327 let (desc, rest) = self.buf.split_at(len + 2);
328 self.buf = rest;
329 Some(Descriptor::from_bytes(desc))
330 }
331 }
332 }
333}
334
335/// An error during parsing of a descriptor
336#[derive(Debug, PartialEq, Eq)]
337pub enum DescriptorError {
338 /// The amount of data available in the buffer is not enough to hold the descriptor's declared
339 /// size.
340 NotEnoughData {
341 /// descriptor tag value
342 tag: u8,
343 /// actual buffer size
344 actual: usize,
345 /// expected buffer size
346 expected: usize,
347 },
348 /// TODO: replace with NotEnoughData
349 TagTooLongForBuffer {
350 /// actual length in descriptor header
351 taglen: usize,
352 /// remaining bytes in buffer (which is seen to be shorter than `taglen`)
353 buflen: usize,
354 },
355 /// The buffer is too short to even hold the two bytes of generic descriptor header data
356 BufferTooShort {
357 /// the actual buffer length
358 buflen: usize,
359 },
360 /// There is no mapping defined of the given descriptor tag value to a `Descriptor` value.
361 UnhandledTagValue(u8),
362}
363
364pub(crate) fn descriptor_len(buf: &[u8], tag: u8, len: usize) -> Result<(), DescriptorError> {
365 if buf.len() < len {
366 Err(DescriptorError::NotEnoughData {
367 tag,
368 actual: buf.len(),
369 expected: len,
370 })
371 } else {
372 Ok(())
373 }
374}
375
376#[cfg(test)]
377mod test {
378 use crate::descriptor::{descriptor_len, CoreDescriptors, DescriptorError, DescriptorIter};
379 use assert_matches::assert_matches;
380 use hex_literal::*;
381
382 #[test]
383 fn core() {
384 let data = hex!("000100");
385 let mut iter = DescriptorIter::<CoreDescriptors<'_>>::new(&data);
386 let desc = iter.next().unwrap();
387 assert!(!format!("{:?}", desc).is_empty());
388 assert_matches!(desc, Ok(CoreDescriptors::Reserved(d)) => {
389 assert_eq!(d.tag, 0);
390 assert_eq!(d.payload, &[0]);
391 });
392 }
393
394 #[test]
395 fn not_enough_data() {
396 assert_matches!(
397 descriptor_len(b"", 0, 1),
398 Err(DescriptorError::NotEnoughData {
399 tag: 0,
400 actual: 0,
401 expected: 1,
402 })
403 );
404 }
405}