scuffle_mp4/
object_description.rs

1//! Object Description Framework
2//!
3//! ISO/IEC 14496-1 - 7.2
4
5use isobmff::IsoSized;
6use nutype_enum::nutype_enum;
7use scuffle_bytes_util::BytesCow;
8use scuffle_bytes_util::zero_copy::{Deserialize, DeserializeSeed, Serialize};
9
10mod decoder_config;
11mod es;
12mod profile_level_indication_index;
13mod sl_config;
14
15pub use decoder_config::*;
16pub use es::*;
17pub use profile_level_indication_index::*;
18pub use sl_config::*;
19
20nutype_enum! {
21    /// Class Tags for Descriptors
22    ///
23    /// ISO/IEC 14496-1 - 7.2.2.1
24    pub enum DescriptorTag(u8) {
25        /// Forbidden
26        Forbidden = 0x00,
27        /// ObjectDescrTag
28        ObjectDescrTag = 0x01,
29        /// InitialObjectDescrTag
30        InitialObjectDescrTag = 0x02,
31        /// ES_DescrTag
32        ES_DescrTag = 0x03,
33        /// DecoderConfigDescrTag
34        DecoderConfigDescrTag = 0x04,
35        /// DecSpecificInfoTag
36        DecSpecificInfoTag = 0x05,
37        /// SLConfigDescrTag
38        SLConfigDescrTag = 0x06,
39        /// ContentIdentDescrTag
40        ContentIdentDescrTag = 0x07,
41        /// SupplContentIdentDescrTag
42        SupplContentIdentDescrTag = 0x08,
43        /// IPI_DescrPointerTag
44        IPI_DescrPointerTag = 0x09,
45        /// IPMP_DescrPointerTag
46        IPMP_DescrPointerTag = 0x0A,
47        /// IPMP_DescrTag
48        IPMP_DescrTag = 0x0B,
49        /// QoS_DescrTag
50        QoS_DescrTag = 0x0C,
51        /// RegistrationDescrTag
52        RegistrationDescrTag = 0x0D,
53        /// ES_ID_IncTag
54        ES_ID_IncTag = 0x0E,
55        /// ES_ID_RefTag
56        ES_ID_RefTag = 0x0F,
57        /// MP4_IOD_Tag
58        MP4_IOD_Tag = 0x10,
59        /// MP4_OD_Tag
60        MP4_OD_Tag = 0x11,
61        /// IPL_DescrPointerRefTag
62        IPL_DescrPointerRefTag = 0x12,
63        /// ExtensionProfileLevelDescrTag
64        ExtensionProfileLevelDescrTag = 0x13,
65        /// profileLevelIndicationIndexDescrTag
66        profileLevelIndicationIndexDescrTag = 0x14,
67        /// ContentClassificationDescrTag
68        ContentClassificationDescrTag = 0x40,
69        /// KeyWordDescrTag
70        KeyWordDescrTag = 0x41,
71        /// RatingDescrTag
72        RatingDescrTag = 0x42,
73        /// LanguageDescrTag
74        LanguageDescrTag = 0x43,
75        /// ShortTextualDescrTag
76        ShortTextualDescrTag = 0x44,
77        /// ExpandedTextualDescrTag
78        ExpandedTextualDescrTag = 0x45,
79        /// ContentCreatorNameDescrTag
80        ContentCreatorNameDescrTag = 0x46,
81        /// ContentCreationDateDescrTag
82        ContentCreationDateDescrTag = 0x47,
83        /// OCICreatorNameDescrTag
84        OCICreatorNameDescrTag = 0x48,
85        /// OCICreationDateDescrTag
86        OCICreationDateDescrTag = 0x49,
87        /// SmpteCameraPositionDescrTag
88        SmpteCameraPositionDescrTag = 0x4A,
89        /// SegmentDescrTag
90        SegmentDescrTag = 0x4B,
91        /// MediaTimeDescrTag
92        MediaTimeDescrTag = 0x4C,
93        /// IPMP_ToolsListDescrTag
94        IPMP_ToolsListDescrTag = 0x60,
95        /// IPMP_ToolTag
96        IPMP_ToolTag = 0x61,
97        /// M4MuxTimingDescrTag
98        M4MuxTimingDescrTag = 0x62,
99        /// M4MuxCodeTableDescrTag
100        M4MuxCodeTableDescrTag = 0x63,
101        /// ExtSLConfigDescrTag
102        ExtSLConfigDescrTag = 0x64,
103        /// M4MuxBufferSizeDescrTag
104        M4MuxBufferSizeDescrTag = 0x65,
105        /// M4MuxIdentDescrTag
106        M4MuxIdentDescrTag = 0x66,
107        /// DependencyPointerTag
108        DependencyPointerTag = 0x67,
109        /// DependencyMarkerTag
110        DependencyMarkerTag = 0x68,
111        /// M4MuxChannelDescrTag
112        M4MuxChannelDescrTag = 0x69,
113        /// Forbidden2
114        Forbidden2 = 0xFF,
115    }
116}
117
118impl<'a> Deserialize<'a> for DescriptorTag {
119    fn deserialize<R>(reader: R) -> std::io::Result<Self>
120    where
121        R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
122    {
123        u8::deserialize(reader).map(Into::into)
124    }
125}
126
127impl Serialize for DescriptorTag {
128    fn serialize<W>(&self, writer: W) -> std::io::Result<()>
129    where
130        W: std::io::Write,
131    {
132        self.0.serialize(writer)
133    }
134}
135
136impl IsoSized for DescriptorTag {
137    fn size(&self) -> usize {
138        1
139    }
140}
141
142/// Base Descriptor
143///
144/// ISO/IEC 14496-1 - 7.2.2.2
145#[derive(Debug, PartialEq, Eq)]
146pub struct BaseDescriptor {
147    /// Descriptor tag
148    pub tag: DescriptorTag,
149    /// Number of bytes used to encode the descriptor, excluding the `tag` and
150    /// `size_of_instance` fields (defined here).
151    ///
152    /// Defined for expandable classes.
153    /// Every class inhereting from (i.e. containing) `BaseDescriptor` is an expandable class.
154    ///
155    /// See ISO/IEC 14496-1 - 8.3.3
156    pub size_of_instance: u32,
157}
158
159impl<'a> Deserialize<'a> for BaseDescriptor {
160    fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
161    where
162        R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
163    {
164        let tag = DescriptorTag::deserialize(&mut reader)?;
165
166        let mut size_of_instance = 0;
167        loop {
168            let byte = u8::deserialize(&mut reader)?;
169            size_of_instance = (size_of_instance << 7) | (byte & 0b0111_1111) as u32;
170
171            if (byte & 0b1000_0000) == 0 {
172                break;
173            }
174        }
175
176        Ok(Self { tag, size_of_instance })
177    }
178}
179
180impl Serialize for BaseDescriptor {
181    fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
182    where
183        W: std::io::Write,
184    {
185        self.tag.serialize(&mut writer)?;
186
187        let bytes = (32 - self.size_of_instance.leading_zeros()).div_ceil(7);
188        for i in (0..bytes).rev() {
189            let mut byte = ((self.size_of_instance >> (i * 7)) & 0b0111_1111) as u8;
190            if i != 0 {
191                byte |= 0b1000_0000;
192            }
193            byte.serialize(&mut writer)?;
194        }
195
196        Ok(())
197    }
198}
199
200impl IsoSized for BaseDescriptor {
201    fn size(&self) -> usize {
202        let mut size = 1; // tag
203        size += (32 - self.size_of_instance.leading_zeros() as usize).div_ceil(7);
204        size
205    }
206}
207
208/// Any descriptor that inherits [`BaseDescriptor`].
209#[derive(Debug, PartialEq, Eq)]
210pub struct UnknownDescriptor<'a> {
211    /// The base descriptor.
212    pub base_descriptor: BaseDescriptor,
213    /// The data of the descriptor.
214    ///
215    /// Length is `base_descriptor.size_of_instance`.
216    pub data: BytesCow<'a>,
217}
218
219impl<'a> UnknownDescriptor<'a> {
220    /// Create a new [`UnknownDescriptor`] from a given [`DescriptorTag`] and data.
221    pub fn new(tag: DescriptorTag, data: BytesCow<'a>) -> Self {
222        Self {
223            base_descriptor: BaseDescriptor {
224                tag,
225                size_of_instance: data.len() as u32,
226            },
227            data,
228        }
229    }
230}
231
232impl<'a> Deserialize<'a> for UnknownDescriptor<'a> {
233    fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
234    where
235        R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
236    {
237        let base_descriptor = BaseDescriptor::deserialize(&mut reader)?;
238        Self::deserialize_seed(reader, base_descriptor)
239    }
240}
241
242impl<'a> DeserializeSeed<'a, BaseDescriptor> for UnknownDescriptor<'a> {
243    fn deserialize_seed<R>(mut reader: R, seed: BaseDescriptor) -> std::io::Result<Self>
244    where
245        R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
246    {
247        let data = reader.try_read(seed.size_of_instance as usize)?;
248        Ok(Self {
249            base_descriptor: seed,
250            data,
251        })
252    }
253}
254
255impl Serialize for UnknownDescriptor<'_> {
256    fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
257    where
258        W: std::io::Write,
259    {
260        self.base_descriptor.serialize(&mut writer)?;
261        self.data.serialize(&mut writer)?;
262        Ok(())
263    }
264}
265
266impl IsoSized for UnknownDescriptor<'_> {
267    fn size(&self) -> usize {
268        self.base_descriptor.size() + self.data.size()
269    }
270}