Skip to main content

oggopus_embedded/
opus.rs

1/*
2 * Copyright (c) 2025 Tomi Leppänen
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5//! Opus parsing code.
6
7use core::num::NonZeroUsize;
8use nom::{bytes::complete::tag, error::ErrorKind, number, Parser};
9
10/// Error values for formatting.
11#[derive(Debug, PartialEq)]
12#[doc(hidden)]
13#[non_exhaustive]
14pub enum ErrorValues {
15    ZeroStreamCount,
16    BadNumberOfChannels(u8, u8),
17    InvalidChannelIndex(u8),
18    TotalStreamCountExceeds(u16),
19    StreamCountsMismatch(u8, u8),
20    BadTableLength(usize, u8),
21    TableTooBig(usize, u8),
22}
23
24/// Errors from parsing opus data.
25#[derive(Debug, PartialEq)]
26pub enum OpusError {
27    /// Parsing error from nom library.
28    ParsingError(ErrorKind),
29    /// Stream ended abruptly.
30    EndOfStreamError(Option<NonZeroUsize>),
31    /// Stream is not a valid opus stream, e.g. it has a value outside specifications.
32    InvalidStream(ErrorValues),
33    /// Stream is not supported. Enabled features may affect this.
34    UnsupportedStream(&'static str),
35    /// Stream is not an opus stream but something else.
36    NotOpusStream,
37}
38
39impl core::fmt::Display for OpusError {
40    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
41        use OpusError::*;
42        match self {
43            ParsingError(kind) => f.write_fmt(format_args!(
44                "parsing error with Opus: {}",
45                kind.description()
46            ))?,
47            EndOfStreamError(Some(size)) => f.write_fmt(format_args!(
48                "Opus stream ended abruptly with {} more bytes needed",
49                size
50            ))?,
51            EndOfStreamError(None) => f.write_fmt(format_args!("Opus stream ended abruptly"))?,
52            InvalidStream(issue) => match issue {
53                ErrorValues::ZeroStreamCount => {
54                    f.write_str("stream count cannot be 0")?
55                }
56                ErrorValues::BadNumberOfChannels(family, channels) => f.write_fmt(format_args!(
57                    "bad number of channels for family {}: {}",
58                    family, channels
59                ))?,
60                ErrorValues::InvalidChannelIndex(index) => f.write_fmt(format_args!(
61                    "invalid channel index in channel mapping table: {}",
62                    index
63                ))?,
64                ErrorValues::TotalStreamCountExceeds(total) => f.write_fmt(format_args!(
65                    "total stream count cannot be more than 255: {}",
66                    total
67                ))?,
68                ErrorValues::StreamCountsMismatch(coupled_count, stream_count) => f.write_fmt(format_args!(
69                    "coupled stream count ({}) cannot be larger than stream count ({})",
70                    coupled_count, stream_count
71                ))?,
72                ErrorValues::BadTableLength(length, channels) => f.write_fmt(format_args!(
73                    "channel mapping table length does not match the number of channels ({}): {}",
74                    channels, length
75                ))?,
76                ErrorValues::TableTooBig(length, max_size) => f.write_fmt(format_args!(
77                    "channel mapping table does not fit to reserved space ({}), it is {} bytes long",
78                    max_size, length,
79                ))?,
80            },
81            UnsupportedStream(issue) => {
82                f.write_fmt(format_args!("unsupported stream: {}", issue))?
83            }
84            NotOpusStream => f.write_str("this is not an Opus stream")?,
85        };
86        Ok(())
87    }
88}
89
90impl core::error::Error for OpusError {
91    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
92        None
93    }
94}
95
96impl<'data> From<nom::Err<(&'data [u8], ErrorKind)>> for OpusError {
97    fn from(error: nom::Err<(&'data [u8], ErrorKind)>) -> OpusError {
98        use OpusError::*;
99        match error {
100            nom::Err::Failure((_, kind)) => ParsingError(kind),
101            nom::Err::Error((_, kind)) => ParsingError(kind),
102            nom::Err::Incomplete(nom::Needed::Size(size)) => EndOfStreamError(Some(size)),
103            nom::Err::Incomplete(nom::Needed::Unknown) => EndOfStreamError(None),
104        }
105    }
106}
107
108/// Result for opus parsing errors.
109pub type Result<'data, O> = core::result::Result<O, OpusError>;
110
111/// Channel mapping of opus stream.
112#[derive(Debug, PartialEq)]
113#[non_exhaustive]
114pub enum ChannelMapping {
115    /**
116     * Family 0 channel mapping.
117     *
118     * Supports mono and stereo audio.
119     */
120    Family0 {
121        /// The number of channels, which can be 1 (mono) or 2 (stereo).
122        channels: u8,
123    },
124    /**
125     * Family 1 channel mapping.
126     *
127     * Vorbis channel order.
128     */
129    Family1 {
130        /// The number of channels, which can be between 1 and 8.
131        channels: u8,
132        /// Channel mapping table.
133        table: ChannelMappingTable<8>,
134    },
135    #[cfg_attr(docsrs, doc(cfg(feature = "family255")))]
136    #[cfg(feature = "family255")]
137    /**
138     * Family 255 channel mapping.
139     *
140     * Channels are unidentified.
141     */
142    Family255 {
143        /// The number of channels.
144        channels: u8,
145        /// Channel mapping table.
146        table: ChannelMappingTable<255>,
147    },
148    #[cfg_attr(docsrs, doc(cfg(feature = "family255")))]
149    #[cfg(feature = "family255")]
150    /**
151     * Reserved channel mapping value was used in the stream.
152     *
153     * Such mapping may be a future extension to the container format.
154     */
155    Reserved {
156        /// The number of channels.
157        channels: u8,
158        /// Channel mapping table.
159        table: ChannelMappingTable<255>,
160    },
161}
162
163impl ChannelMapping {
164    /// Get channel count.
165    pub fn get_channel_count(&self) -> u8 {
166        use ChannelMapping::*;
167        match self {
168            Family0 { channels } => *channels,
169            Family1 { channels, .. } => *channels,
170            #[cfg(feature = "family255")]
171            Family255 { channels, .. } => *channels,
172            #[cfg(feature = "family255")]
173            Reserved { channels, .. } => *channels,
174        }
175    }
176
177    /// Get stream count.
178    pub fn get_stream_count(&self) -> u8 {
179        use ChannelMapping::*;
180        match self {
181            Family0 { .. } => 1,
182            Family1 { table, .. } => table.stream_count,
183            #[cfg(feature = "family255")]
184            Family255 { table, .. } => table.stream_count,
185            #[cfg(feature = "family255")]
186            Reserved { table, .. } => table.stream_count,
187        }
188    }
189
190    /// Get coupled stream count.
191    pub fn get_coupled_stream_count(&self) -> u8 {
192        use ChannelMapping::*;
193        match self {
194            Family0 { channels } => *channels - 1,
195            Family1 { table, .. } => table.coupled_count,
196            #[cfg(feature = "family255")]
197            Family255 { table, .. } => table.coupled_count,
198            #[cfg(feature = "family255")]
199            Reserved { table, .. } => table.coupled_count,
200        }
201    }
202
203    /**
204     * Get channel mapping for given channel index.
205     *
206     * Returns [`None`] for invalid channel indexes.
207     */
208    pub fn get_mapping(&self, channel: u8) -> Option<Mapping> {
209        use ChannelMapping::*;
210        let (speaker_location, index, coupled_count) = match self {
211            Family0 { channels } => {
212                let speaker_location = match (*channels, channel) {
213                    (1, 0) => SpeakerLocation::Mono,
214                    (2, 0) => SpeakerLocation::Left,
215                    (2, 1) => SpeakerLocation::Right,
216                    _ => return None,
217                };
218                Some((Some(speaker_location), channel, *channels - 1))
219            }
220            Family1 { channels, table } => {
221                let speaker_location = match (*channels, channel) {
222                    (1, 0) => SpeakerLocation::Mono,
223                    (2..=8, 0) => SpeakerLocation::Left,
224                    (2, 1) | (3, 2) | (4, 1) | (5..=8, 2) => SpeakerLocation::Right,
225                    (3, 1) | (5..=8, 1) => SpeakerLocation::Center,
226                    (4, 2) | (5..=6, 3) | (8, 5) => SpeakerLocation::RearLeft,
227                    (4, 3) | (5..=6, 4) | (8, 6) => SpeakerLocation::RearRight,
228                    (6, 5) | (7, 6) | (8, 7) => SpeakerLocation::LFE,
229                    (7..=8, 3) => SpeakerLocation::SideLeft,
230                    (7..=8, 4) => SpeakerLocation::SideRight,
231                    (7, 5) => SpeakerLocation::RearCenter,
232                    _ => return None,
233                };
234                let ChannelMappingTable {
235                    coupled_count,
236                    mapping,
237                    ..
238                } = &table;
239                let index = mapping[usize::from(channel)];
240                Some((Some(speaker_location), index, *coupled_count))
241            }
242            #[cfg(feature = "family255")]
243            Family255 { channels, table } | Reserved { channels, table } => {
244                if channel >= *channels {
245                    None
246                } else {
247                    let ChannelMappingTable {
248                        coupled_count,
249                        mapping,
250                        ..
251                    } = &table;
252                    let index = mapping[usize::from(channel)];
253                    Some((None, index, *coupled_count))
254                }
255            }
256        }?;
257        if index == 255 {
258            Some(Mapping {
259                stream: None,
260                speaker_location,
261            })
262        } else {
263            let stream = if index < 2 * coupled_count {
264                if index % 2 == 0 {
265                    (index / 2, DecodedChannel::Left)
266                } else {
267                    (index / 2, DecodedChannel::Right)
268                }
269            } else {
270                (index - coupled_count, DecodedChannel::Mono)
271            };
272            let stream = Some(stream);
273            Some(Mapping {
274                stream,
275                speaker_location,
276            })
277        }
278    }
279}
280
281/// Speaker location in audio setup.
282#[derive(Clone, Copy, Debug, PartialEq)]
283#[non_exhaustive]
284pub enum SpeakerLocation {
285    /// Mono speaker.
286    Mono,
287    /// Left channel of a stereo stream. Front left in surround setup.
288    Left,
289    /// Right channel of a stereo stream. Front right in surround setup.
290    Right,
291    /// Center channel in linear surround setup. Front center in surround setup.
292    Center,
293    /// Rear left channel of a surround setup.
294    RearLeft,
295    /// Rear right channel of a surround setup.
296    RearRight,
297    /// Rear center channel of a surround setup.
298    RearCenter,
299    /// Side left channel of a surround setup.
300    SideLeft,
301    /// Side right channel of a surround setup.
302    SideRight,
303    /// Low-frequency effects channel of a surround setup.
304    LFE,
305}
306
307/// Decoded opus channel to use for this audio channel.
308#[derive(Clone, Copy, Debug, PartialEq)]
309pub enum DecodedChannel {
310    /// The opus stream will be mono audio.
311    Mono,
312    /// Use the first decoded channel of the stereo stream.
313    Left,
314    /// Use the second decoded channel of the stereo stream.
315    Right,
316}
317
318/// Channel mapping for an audio channel.
319#[derive(Debug, PartialEq)]
320pub struct Mapping {
321    /// Stream index and decoded opus stream channel to use. Silent channel if [`None`].
322    pub stream: Option<(u8, DecodedChannel)>,
323    /// Speaker location for this index if available.
324    pub speaker_location: Option<SpeakerLocation>,
325}
326
327/// Channel mapping table.
328#[derive(Debug, PartialEq)]
329pub struct ChannelMappingTable<const MAX_CHANNELS: usize> {
330    /// The number of total streams encoded in each Ogg packet.
331    stream_count: u8,
332    /// The number of stereo decoders needed.
333    coupled_count: u8,
334    /// Channel mapping data.
335    mapping: [u8; MAX_CHANNELS],
336}
337
338impl<const MAX_CHANNELS: usize> ChannelMappingTable<MAX_CHANNELS> {
339    fn parse(input: &[u8], channels: u8) -> Result<ChannelMappingTable<MAX_CHANNELS>> {
340        use OpusError::*;
341        let (input, stream_count) = number::u8().parse(input)?;
342        let (input, coupled_count) = number::u8().parse(input)?;
343        let total_stream_count = stream_count.checked_add(coupled_count).ok_or_else(|| {
344            let total = stream_count as u16 + coupled_count as u16;
345            InvalidStream(ErrorValues::TotalStreamCountExceeds(total))
346        })?;
347        if stream_count == 0 {
348            Err(InvalidStream(ErrorValues::ZeroStreamCount))
349        } else if coupled_count > stream_count {
350            Err(InvalidStream(ErrorValues::StreamCountsMismatch(
351                coupled_count,
352                stream_count,
353            )))
354        } else if input.len() != channels.into() {
355            Err(InvalidStream(ErrorValues::BadTableLength(
356                input.len(),
357                channels,
358            )))
359        } else if input.len() > MAX_CHANNELS {
360            Err(InvalidStream(ErrorValues::TableTooBig(
361                input.len(),
362                MAX_CHANNELS as u8, // At most 255
363            )))
364        } else {
365            let mut mapping = [0; MAX_CHANNELS];
366            for (i, &v) in input.iter().enumerate() {
367                if v >= total_stream_count && v != 255 {
368                    return Err(InvalidStream(ErrorValues::InvalidChannelIndex(v)));
369                }
370                mapping[i] = v;
371            }
372            Ok(ChannelMappingTable {
373                stream_count,
374                coupled_count,
375                mapping,
376            })
377        }
378    }
379}
380
381/// Opus header data.
382#[derive(Debug, PartialEq)]
383pub struct OpusHeader {
384    /// Opus version.
385    pub version: u8,
386    /// Channel mapping.
387    pub channels: ChannelMapping,
388    /// The number of samples to skip in the beginning of the stream.
389    pub pre_skip: u16,
390    /// Sample rate used for the original audio.
391    pub sample_rate: u32,
392    /// Output gain.
393    pub output_gain: u16,
394}
395
396impl OpusHeader {
397    /**
398     * Parse opus header from input data.
399     *
400     * May return [`UnsupportedStream`][`OpusError::UnsupportedStream`] if family255 feature has
401     * not been enabled and such stream is encountered.
402     */
403    pub fn parse(input: &[u8]) -> Result<Self> {
404        use OpusError::*;
405        let (input, _) = tag(b"OpusHead".as_slice())(input)
406            .map_err(|_: nom::Err<(&[u8], ErrorKind)>| NotOpusStream)?;
407        let (input, version) = number::u8().parse(input)?;
408        let (input, channels) = number::u8().parse(input)?;
409        let (input, pre_skip) = number::le_u16().parse(input)?;
410        let (input, sample_rate) = number::le_u32().parse(input)?;
411        let (input, output_gain) = number::le_u16().parse(input)?;
412        let (channel_mapping_table, channel_mapping_family) = number::u8().parse(input)?;
413        let channels = match channel_mapping_family {
414            0 => match channels {
415                1..=2 => ChannelMapping::Family0 { channels },
416                _ => return Err(InvalidStream(ErrorValues::BadNumberOfChannels(0, channels))),
417            },
418            1 => match channels {
419                1..=8 => ChannelMapping::Family1 {
420                    channels,
421                    table: ChannelMappingTable::parse(channel_mapping_table, channels)?,
422                },
423                _ => return Err(InvalidStream(ErrorValues::BadNumberOfChannels(1, channels))),
424            },
425            #[cfg(feature = "family255")]
426            255 => ChannelMapping::Family255 {
427                channels,
428                table: ChannelMappingTable::parse(channel_mapping_table, channels)?,
429            },
430            #[cfg(feature = "family255")]
431            _ => ChannelMapping::Reserved {
432                channels,
433                table: ChannelMappingTable::parse(channel_mapping_table, channels)?,
434            },
435            #[cfg(not(feature = "family255"))]
436            _ => {
437                return Err(UnsupportedStream(
438                    "family 255 channel mapping is not supported",
439                ))
440            }
441        };
442        Ok(Self {
443            version,
444            channels,
445            pre_skip,
446            sample_rate,
447            output_gain,
448        })
449    }
450}
451
452#[cfg(test)]
453mod test {
454    use super::*;
455    use core::error::Error;
456
457    #[test]
458    fn parse_header() {
459        let data = include_bytes!("test/opus.data");
460        let header = OpusHeader::parse(data).unwrap();
461        assert_eq!(header.version, 1);
462        if let ChannelMapping::Family0 { channels } = header.channels {
463            assert_eq!(channels, 1);
464        } else {
465            panic!("Channel mapping family must be 0");
466        }
467        assert_eq!(header.pre_skip, 312);
468        assert_eq!(header.sample_rate, 8_000);
469        assert_eq!(header.output_gain, 0);
470    }
471
472    #[test]
473    fn family_0_mono() {
474        let channels = ChannelMapping::Family0 { channels: 1 };
475        assert_eq!(channels.get_channel_count(), 1);
476        assert_eq!(channels.get_stream_count(), 1);
477        assert_eq!(channels.get_coupled_stream_count(), 0);
478        let mapping = channels.get_mapping(0).unwrap();
479        assert_eq!(mapping.stream, Some((0, DecodedChannel::Mono)));
480        assert_eq!(mapping.speaker_location, Some(SpeakerLocation::Mono));
481        for index in 1..=255 {
482            assert_eq!(channels.get_mapping(index), None);
483        }
484    }
485
486    #[test]
487    fn family_0_stereo() {
488        let channels = ChannelMapping::Family0 { channels: 2 };
489        assert_eq!(channels.get_channel_count(), 2);
490        assert_eq!(channels.get_stream_count(), 1);
491        assert_eq!(channels.get_coupled_stream_count(), 1);
492        let mapping = channels.get_mapping(0).unwrap();
493        assert_eq!(mapping.stream, Some((0, DecodedChannel::Left)));
494        assert_eq!(mapping.speaker_location, Some(SpeakerLocation::Left));
495        let mapping = channels.get_mapping(1).unwrap();
496        assert_eq!(mapping.stream, Some((0, DecodedChannel::Right)));
497        assert_eq!(mapping.speaker_location, Some(SpeakerLocation::Right));
498        for index in 2..=255 {
499            assert_eq!(channels.get_mapping(index), None);
500        }
501    }
502
503    #[test]
504    fn family_1_stereo() {
505        let channels = ChannelMapping::Family1 {
506            channels: 2,
507            table: ChannelMappingTable::parse(&[1, 1, 0, 1], 2).unwrap(),
508        };
509        assert_eq!(channels.get_channel_count(), 2);
510        assert_eq!(channels.get_stream_count(), 1);
511        assert_eq!(channels.get_coupled_stream_count(), 1);
512        let mapping = channels.get_mapping(0).unwrap();
513        assert_eq!(mapping.stream, Some((0, DecodedChannel::Left)));
514        assert_eq!(mapping.speaker_location, Some(SpeakerLocation::Left));
515        let mapping = channels.get_mapping(1).unwrap();
516        assert_eq!(mapping.stream, Some((0, DecodedChannel::Right)));
517        assert_eq!(mapping.speaker_location, Some(SpeakerLocation::Right));
518        for index in 2..=255 {
519            assert_eq!(channels.get_mapping(index), None);
520        }
521    }
522
523    #[test]
524    fn family_1_surround_5_1() {
525        let data: [u8; 0x08] = [0x04, 0x02, 0x00, 0x04, 0x01, 0x02, 0x03, 0x05];
526        let channels = ChannelMapping::Family1 {
527            channels: 6,
528            table: ChannelMappingTable::parse(&data, 6).unwrap(),
529        };
530        assert_eq!(channels.get_channel_count(), 6);
531        assert_eq!(channels.get_stream_count(), 4);
532        assert_eq!(channels.get_coupled_stream_count(), 2);
533        let mappings = [
534            (0, DecodedChannel::Left, SpeakerLocation::Left),
535            (2, DecodedChannel::Mono, SpeakerLocation::Center),
536            (0, DecodedChannel::Right, SpeakerLocation::Right),
537            (1, DecodedChannel::Left, SpeakerLocation::RearLeft),
538            (1, DecodedChannel::Right, SpeakerLocation::RearRight),
539            (3, DecodedChannel::Mono, SpeakerLocation::LFE),
540        ];
541        for (index, (stream, channel, location)) in mappings.iter().enumerate() {
542            let mapping = channels.get_mapping(index as u8).unwrap();
543            assert_eq!(mapping.stream, Some((*stream, *channel)));
544            assert_eq!(mapping.speaker_location, Some(*location));
545        }
546        for index in 6..=255 {
547            assert_eq!(channels.get_mapping(index), None);
548        }
549    }
550
551    #[test]
552    #[cfg(feature = "family255")]
553    fn family_255() {
554        let data: [u8; 0x08] = [0x04, 0x02, 0x00, 0x04, 0x01, 0x02, 0x03, 0x05];
555        let channels = ChannelMapping::Family255 {
556            channels: 6,
557            table: ChannelMappingTable::parse(&data, 6).unwrap(),
558        };
559        assert_eq!(channels.get_channel_count(), 6);
560        assert_eq!(channels.get_stream_count(), 4);
561        assert_eq!(channels.get_coupled_stream_count(), 2);
562        let mappings = [
563            (0, DecodedChannel::Left),
564            (2, DecodedChannel::Mono),
565            (0, DecodedChannel::Right),
566            (1, DecodedChannel::Left),
567            (1, DecodedChannel::Right),
568            (3, DecodedChannel::Mono),
569        ];
570        for (index, (stream, channel)) in mappings.iter().enumerate() {
571            let mapping = channels.get_mapping(index as u8).unwrap();
572            assert_eq!(mapping.stream, Some((*stream, *channel)));
573            assert_eq!(mapping.speaker_location, None);
574        }
575        for index in 6..=255 {
576            assert_eq!(channels.get_mapping(index), None);
577        }
578    }
579
580    #[test]
581    #[cfg(feature = "family255")]
582    fn family_reserved() {
583        let data: [u8; 0x06] = [0x02, 0x01, 0x01, 0x00, 0x02, 0xFF];
584        let channels = ChannelMapping::Reserved {
585            channels: 4,
586            table: ChannelMappingTable::parse(&data, 4).unwrap(),
587        };
588        assert_eq!(channels.get_channel_count(), 4);
589        assert_eq!(channels.get_stream_count(), 2);
590        assert_eq!(channels.get_coupled_stream_count(), 1);
591        let mappings = [
592            Some((0, DecodedChannel::Right)),
593            Some((0, DecodedChannel::Left)),
594            Some((1, DecodedChannel::Mono)),
595            None,
596        ];
597        for (index, stream) in mappings.iter().enumerate() {
598            let mapping = channels.get_mapping(index as u8).unwrap();
599            assert_eq!(mapping.stream, *stream);
600            assert_eq!(mapping.speaker_location, None);
601        }
602        for index in 4..=255 {
603            assert_eq!(channels.get_mapping(index), None);
604        }
605    }
606
607    #[test]
608    fn invalid_stream_count() {
609        let data: [u8; 0x08] = [0x04, 0x05, 0x00, 0x04, 0x01, 0x02, 0x03, 0x05];
610        let result = ChannelMappingTable::<255>::parse(&data, 6);
611        assert_eq!(
612            result,
613            Err(OpusError::InvalidStream(ErrorValues::StreamCountsMismatch(
614                5, 4
615            )))
616        );
617        assert_eq!(
618            result.unwrap_err().to_string(),
619            "coupled stream count (5) cannot be larger than stream count (4)"
620        );
621    }
622
623    #[test]
624    fn zero_stream_count() {
625        let data: [u8; 0x08] = [0x00, 0x01, 0x00, 0x04, 0x01, 0x02, 0x03, 0x05];
626        let result = ChannelMappingTable::<255>::parse(&data, 6);
627        assert_eq!(
628            result,
629            Err(OpusError::InvalidStream(ErrorValues::ZeroStreamCount))
630        );
631        assert_eq!(result.unwrap_err().to_string(), "stream count cannot be 0");
632    }
633
634    #[test]
635    fn invalid_table_length() {
636        let data: [u8; 0x08] = [0x04, 0x02, 0x00, 0x04, 0x01, 0x02, 0x03, 0x05];
637        let result = ChannelMappingTable::<255>::parse(&data, 2);
638        assert_eq!(
639            result,
640            Err(OpusError::InvalidStream(ErrorValues::BadTableLength(6, 2)))
641        );
642        assert_eq!(
643            result.unwrap_err().to_string(),
644            "channel mapping table length does not match the number of channels (2): 6"
645        );
646    }
647
648    #[test]
649    fn too_long_table() {
650        let data: [u8; 0x08] = [0x04, 0x02, 0x00, 0x04, 0x01, 0x02, 0x03, 0x05];
651        let result = ChannelMappingTable::<5>::parse(&data, 6);
652        assert_eq!(
653            result,
654            Err(OpusError::InvalidStream(ErrorValues::TableTooBig(6, 5)))
655        );
656        assert_eq!(
657            result.unwrap_err().to_string(),
658            "channel mapping table does not fit to reserved space (5), it is 6 bytes long"
659        );
660    }
661
662    #[test]
663    fn invalid_channel_index() {
664        let data: [u8; 0x08] = [0x04, 0x02, 0x00, 0xFF, 0x0A, 0x02, 0x03, 0x05];
665        let result = ChannelMappingTable::<255>::parse(&data, 6);
666        assert_eq!(
667            result,
668            Err(OpusError::InvalidStream(ErrorValues::InvalidChannelIndex(
669                0x0A
670            )))
671        );
672        assert_eq!(
673            result.unwrap_err().to_string(),
674            "invalid channel index in channel mapping table: 10"
675        );
676    }
677
678    #[test]
679    fn too_many_streams() {
680        let data: [u8; 0x02] = [0x90, 0x90];
681        let result = ChannelMappingTable::<5>::parse(&data, 6);
682        assert_eq!(
683            result,
684            Err(OpusError::InvalidStream(
685                ErrorValues::TotalStreamCountExceeds(0x90 * 2)
686            ))
687        );
688        assert_eq!(
689            result.unwrap_err().to_string(),
690            "total stream count cannot be more than 255: 288"
691        );
692    }
693
694    #[test]
695    fn corrupted_stream() {
696        let mut data = Vec::from(include_bytes!("test/opus.data"));
697        data[2] = 10;
698        let result = OpusHeader::parse(&data);
699        assert_eq!(result, Err(OpusError::NotOpusStream));
700        assert!(result.unwrap_err().source().is_none());
701    }
702
703    #[test]
704    fn incomplete_header() {
705        let data = include_bytes!("test/opus.data");
706        let result = OpusHeader::parse(&data[..10]);
707        assert_eq!(
708            result,
709            Err(OpusError::EndOfStreamError(Some(2.try_into().unwrap())))
710        );
711        assert!(result.unwrap_err().source().is_none());
712    }
713
714    #[test]
715    fn invalid_channels() {
716        let mut data = Vec::from(include_bytes!("test/opus.data"));
717        data[9] = 0;
718        let result = OpusHeader::parse(&data);
719        assert_eq!(
720            result,
721            Err(OpusError::InvalidStream(ErrorValues::BadNumberOfChannels(
722                0, 0
723            )))
724        );
725        assert!(result.unwrap_err().source().is_none());
726        data[0x12] = 1;
727        let result = OpusHeader::parse(&data);
728        assert_eq!(
729            result,
730            Err(OpusError::InvalidStream(ErrorValues::BadNumberOfChannels(
731                1, 0
732            )))
733        );
734        assert!(result.unwrap_err().source().is_none());
735    }
736}