scuffle_mp4/object_description/
decoder_config.rs1use isobmff::IsoSized;
2use nutype_enum::nutype_enum;
3use scuffle_bytes_util::zero_copy::{Deserialize, DeserializeSeed, Serialize, U24Be};
4use scuffle_bytes_util::{BitWriter, IoResultExt};
5
6use super::profile_level_indication_index::ProfileLevelIndicationIndexDescriptor;
7use super::{BaseDescriptor, DescriptorTag, UnknownDescriptor};
8
9nutype_enum! {
10 pub enum ObjectTypeIndication(u8) {
14 Forbidden = 0x00,
16 Systems14496_1_a = 0x01,
18 Systems14496_1_b = 0x02,
20 InteractionStream = 0x03,
22 Systems14496_1_ExtendedBIFSConfiguration = 0x04,
24 Systems14496_1_AFX = 0x05,
26 FontDataStream = 0x06,
28 SynthesizedTextureStream = 0x07,
30 StreamingTextStream = 0x08,
32 Visual14496_2 = 0x20,
34 Visual14496_10 = 0x21,
36 ParameterSets_14496_10 = 0x22,
38 Audio14496_3 = 0x40,
40 Visual13818_2_SimpleProfile = 0x60,
42 Visual13818_2_MainProfile = 0x61,
44 Visual13818_2_SNRProfile = 0x62,
46 Visual13818_2_SpatialProfile = 0x63,
48 Visual13818_2_HighProfile = 0x64,
50 Visual13818_2_422Profile = 0x65,
52 Audio13818_7_MainProfile = 0x66,
54 Audio13818_7_LowComplexityProfile = 0x67,
56 Audio13818_7_ScaleableSamplingRateProfile = 0x68,
58 Audio13818_3 = 0x69,
60 Visual11172_2 = 0x6A,
62 Audio11172_3 = 0x6B,
64 Visual10918_1 = 0x6C,
66 Visual15444_1 = 0x6E,
68 Unspecified = 0xFF,
70 }
71}
72
73impl<'a> Deserialize<'a> for ObjectTypeIndication {
74 fn deserialize<R>(reader: R) -> std::io::Result<Self>
75 where
76 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
77 {
78 u8::deserialize(reader).map(Into::into)
79 }
80}
81
82impl Serialize for ObjectTypeIndication {
83 fn serialize<W>(&self, writer: W) -> std::io::Result<()>
84 where
85 W: std::io::Write,
86 {
87 self.0.serialize(writer)
88 }
89}
90
91impl IsoSized for ObjectTypeIndication {
92 fn size(&self) -> usize {
93 1
94 }
95}
96
97nutype_enum! {
98 pub enum StreamType(u8) {
102 Forbidden = 0x00,
104 ObjectDescriptorStream = 0x01,
108 ClockReferenceStream = 0x02,
112 SceneDescriptionStream = 0x03,
116 VisualStream = 0x04,
118 AudioStream = 0x05,
120 MPEG7Stream = 0x06,
122 IPMPStream = 0x07,
126 ObjectContentInfoStream = 0x08,
130 MPEGJStream = 0x09,
132 InteractionStream = 0x0A,
134 IPMPToolStream = 0x0B,
138 }
139}
140
141#[derive(Debug, PartialEq, Eq)]
145pub struct DecoderConfigDescriptor<'a> {
146 pub object_type_indication: ObjectTypeIndication,
149 pub stream_type: StreamType,
151 pub up_stream: bool,
153 pub reserved: bool,
155 pub buffer_size_db: U24Be,
157 pub max_bitrate: u32,
160 pub avg_bitrate: u32,
163 pub dec_specific_info: Option<UnknownDescriptor<'a>>,
165 pub profile_level_indication_index_descr: Vec<ProfileLevelIndicationIndexDescriptor>,
167 pub unknown_descriptors: Vec<UnknownDescriptor<'a>>,
169}
170
171impl DecoderConfigDescriptor<'_> {
172 fn payload_size(&self) -> usize {
173 let mut size = 0;
174 size += self.object_type_indication.size();
175 size += 1; size += self.buffer_size_db.size();
177 size += self.max_bitrate.size();
178 size += self.avg_bitrate.size();
179
180 size += self.dec_specific_info.size();
181 size += self.profile_level_indication_index_descr.size();
182 size += self.unknown_descriptors.size();
183
184 size
185 }
186
187 pub fn base_descriptor(&self) -> BaseDescriptor {
189 BaseDescriptor {
190 tag: DescriptorTag::DecoderConfigDescrTag,
191 size_of_instance: self.payload_size() as u32,
192 }
193 }
194}
195
196impl<'a> Deserialize<'a> for DecoderConfigDescriptor<'a> {
197 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
198 where
199 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
200 {
201 let base_descriptor = BaseDescriptor::deserialize(&mut reader)?;
202 let mut reader = reader.take(base_descriptor.size_of_instance as usize);
203
204 let object_type_indication = ObjectTypeIndication::deserialize(&mut reader)?;
205
206 let byte = u8::deserialize(&mut reader)?;
207 let stream_type = StreamType::from((byte & 0b111_1100) >> 2);
208 let up_stream = (byte & 0b0000_0010) != 0;
209 let reserved = (byte & 0b0000_0001) != 0;
210 let buffer_size_db = U24Be::deserialize(&mut reader)?;
211 let max_bitrate = u32::deserialize(&mut reader)?;
212 let avg_bitrate = u32::deserialize(&mut reader)?;
213
214 let mut dec_specific_info = None;
215 let mut profile_level_indication_index_descr = Vec::new();
216 let mut unknown_descriptors = Vec::new();
217
218 loop {
219 let Some(base_descriptor) = BaseDescriptor::deserialize(&mut reader).eof_to_none()? else {
220 break;
221 };
222
223 match base_descriptor.tag {
224 DescriptorTag::DecSpecificInfoTag => {
225 let Some(descr) = UnknownDescriptor::deserialize_seed(&mut reader, base_descriptor).eof_to_none()?
226 else {
227 break;
228 };
229 dec_specific_info = Some(descr);
230 }
231 DescriptorTag::profileLevelIndicationIndexDescrTag => {
232 let Some(descr) = ProfileLevelIndicationIndexDescriptor::deserialize_seed(&mut reader, base_descriptor)
233 .eof_to_none()?
234 else {
235 break;
236 };
237 profile_level_indication_index_descr.push(descr);
238 }
239 _ => {
240 let Some(descr) = UnknownDescriptor::deserialize_seed(&mut reader, base_descriptor).eof_to_none()?
241 else {
242 break;
243 };
244 unknown_descriptors.push(descr);
245 }
246 }
247 }
248
249 Ok(Self {
250 object_type_indication,
251 stream_type,
252 up_stream,
253 reserved,
254 buffer_size_db,
255 max_bitrate,
256 avg_bitrate,
257 dec_specific_info,
258 profile_level_indication_index_descr,
259 unknown_descriptors,
260 })
261 }
262}
263
264impl Serialize for DecoderConfigDescriptor<'_> {
265 fn serialize<W>(&self, writer: W) -> std::io::Result<()>
266 where
267 W: std::io::Write,
268 {
269 let mut bit_writer = BitWriter::new(writer);
270
271 self.base_descriptor().serialize(&mut bit_writer)?;
272 self.object_type_indication.serialize(&mut bit_writer)?;
273 bit_writer.write_bits(self.stream_type.0 as u64, 6)?;
274 bit_writer.write_bit(self.up_stream)?;
275 bit_writer.write_bit(self.reserved)?;
276 self.buffer_size_db.serialize(&mut bit_writer)?;
277 self.max_bitrate.serialize(&mut bit_writer)?;
278 self.avg_bitrate.serialize(&mut bit_writer)?;
279
280 if let Some(dec_specific_info) = &self.dec_specific_info {
281 dec_specific_info.serialize(&mut bit_writer)?;
282 }
283
284 for profile_level_indication_index_descr in &self.profile_level_indication_index_descr {
285 profile_level_indication_index_descr.serialize(&mut bit_writer)?;
286 }
287
288 for unknown_descriptor in &self.unknown_descriptors {
289 unknown_descriptor.serialize(&mut bit_writer)?;
290 }
291
292 Ok(())
293 }
294}
295
296impl IsoSized for DecoderConfigDescriptor<'_> {
297 fn size(&self) -> usize {
298 self.base_descriptor().size() + self.payload_size()
299 }
300}