mp4_atom/moov/trak/mdia/minf/stbl/stsd/mp4a/
esds.rs

1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq, Default)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub struct Esds {
6    pub es_desc: EsDescriptor,
7}
8
9impl AtomExt for Esds {
10    type Ext = ();
11
12    const KIND_EXT: FourCC = FourCC::new(b"esds");
13
14    fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
15        let mut es_desc = None;
16
17        while let Some(desc) = Descriptor::decode_maybe(buf)? {
18            match desc {
19                Descriptor::EsDescriptor(desc) => es_desc = Some(desc),
20                Descriptor::Unknown(tag, _) => {
21                    tracing::warn!("unknown descriptor: {:02X}", tag)
22                }
23                _ => return Err(Error::UnexpectedDescriptor(desc.tag())),
24            }
25        }
26
27        Ok(Esds {
28            es_desc: es_desc.ok_or(Error::MissingDescriptor(EsDescriptor::TAG))?,
29        })
30    }
31
32    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
33        Descriptor::from(self.es_desc).encode(buf)
34    }
35}
36
37macro_rules! descriptors {
38    ($($name:ident,)*) => {
39        #[derive(Debug, Clone, PartialEq, Eq)]
40        pub enum Descriptor {
41            $(
42                $name($name),
43            )*
44            Unknown(u8, Vec<u8>),
45        }
46
47        impl Decode for Descriptor {
48            fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
49                let tag = u8::decode(buf)?;
50
51                let mut size: u32 = 0;
52                for _ in 0..4 {
53                    let b = u8::decode(buf)?;
54                    size = (size << 7) | (b & 0x7F) as u32;
55                    if b & 0x80 == 0 {
56                        break;
57                    }
58                }
59
60                match tag {
61                    $(
62                        $name::TAG => Ok($name::decode_exact(buf, size as _)?.into()),
63                    )*
64                    _ => Ok(Descriptor::Unknown(tag, Vec::decode_exact(buf, size as _)?)),
65                }
66            }
67        }
68
69        impl DecodeMaybe for Descriptor {
70            fn decode_maybe<B: Buf>(buf: &mut B) -> Result<Option<Self>> {
71                match buf.has_remaining() {
72                    true => Descriptor::decode(buf).map(Some),
73                    false => Ok(None),
74                }
75            }
76        }
77
78        impl Encode for Descriptor {
79            fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
80                // TODO This is inefficient; we could compute the size upfront.
81                let mut tmp = Vec::new();
82
83                match self {
84                    $(
85                        Descriptor::$name(t) => {
86                            $name::TAG.encode(buf)?;
87                            t.encode(&mut tmp)?;
88                        },
89                    )*
90                    Descriptor::Unknown(tag, data) => {
91                        tag.encode(buf)?;
92                        data.encode(&mut tmp)?;
93                    },
94                };
95
96                let mut size = tmp.len() as u32;
97                while size > 0 {
98                    let mut b = (size & 0x7F) as u8;
99                    size >>= 7;
100                    if size > 0 {
101                        b |= 0x80;
102                    }
103                    b.encode(buf)?;
104                }
105
106                tmp.encode(buf)
107            }
108        }
109
110        impl Descriptor {
111            pub const fn tag(&self) -> u8 {
112                match self {
113                    $(
114                        Descriptor::$name(_) => $name::TAG,
115                    )*
116                    Descriptor::Unknown(tag, _) => *tag,
117                }
118            }
119        }
120
121        $(
122            impl From<$name> for Descriptor {
123                fn from(desc: $name) -> Self {
124                    Descriptor::$name(desc)
125                }
126            }
127        )*
128    };
129}
130
131descriptors! {
132    EsDescriptor,
133    DecoderConfig,
134    DecoderSpecific,
135    SLConfig,
136}
137
138#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
139#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
140pub struct EsDescriptor {
141    pub es_id: u16,
142
143    pub dec_config: DecoderConfig,
144    pub sl_config: SLConfig,
145}
146
147impl EsDescriptor {
148    pub const TAG: u8 = 0x03;
149}
150
151impl Decode for EsDescriptor {
152    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
153        let es_id = u16::decode(buf)?;
154        u8::decode(buf)?; // XXX flags must be 0
155
156        let mut dec_config = None;
157        let mut sl_config = None;
158
159        while let Some(desc) = Descriptor::decode_maybe(buf)? {
160            match desc {
161                Descriptor::DecoderConfig(desc) => dec_config = Some(desc),
162                Descriptor::SLConfig(desc) => sl_config = Some(desc),
163                Descriptor::Unknown(tag, _) => tracing::warn!("unknown descriptor: {:02X}", tag),
164                desc => return Err(Error::UnexpectedDescriptor(desc.tag())),
165            }
166        }
167
168        Ok(EsDescriptor {
169            es_id,
170            dec_config: dec_config.ok_or(Error::MissingDescriptor(DecoderConfig::TAG))?,
171            sl_config: sl_config.ok_or(Error::MissingDescriptor(SLConfig::TAG))?,
172        })
173    }
174}
175
176impl Encode for EsDescriptor {
177    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
178        self.es_id.encode(buf)?;
179        0u8.encode(buf)?;
180
181        Descriptor::from(self.dec_config).encode(buf)?;
182        Descriptor::from(self.sl_config).encode(buf)?;
183
184        Ok(())
185    }
186}
187
188#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
189#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
190pub struct DecoderConfig {
191    pub object_type_indication: u8,
192    pub stream_type: u8,
193    pub up_stream: u8,
194    pub buffer_size_db: u24,
195    pub max_bitrate: u32,
196    pub avg_bitrate: u32,
197    pub dec_specific: DecoderSpecific,
198}
199
200impl DecoderConfig {
201    pub const TAG: u8 = 0x04;
202}
203
204impl Decode for DecoderConfig {
205    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
206        let object_type_indication = u8::decode(buf)?;
207        let byte_a = u8::decode(buf)?;
208        let stream_type = (byte_a & 0xFC) >> 2;
209        let up_stream = byte_a & 0x02;
210        let buffer_size_db = u24::decode(buf)?;
211        let max_bitrate = u32::decode(buf)?;
212        let avg_bitrate = u32::decode(buf)?;
213
214        let mut dec_specific = None;
215
216        while let Some(desc) = Descriptor::decode_maybe(buf)? {
217            match desc {
218                Descriptor::DecoderSpecific(desc) => dec_specific = Some(desc),
219                Descriptor::Unknown(tag, _) => tracing::warn!("unknown descriptor: {:02X}", tag),
220                desc => return Err(Error::UnexpectedDescriptor(desc.tag())),
221            }
222        }
223
224        Ok(DecoderConfig {
225            object_type_indication,
226            stream_type,
227            up_stream,
228            buffer_size_db,
229            max_bitrate,
230            avg_bitrate,
231            dec_specific: dec_specific.ok_or(Error::MissingDescriptor(DecoderSpecific::TAG))?,
232        })
233    }
234}
235
236impl Encode for DecoderConfig {
237    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
238        self.object_type_indication.encode(buf)?;
239        ((self.stream_type << 2) + (self.up_stream & 0x02) + 1).encode(buf)?; // 1 reserved
240        self.buffer_size_db.encode(buf)?;
241        self.max_bitrate.encode(buf)?;
242        self.avg_bitrate.encode(buf)?;
243
244        Descriptor::from(self.dec_specific).encode(buf)?;
245
246        Ok(())
247    }
248}
249
250#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
251#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
252pub struct DecoderSpecific {
253    pub profile: u8,
254    pub freq_index: u8,
255    pub chan_conf: u8,
256}
257
258impl DecoderSpecific {
259    pub const TAG: u8 = 0x05;
260}
261
262impl Decode for DecoderSpecific {
263    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
264        let byte_a = u8::decode(buf)?;
265        let byte_b = u8::decode(buf)?;
266
267        let mut profile = byte_a >> 3;
268        if profile == 31 {
269            profile = 32 + ((byte_a & 7) | (byte_b >> 5));
270        }
271
272        let freq_index = if profile > 31 {
273            (byte_b >> 1) & 0x0F
274        } else {
275            ((byte_a & 0x07) << 1) + (byte_b >> 7)
276        };
277
278        let chan_conf;
279        if freq_index == 15 {
280            // Skip the 24 bit sample rate
281            // TODO this needs to be implemented in encode
282            let sample_rate = u24::decode(buf)?;
283            chan_conf = ((u32::from(sample_rate) >> 4) & 0x0F) as u8;
284        } else if profile > 31 {
285            let byte_c = u8::decode(buf)?;
286            chan_conf = (byte_b & 1) | (byte_c & 0xE0);
287        } else {
288            chan_conf = (byte_b >> 3) & 0x0F;
289        }
290
291        if buf.has_remaining() {
292            tracing::warn!("PLEASE FIX: failed to consume all bytes in DecoderSpecificDescriptor");
293            buf.advance(buf.remaining());
294        }
295
296        Ok(DecoderSpecific {
297            profile,
298            freq_index,
299            chan_conf,
300        })
301    }
302}
303
304impl Encode for DecoderSpecific {
305    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
306        ((self.profile << 3) + (self.freq_index >> 1)).encode(buf)?;
307        ((self.freq_index << 7) + (self.chan_conf << 3)).encode(buf)?;
308
309        Ok(())
310    }
311}
312
313#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
314#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
315pub struct SLConfig {}
316
317impl SLConfig {
318    pub const TAG: u8 = 0x06;
319}
320
321impl Decode for SLConfig {
322    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
323        u8::decode(buf)?; // pre-defined
324        Ok(SLConfig {})
325    }
326}
327
328impl Encode for SLConfig {
329    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
330        2u8.encode(buf)?; // pre-defined
331        Ok(())
332    }
333}