Skip to main content

dvb_si/descriptors/
mpeg4_audio.rs

1//! MPEG-4 Audio Descriptor — ISO/IEC 13818-1 §2.6.38 (tag 0x1C).
2//!
3//! Provides the MPEG-4 audio profile and level of the associated
4//! elementary stream.
5
6use super::descriptor_body;
7use crate::error::{Error, Result};
8use dvb_common::{Parse, Serialize};
9
10/// Descriptor tag for MPEG-4_audio_descriptor.
11pub const TAG: u8 = 0x1C;
12const HEADER_LEN: usize = 2;
13const BODY_LEN: u8 = 1;
14
15/// MPEG-4 Audio Descriptor.
16#[derive(Debug, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize))]
18#[cfg_attr(feature = "yoke", derive(yoke::Yokeable))]
19pub struct Mpeg4AudioDescriptor {
20    /// MPEG-4 audio profile and level indication.
21    pub mpeg_4_audio_profile_and_level: u8,
22}
23
24impl<'a> Parse<'a> for Mpeg4AudioDescriptor {
25    type Error = crate::error::Error;
26
27    fn parse(bytes: &'a [u8]) -> Result<Self> {
28        let body = descriptor_body(
29            bytes,
30            TAG,
31            "Mpeg4AudioDescriptor",
32            "unexpected tag for MPEG-4_audio_descriptor",
33        )?;
34        if body.len() < (BODY_LEN as usize) {
35            return Err(Error::InvalidDescriptor {
36                tag: TAG,
37                reason: "MPEG-4_audio_descriptor too short",
38            });
39        }
40        Ok(Self {
41            mpeg_4_audio_profile_and_level: body[0],
42        })
43    }
44}
45
46impl Serialize for Mpeg4AudioDescriptor {
47    type Error = crate::error::Error;
48
49    fn serialized_len(&self) -> usize {
50        HEADER_LEN + (BODY_LEN as usize)
51    }
52
53    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
54        let len = self.serialized_len();
55        if buf.len() < len {
56            return Err(Error::OutputBufferTooSmall {
57                need: len,
58                have: buf.len(),
59            });
60        }
61        buf[0] = TAG;
62        buf[1] = BODY_LEN;
63        buf[HEADER_LEN] = self.mpeg_4_audio_profile_and_level;
64        Ok(len)
65    }
66}
67
68impl<'a> crate::traits::DescriptorDef<'a> for Mpeg4AudioDescriptor {
69    const TAG: u8 = TAG;
70    const NAME: &'static str = "MPEG4_AUDIO";
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn round_trip() {
79        let orig = Mpeg4AudioDescriptor {
80            mpeg_4_audio_profile_and_level: 0xCD,
81        };
82        let mut buf = vec![0u8; orig.serialized_len()];
83        orig.serialize_into(&mut buf).unwrap();
84        let reparsed = Mpeg4AudioDescriptor::parse(&buf).unwrap();
85        assert_eq!(orig, reparsed);
86    }
87
88    #[test]
89    fn parse_rejects_wrong_tag() {
90        let err = Mpeg4AudioDescriptor::parse(&[0x02, 1, 0x00]).unwrap_err();
91        assert!(matches!(err, Error::InvalidDescriptor { tag: 0x02, .. }));
92    }
93
94    #[test]
95    fn parse_rejects_too_short() {
96        let err = Mpeg4AudioDescriptor::parse(&[TAG, 0]).unwrap_err();
97        assert!(matches!(err, Error::InvalidDescriptor { tag: TAG, .. }));
98    }
99}